iOS逆向-16:Fishhook原理

fishhook

fishhook是如何通過字符串找到符號表的呢?
先來看看如何通過符號找到字符串:


image.png

image.png

可以看到懶加載符號表的順序和間接符號表(undefine)的順序是一樣的,這個間接符號表和symbols是有關(guān)聯(lián)的,比如NSLog在間接符號表的data 為0x000000CC十進制為204,這個204就是符號表中的角標,如下圖:


image.png

在圖中可以看到,在字符表中的偏移量為0xCE,我們在看看String table中的偏移的0xce是什么(即0x11378+0xce=0x11446),如圖:
image.png

所以fishhook正好和這個過程是相反的。

去符號Strip

去掉符號的作用:安全,減小包體積,優(yōu)化
全局符號 、本地符號

  • app : 去掉所有的
  • 動態(tài)庫: 保留全局符號

symbols 最下面,本地的保存的imp, 間接符號找樁,所以為0


image.png

去符號 斷點短不住

Strip Style

  • 去全局符號
  • 去非全局符號
  • 去debug符號

Deployment Postprocessing

  • 改成YES編譯階段就會脫符號


    image.png

    編譯


    image.png

    這個是上線后bitcode恢復(fù)符號用的
    image.png

    image.png

    這里是imp,因為間接符號的調(diào)用是找樁去執(zhí)行的,所以為0,但是本地符號,和全局符號就是imp了

image.png

去掉符號時候都是unnamed_symbol,這里不好分析,所以可以通過restore-symbol重新恢復(fù)符號
./restore-symbol MachO -o NewMachO
image.png

image.png

可以看到符號恢復(fù)了,這里的恢復(fù)建立在runtime基礎(chǔ)上,動態(tài)派發(fā)的必定保留了類名,方法名以及imp之間的關(guān)系,本質(zhì)通過MachO下圖這兩個段重新創(chuàng)建了符號表,但是這個工具c函數(shù)以及swift靜態(tài)調(diào)用的是無法恢復(fù)的
image.png

fishhook防護

這里是一種簡單的防護,也有辦法破解、
首先OC MethodSwizzle 使用系統(tǒng)函數(shù),那么APP利用fishhook hook系統(tǒng)的MethodSwizzle,可以讓他人hook不了
防hook代碼最好在framework中寫,framework中的load比主工程的load先加載,同時也在別人注入的framework之前
弊端:靠運行時,我只要比你早,找到fishhook ,對內(nèi)部的fishhook進行hook,hook +load 然后不執(zhí)行,也可以通過字符串就能定位修改字符串常量,導(dǎo)致防護失效
實例:

+(void)load
{
    //exchange
    struct rebinding exchange;
    exchange.name = "method_exchangeImplementations";
    exchange.replacement = my_exchange;
    exchange.replaced = (void *)&exchangeP;
    
    //setIMP
    struct rebinding setIMP;
    setIMP.name = "method_setImplementation";
    setIMP.replacement = my_exchange;
    setIMP.replaced = (void *)&setIMP_p;
    
    //getIMP
    struct rebinding getIMP;
    getIMP.name = "method_getImplementation";
    getIMP.replacement = my_exchange;
    getIMP.replaced = (void *)&getIMP_p;

    
    
    struct rebinding bds[] = {exchange,setIMP,getIMP};
    rebind_symbols(bds, 3);
    
}

//指針!這個可以暴露給外接!我自己的工程使用!!
void (*exchangeP)(Method _Nonnull m1, Method _Nonnull m2);

IMP _Nonnull (*setIMP_p)(Method _Nonnull m, IMP _Nonnull imp);
IMP _Nonnull (*getIMP_p)(Method _Nonnull m);


void my_exchange(Method _Nonnull m1, Method _Nonnull m2){
    NSLog(@"檢測到了HOOK!");
}

給自己工程用,在.h中導(dǎo)出,同時將.h拖入public中,給外部用

CF_EXPORT void (*exchangeP)(Method _Nonnull m1, Method _Nonnull m2);

本地使用:

#import <HookFramework/HookFramework.h>
exchangeP(class_getInstanceMethod(self.class, @selector(btnClick2:)),
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容