關(guān)于系統(tǒng)調(diào)用
ptrace是一個系統(tǒng)調(diào)用。那系統(tǒng)調(diào)用是什么東東呢?它是一個系統(tǒ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
這個命令使用了另外一個更強大的工具叫DTrace,暫不詳談它。
一 lldb調(diào)試原理:debugserver
1、xcode的lldb之所以能調(diào)試app,是因為手機運行app,lldb會把調(diào)試指令發(fā)給手機的debugServer; debugServer是由Xcode第一次運行程序給安裝到手機上。
Xcode上查看debugserver:
按住command鍵點擊Xcode,找到xcode.app顯示包內(nèi)
容/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/11.3 找到DeveloperDiskImage.dmg 里的usr -> bin -> debugserver
機的根目錄下的 Developer -> usr -> bin 里能找到debugserver,越獄手機可以查看
2、越獄環(huán)境下,lldb連接手機的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à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ù)
#import "fishhook.h"#import "MyPtrace.h"@implementation meryinDylibint (*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打開,下符號斷點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,點擊bl __NSlog的下一行然后Alt+a,寫入代碼bl 0x 0000000000005d94
4、導(dǎo)出新的macho
File --> Produce New Executable
然后再運行就可以了
六 針對五 我不想暴露自己的ptrace等系統(tǒng)方法,不想被符號斷點斷住,可以采用匯編進(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í)價值,如果有疑問大家可以留言交流,謝謝大家對武林網(wǎng)的支持。
新聞熱點
疑難解答