iOS安全防護(hù)系列之ptrace反調(diào)試與匯編調(diào)用系統(tǒng)方法詳解
關(guān)于系統(tǒng)調(diào)用
ptrace是一個系統(tǒng)調(diào)用。那系統(tǒng)調(diào)用是什么東東呢?它是一個系統(tǒng)提供的很強(qiáng)大的底層服務(wù)。用戶層的框架是構(gòu)建在system call之上的。
macOS Sierra大約提供了500個系統(tǒng)調(diào)用。通過以下命令來了解你系統(tǒng)上的系統(tǒng)調(diào)用的個數(shù):
➜ ~ sudo dtrace -ln 'syscall:::entry' | wc -l
這個命令使用了另外一個更強(qiáng)大的工具叫DTrace,暫不詳談它。
一 lldb調(diào)試原理:debugserver
1、xcode的lldb之所以能調(diào)試app,是因為手機(jī)運(yùn)行app,lldb會把調(diào)試指令發(fā)給手機(jī)的debugServer; debugServer是由Xcode第一次運(yùn)行程序給安裝到手機(jī)上。
Xcode上查看debugserver:
按住command鍵點(diǎn)擊Xcode,找到xcode.app顯示包內(nèi)
容/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/11.3 找到DeveloperDiskImage.dmg 里的usr -> bin -> debugserver
機(jī)的根目錄下的 Developer -> usr -> bin 里能找到debugserver,越獄手機(jī)可以查看
2、越獄環(huán)境下,lldb連接手機(jī)的debugserver,然后就可以通過debugserver調(diào)試某個app
3、debugserver如何調(diào)試app?
debugserver通過ptrace函數(shù)調(diào)試app
ptrace是系統(tǒng)函數(shù),此函數(shù)提供一個進(jìn)程去監(jiān)聽和控制另一個進(jìn)程,并且可以檢測被控制進(jìn)程的內(nèi)存和寄存器里面的數(shù)據(jù)。ptrace可以用來實現(xiàn)斷點(diǎn)調(diào)試和系統(tǒng)調(diào)用跟蹤。
推薦書單:《程序員的自我修養(yǎng)》
二 利用ptrace防護(hù)debugserver
把ptrace.h導(dǎo)入工程
ptrace頭文件不能直接導(dǎo)入app工程,可以新建命令行工程,然后#import <sys/ptrace.h>進(jìn)入到ptrace.h,把內(nèi)容全部復(fù)制到自己工程中新建的header文件MyPtrace.h中,那么自己的工程想調(diào)用ptrace就可以導(dǎo)入MyPtrace.h直接進(jìn)行調(diào)用
ptrace防護(hù)
ptrace(<#int _request#>, <#pid_t _pid#>, <#caddr_t _addr#>, <#int _data#>)有四個參數(shù)
參數(shù)1:要做的事情
參數(shù)2:要控制的進(jìn)程ID
參數(shù)3:地址
參數(shù)4:數(shù)據(jù)
參數(shù)3和參數(shù)4都由 參數(shù)1決定 參數(shù)1要傳遞的地址和數(shù)據(jù)
參數(shù)1的列表:
#define PT_TRACE_ME 0 /* child declares it's being traced */
#define PT_READ_I 1 /* read word in child's I space */
#define PT_READ_D 2 /* read word in child's D space */
#define PT_READ_U 3 /* read word in child's user structure */
#define PT_WRITE_I 4 /* write word in child's I space */
#define PT_WRITE_D 5 /* write word in child's D space */
#define PT_WRITE_U 6 /* write word in child's user structure */
#define PT_CONTINUE 7 /* continue the child */
#define PT_KILL 8 /* kill the child process */
#define PT_STEP 9 /* single step the child */
#define PT_ATTACH ePtAttachDeprecated /* trace some running process */
#define PT_DETACH 11 /* stop tracing a process */
#define PT_SIGEXC 12 /* signals as exceptions for current_proc */
#define PT_THUPDATE 13 /* signal for thread# */
#define PT_ATTACHEXC 14 /* attach to running process with signal exception */#define PT_FORCEQUOTA 30 /* Enforce quota for root */
#define PT_DENY_ATTACH 31#define PT_FIRSTMACH 32 /* for machine-specific requests */
要做到反調(diào)試,只需參數(shù)1為PT_DENY_ATTACH, 參數(shù)2為自己
#import "MyPtrace.h" //app反調(diào)試防護(hù) ptrace(PT_DENY_ATTACH, 0, 0, 0);
這樣你的app就不可以用Xcode調(diào)試了
三 反ptrace ,讓別人的ptrace失效
就是如果別人的的app進(jìn)行了ptrace防護(hù),那么你怎么讓他的ptrace不起作用,進(jìn)行調(diào)試他的app呢?
由于ptrace是系統(tǒng)函數(shù),那么我們可以用fishhook來hook住ptrace函數(shù),然后讓他的app調(diào)用我們自己的ptrace函數(shù)
- 注入動態(tài)庫meryinDylib
- 在meryinDylib中hook住ptrace函數(shù)
#import "fishhook.h"
#import "MyPtrace.h"
@implementation meryinDylib
int (*ptrace_p)(int _request, pid_t _pid, caddr_t _addr, int _data);
int myPtrace(int _request, pid_t _pid, caddr_t _addr, int _data){
if (_request != PT_DENY_ATTACH) {
return ptrace_p(_request,_pid,_addr,_data);
}
return 0;
}
+ (void)load
{
struct rebinding ptraceBind;
//函數(shù)的名稱
ptraceBind.name = "ptrace";
//新的函數(shù)地址
ptraceBind.replacement = myPtrace;
//保存原始函數(shù)地址的變量的指針
ptraceBind.replaced = (void *)&ptrace_p;
//定義數(shù)組
struct rebinding rebs[] = {ptraceBind};
/*
arg1 : 存放rebinding結(jié)構(gòu)體的數(shù)組
arg2 : 數(shù)組的長度
*/
rebind_symbols(rebs, 1);
}
四 針對三,要想別人hook自己的app的ptrace失效
思路:別人hook ptrace的時候,自己的ptrace已經(jīng)調(diào)用
想要自己函數(shù)調(diào)用在最之前:自己寫一個framework庫
在庫中寫入ptrace(PT_DENY_ATTACH, 0, 0, 0);
庫加載順序:
自己寫的庫>別人注入的庫
自己的庫加載順序:按照 Link Binary Libraries的順序加載
五 針對四 進(jìn)行反反調(diào)試
就算他的ptrace自己fishhook不到,可以通過修改macho的二進(jìn)制讓他的ptrace失效,然后進(jìn)行調(diào)試.
1、用MonkeyDev打開,下符號斷點(diǎn)trace,然后lldb調(diào)試bt,找到ptrace的庫antiDebug以及其地址0x0000000102165d98,再image list找到antiDebug的地址0x0000000102160000,那么真實地址為0x5d98;
2、然后顯示包內(nèi)容,在Frameworks中,找到antiDebug庫的macho,用hopper打開,找到0x5d98
3、更改二進(jìn)制
可以直接在bl __NSlog之后直接函數(shù)結(jié)束,去除bl __ptrace,不調(diào)用ptrace函數(shù)
復(fù)制ptrace下一條指令0000000000005d94 bl imp___stubs__ptrace,點(diǎn)擊bl __NSlog的下一行然后Alt+a,寫入代碼bl 0x 0000000000005d94

4、導(dǎo)出新的macho
File --> Produce New Executable
然后再運(yùn)行就可以了
六 針對五 我不想暴露自己的ptrace等系統(tǒng)方法,不想被符號斷點(diǎn)斷住,可以采用匯編進(jìn)行調(diào)用ptrace
//安全防護(hù)-反調(diào)試 asm( "mov x0,#31\n" "mov x1,#0\n" "mov x2,#0\n" "mov x3,#0\n" "mov w16,#26\n" //26是ptrace "svc #0x80" //0x80觸發(fā)中斷去找w16執(zhí)行 );
去哪里找26就是ptrace?
在#import <sys/syscall.h>中有500多個系統(tǒng)函數(shù),都有其編號
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
iOS11上Xcode9 AppIcon 圖標(biāo)不顯示
升級到iOS11系統(tǒng)下自己的項目桌面app圖標(biāo)不見了,是什么原因呢,經(jīng)過一番查找,終于發(fā)現(xiàn)問題所在,現(xiàn)在分享給大家2017-11-11
Objective-C基礎(chǔ) 自定義對象歸檔詳解及簡單實例
這篇文章主要介紹了Objective-C基礎(chǔ) 自定義對象歸檔詳解及簡單實例的相關(guān)資料,需要的朋友可以參考下2017-04-04

