iOS逆向之反HOOK的基本防護


如果在我們的項目中hook了Method Swizzle,那么別人還能hook我們的項目嗎??

一、寫上基本的防護,內部使用hook,外部沒有hook

1、新建工程:基本防護,寫個簡單的頁面

image.png

代碼如下:
image.png

2、需求:在外部hook btnClick2,在內部hook btnClick1,需要保證的是在外部hook btnClick2無效,在內部hook btnClick1生效。

3、拖入fishhook代碼,新建hookMgr類

//專門HOOK
+(void)load{
    //內部用到的交換代碼
    Method old = class_getInstanceMethod(objc_getClass("ViewController"), @selector(btnClick1:));
    Method new = class_getInstanceMethod(self, @selector(click1Hook:));
    method_exchangeImplementations(old, new);
    
    //在交換代碼之前,把所有的runtime代碼寫完 
    
    //基本防護
    struct rebinding bd;
    bd.name = "method_exchangeImplementations";
    bd.replacement=myExchang;
    bd.replaced=(void *)&exchangeP;
    
    struct rebinding rebindings[]={bd};
    rebind_symbols(rebindings, 1);
}

//保留原來的交換函數
void (* exchangeP)(Method _Nonnull m1, Method _Nonnull m2);

//新的函數
void myExchang(Method _Nonnull m1, Method _Nonnull m2){
    NSLog(@"檢測到了hook");
}
-(void)click1Hook:(id)sender{
    NSLog(@"原來APP的hook保留");
}

說明:

  • 在做防護之前,先把自己內部需要runtime交換的代碼寫完,比如開放btnClick1給自己內部去hook,其他的hook則禁止
  • 使用fishhook hook method_exchangeImplementations方法,這樣當外部使用method_exchangeImplementations方法時,讓它失效

4、運行,分別點擊按鈕1和按鈕2,此時內部hook了btnClick1方法,外部暫時沒有hook任何方法

image.png

二、准備ipa

1. 打包ipa

  • 將基本防護.app拷貝出來
    image.png
  • 新建文件夾Payload,將基本防護.app拷貝到Payload文件夾中
  • cd到Payload的上級目錄,使用命令壓縮,生成ipa
    zip -ry Hook.ipa Payload

三、外部hook,注入代碼

1.新建工程:Hook基本防護

代碼注入參考:iOS逆向之代碼注入(framework)

前面在hookMgr中已經做了防護,不能交換btnClick2方法,那么我們寫下hook btnClick2的代碼來測試一下:

+(void)load
{
    Method old = class_getInstanceMethod(objc_getClass("ViewController"), @selector(btnClick2:));
    Method new = class_getInstanceMethod(self, @selector(click2Hook:));
    method_exchangeImplementations(old, new);
}
    
-(void)click2Hook:(id)sender{
    NSLog(@"btnClick2交換成功");
}

運行,分別點擊按鈕1,按鈕2,發現btnClick2交換成功,防護失敗了
image.png

2.思考防護失敗的原因

  • 1.在基本防護工程里,hookMgr的load方法里加上NSLog(@"hookMgr--Load");
  • 2.在ViewController的load方法里加上NSLog(@"ViewController--Load");
  • 3.在AppDelegate的load方法里加上
+(void)load{
    NSLog(@"AppDelegate--Load");
}
  • 4.編譯基本防護工程重新運行,生成基本防護.app,重新打包
    zip -ry Hook.ipa Payload
  • 5.將Hook.ipa拷貝到Hook基本防護工程的APP文件夾里,打開Hook基本防護工程,在WJHook的load方法里加上,NSLog(@"WJHook---load"); 然后運行
    image.png
    發現WJHook(攻擊方)是最早調用的,hookMgr(防護方)是最晚調用的,那么攻擊方方法都交換成功了,你防護方才來防護,明顯是沒用。因此,上面的btnClick2方法仍然被外部交換了,hookMgr沒起到防護的作用。

3.解決辦法

1.修改Complie Sources的順序

  • 修改前
    image.png
    image.png

  • 修改后
    image.png
    image.png

2.既然外部的動態庫最先加載,那么防護方自己建立一個動態庫

  • 在基本防護工程里新建動態庫antiHook
    image.png
  • 編譯運行
    image.png
  • 生成基本防護.app,重新打包zip -ry Hook.ipa Payload
  • 將Hook.ipa拷貝到Hook基本防護工程的APP文件夾里

3.打開Hook基本防護工程,運行

image.png

  • 發現我們的防護hookMgr先執行,並且 檢測到了hook
  • 至此外部就不能通過hook “Method Swizzle”來交換btnClick2方法

4、弊端

  • 如果hookMgr內部要交換方法,需要提前在hookMgr的內部寫好交換代碼,然后再做防護。

  • 因為在內部是沒有辦法再進行hook了,所以有些三方庫如果用了Method Swizzle,那么你要做的修改就比較多,需要將工程里用到的全部method_exchangeImplementations換成exchangeP
    image.png

  • 如果用Cydia Substrate或者MonkeyDev來hook,依然能hook成功

5、下面用MonkeyDev來舉例:

1、新建MonkeyDev工程MonkeyDemo,此過程需要先安裝好MonkeyDev

image.png

2、將防護的Hook.ipa拷貝到MonkeyDemo->TargetApp文件夾下

image.png

  • %hook ViewController 表示hook ViewController這個類

  • -(void)btnClick2:(id) org 表示hook btnClick2這個方法
    image.png

  • hookMgr是最先加載的,但是MonkeyDev還是能hook成功
    image.png

6、為什么MonkeyDev和Cydia Substrate能hook成功?

1.首先了解Cydia Substrate的組成部分(MonkeyDev也是集成了Cydia Substrate):

Cydia Substrate主要由3部分組成:

  • 1.MobileHooker
       MobileHooker顧名思義用於HOOK。它定義一系列的宏和函數,底層調用objc的runtime和fishhook來替換系統或者目標應用的函數.
    其中有兩個函數:

    • MSHookMessageEx 主要作用於Objective-C方法
      void MSHookMessageEx(Class class, SEL selector, IMP replacement, IMP result)
    • MSHookFunction 主要作用於C和C++函數
      void MSHookFunction(voidfunction,void* replacement,void** p_original)
  • 2.MobileLoader
       MobileLoader用於加載第三方dylib在運行的應用程序中。啟動時MobileLoader會根據規則把指定目錄的第三方的動態庫加載進去,第三方的動態庫也就是我們寫的破解程序.

  • 3.safe mode
       因為APP程序質量參差不齊崩潰再所難免,破解程序本質是dylib,寄生在別人進程里。 系統進程一旦出錯,可能導致整個進程崩潰,崩潰后就會造成iOS癱瘓。所以CydiaSubstrate引入了安全模式,在安全模 式下所有基於CydiaSubstratede 的三方dylib都會被禁用,便於查錯與修復。

2. MSHookMessageEx底層調用objc的runtime和fishhook來替換系統或者目標應用的函數

在我們的防護代碼中,只防護了method_exchangeImplementations方法,然而method_setImplementation和method_getImplementation並沒有做防護,因此猜想Cydia Substrate就是通過這兩個方法來hook的。

3.實驗

  • 在基本防護2的工程中,增加對method_setImplementation和method_getImplementation的防護
    image.png

  • 編譯生成基本防護.app,再次打包成Hook.ipa

  • 將Hook.ipa拷貝到MonkeyDemo->TargetApp文件夾下

  • 運行MonkeyDemo工程

image.png
如圖,做到了防護MonkeyDev的hook,在檢測到hook,強制退出APP

  • 那么,上面的防護真的就無法破解了嗎?
    答案當然是否定的,提供一個思路:
    通過修改MachO文件,在防護動態庫之前調用hook的動態庫,就能實現hook,因為你是在我hook成功之后才做的防護。
  • 不過新手一般就破解不了上面的防護了。進攻和防護還需要不斷學習!
代碼已上傳:https://github.com/WinJayQ/HookDefend


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM