iOS安全防護(hù)系列之ptrace反調(diào)試與匯編調(diào)用系統(tǒng)方法詳解
關(guān)于系統(tǒng)調(diào)用
ptrace是一個(gè)系統(tǒng)調(diào)用。那系統(tǒng)調(diào)用是什么東東呢?它是一個(gè)系統(tǒng)提供的很強(qiáng)大的底層服務(wù)。用戶層的框架是構(gòu)建在system call之上的。
macOS Sierra大約提供了500個(gè)系統(tǒng)調(diào)用。通過以下命令來了解你系統(tǒng)上的系統(tǒng)調(diào)用的個(gè)數(shù):
➜ ~ sudo dtrace -ln 'syscall:::entry' | wc -l
這個(gè)命令使用了另外一個(gè)更強(qiáng)大的工具叫DTrace,暫不詳談它。
一 lldb調(diào)試原理:debugserver
1、xcode的lldb之所以能調(diào)試app,是因?yàn)槭謾C(jī)運(yùn)行app,lldb會(huì)把調(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)試某個(gè)app
3、debugserver如何調(diào)試app?
debugserver通過ptrace函數(shù)調(diào)試app
ptrace是系統(tǒng)函數(shù),此函數(shù)提供一個(gè)進(jìn)程去監(jiān)聽和控制另一個(gè)進(jìn)程,并且可以檢測(cè)被控制進(jìn)程的內(nèi)存和寄存器里面的數(shù)據(jù)。ptrace可以用來實(shí)現(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#>)
有四個(gè)參數(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ù)
- 注入動(dòng)態(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ù)組的長(zhǎng)度 */ rebind_symbols(rebs, 1); }
四 針對(duì)三,要想別人hook自己的app的ptrace失效
思路:別人hook ptrace的時(shí)候,自己的ptrace已經(jīng)調(diào)用
想要自己函數(shù)調(diào)用在最之前:自己寫一個(gè)framework庫
在庫中寫入ptrace(PT_DENY_ATTACH, 0, 0, 0);
庫加載順序:
自己寫的庫>別人注入的庫
自己的庫加載順序:按照 Link Binary Libraries的順序加載
五 針對(duì)四 進(jìn)行反反調(diào)試
就算他的ptrace自己fishhook不到,可以通過修改macho的二進(jìn)制讓他的ptrace失效,然后進(jìn)行調(diào)試.
1、用MonkeyDev打開,下符號(hào)斷點(diǎn)trace,然后lldb調(diào)試bt,找到ptrace的庫antiDebug以及其地址0x0000000102165d98,再image list找到antiDebug的地址0x0000000102160000,那么真實(shí)地址為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)行就可以了
六 針對(duì)五 我不想暴露自己的ptrace等系統(tǒng)方法,不想被符號(hào)斷點(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多個(gè)系統(tǒng)函數(shù),都有其編號(hào)
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
iOS自定義UITableView實(shí)現(xiàn)不同系統(tǒng)下的左滑刪除功能詳解
關(guān)于左滑刪除這塊,相信不少朋友都遇到過。下面這篇文章主要給大家介紹了關(guān)于iOS如何自定義UITableView實(shí)現(xiàn)不同系統(tǒng)下的左滑刪除功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-09-09iOS實(shí)現(xiàn)秒殺活動(dòng)倒計(jì)時(shí)
這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)秒殺活動(dòng)倒計(jì)時(shí),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12iOS16使用SwiftUI Charts創(chuàng)建折線圖實(shí)現(xiàn)實(shí)例
這篇文章主要為大家介紹了iOS16使用SwiftUI Charts創(chuàng)建折線圖實(shí)現(xiàn)實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11iOS 用Swipe手勢(shì)和動(dòng)畫實(shí)現(xiàn)循環(huán)播放圖片示例
本篇文章主要介紹了iOS 用Swipe手勢(shì)和動(dòng)畫實(shí)現(xiàn)循環(huán)播放圖片示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2017-03-03