iOS安全防禦之ptrace反調試和彙編調用系統方法

一 lldb調試原理:debugserver

  1. xcode的lldb之因此能調試app,是由於手機運行app,lldb會把調試指令發給手機的debugServer; debugServer是由Xcode第一次運行程序給安裝到手機上。
    Xcode上查看debugserver:
    按住command鍵點擊Xcode,找到xcode.app顯示包內容/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/11.3 找到DeveloperDiskImage.dmg 裏的usr -> bin -> debugserver
    手機的根目錄下的 Developer -> usr -> bin 裏能找到debugserver,越獄手機能夠查看
  2. 越獄環境下,lldb鏈接手機的debugserver,而後就能夠經過debugserver調試某個app
  3. debugserver如何調試app?
    debugserver經過ptrace函數調試app
    ptrace是系統函數,此函數提供一個進程去監聽和控制另外一個進程,而且能夠檢測被控制進程的內存和寄存器裏面的數據。ptrace能夠用來實現斷點調試和系統調用跟蹤。

推薦書單:《程序員的自我修養》程序員

二 利用ptrace防禦debugserver

  1. 把ptrace.h導入工程
    ptrace頭文件不能直接導入app工程,能夠新建命令行工程,而後#import <sys/ptrace.h>進入到ptrace.h,把內容所有複製到本身工程中新建的header文件MyPtrace.h中,那麼本身的工程想調用ptrace就能夠導入MyPtrace.h直接進行調用數組

  2. ptrace防禦
    ptrace(<#int _request#>, <#pid_t _pid#>, <#caddr_t _addr#>, <#int _data#>)有四個參數
    參數1:要作的事情
    參數2:要控制的進程ID
    參數3:地址
    參數4:數據
    參數3和參數4都由 參數1決定 參數1要傳遞的地址和數據
    參數1的列表:xcode

    #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 31markdown

    #define PT_FIRSTMACH 32 /* for machine-specific requests */app

要作到反調試,只需參數1爲PT_DENY_ATTACH, 參數2爲本身函數

#import "MyPtrace.h"
 //app反調試防禦
   ptrace(PT_DENY_ATTACH, 0, 0, 0);
複製代碼

這樣你的app就不能夠用Xcode調試了oop

三 反ptrace ,讓別人的ptrace失效

就是若是別人的的app進行了ptrace防禦,那麼你怎麼讓他的ptrace不起做用,進行調試他的app呢?
因爲ptrace是系統函數,那麼咱們能夠用fishhook來hook住ptrace函數,而後讓他的app調用咱們本身的ptrace函數spa

  1. 注入動態庫meryinDylib命令行

  2. 在meryinDylib中hook住ptrace函數

    #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; //函數的名稱 ptraceBind.name = "ptrace"; //新的函數地址 ptraceBind.replacement = myPtrace; //保存原始函數地址的變量的指針 ptraceBind.replaced = (void )&ptrace_p; //定義數組 struct rebinding rebs[] = {ptraceBind}; / arg1 : 存放rebinding結構體的數組 arg2 : 數組的長度 */ rebind_symbols(rebs, 1); }

四 針對三,要想別人hook本身的app的ptrace失效

思路:別人hook ptrace的時候,本身的ptrace已經調用
想要本身函數調用在最以前:本身寫一個framework庫
在庫中寫入ptrace(PT_DENY_ATTACH, 0, 0, 0);

  • 庫加載順序:
    本身寫的庫>別人注入的庫
    本身的庫加載順序:按照 Link Binary Libraries的順序加載

五 針對四 進行反反調試

就算他的ptrace本身fishhook不到,能夠經過修改macho的二進制讓他的ptrace失效,而後進行調試.

  1. 用MonkeyDev打開,下符號斷點trace,而後lldb調試bt,找到ptrace的庫antiDebug以及其地址0x0000000102165d98,再image list找到antiDebug的地址0x0000000102160000,那麼真實地址爲0x5d98;

  2. 而後顯示包內容,在Frameworks中,找到antiDebug庫的macho,用hopper打開,找到0x5d98

  3. 更改二進制
    能夠直接在bl __NSlog以後直接函數結束,去除bl __ptrace,不調用ptrace函數
    複製ptrace下一條指令0000000000005d94 bl imp___stubs__ptrace,點擊bl __NSlog的下一行而後Alt+a,寫入代碼bl 0x 0000000000005d94

  4. 導出新的macho
    File --> Produce New Executable
    而後再運行就能夠了

六 針對五 我不想暴露本身的ptrace等系統方法,不想被符號斷點斷住,能夠採用彙編進行調用ptrace

//安全防禦-反調試
    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觸發中斷去找w16執行
    );
複製代碼
  • 去哪裏找26就是ptrace?
    #import <sys/syscall.h>中有500多個系統函數,都有其編號

查看原文

推薦

iOS逆向視頻詳解

相關文章
相關標籤/搜索