fishhook原理

fishhook

fishhook是Facebook提供的用于hook系統(tǒng)c函數(shù)的庫。它能動態(tài)重新綁定運行在iOS模擬器和真機設(shè)備上的MachO文件中的符號表中的符號。

hacker

準備知識

  • PIC(Position Independent Code)位置代碼獨立。
    為了使多個進程能夠共享內(nèi)存中的同一份代碼拷貝,已達到節(jié)約內(nèi)存資源的目的。
  • ASLR(Address Space Layout Randomization)地址空間布局隨機化技術(shù)。
    它將進程的某些內(nèi)存空間地址進行隨機化來增大入侵者預(yù)測目的地址的難度,從而降低進程被成功入侵的風險。因而每次啟動程序時,程序在內(nèi)存中的地址都不一樣。
  • DYLD(Dynamic Loader)動態(tài)加載器。在Darwin/OS X被叫做dyld,它用來加載所有的frameworks, dynamic libraries, and bundles (plug-ins)。

由于蘋果的動態(tài)庫遵循PIC,存在于共享緩存庫,同時采用了ASLR技術(shù)。每次重啟手機后,動態(tài)庫的地址都會隨機偏移,需要通過基地址加偏移地址來獲取代碼的真實地址。

MachO文件

MachO文件是蘋果系統(tǒng)的可執(zhí)行文件。通過DYLD動態(tài)加載。

我們的應(yīng)用程序為了能夠獲取動態(tài)庫的真實地址,由DYLD動態(tài)加載MachO中的符號表,將符號表中的指針指向動態(tài)庫地址。從而達到調(diào)用系統(tǒng)庫的目的。

而fishhook正是通過dyld來修改符號表中指向動態(tài)庫的指針來達到hook的目的。

MachO中,__DATA段中與動態(tài)符號綁定相關(guān)的有兩個section__nl_symbol_ptr__la_symbol_ptr。

  • __nl_symbol_ptr是一個非懶加載數(shù)據(jù)的指針數(shù)組。
  • __la_symbol_ptr在第一次調(diào)用前,dyld會去通過dyld_stub_binder填充指針數(shù)組。在第一次調(diào)用之后才會真正鏈接到動態(tài)庫的位置。
__la_symbol_ptr

為了在MachO中找到想要hook的函數(shù)的名字,需要在幾個間接的層間進行跳轉(zhuǎn)。在這兩個sectionsection header提供了一個offset用來指向?qū)?yīng)的section。

section_header

__la_symbol_ptr指針數(shù)組的下標和indirect_symbol_table中的下標是一一對應(yīng)的。

indirect_symbol_table

indirect_symbol_table中的每個元素的data中保存著一個十六進制的數(shù),這個數(shù)就是真正的符號表中的數(shù)組下標。比如NSStringFromClass這個函數(shù)的Data為0x54,對應(yīng)十進制84,在symbol_table中的第84位即可找到。

symbol_table

symbol_table對應(yīng)的元素中的data同樣保存著一個十六進制的數(shù),這個數(shù)是字符串表中的偏移地址。比如NSStringFromClassstring_table中的偏移為0x92,找到string_table的首地址,為0xCA18,則該函數(shù)的字符串常量位于 0xCA18 + 0x92 = 0xCAAA 的位置。

string_table

借用fishhook的圖


fishhook過程

用法

static void (*orig_NSLog)(NSString *format, ...);

void my_NSLog(NSString *format, ...)
{
    orig_NSLog(@"hook成功:%@",format);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    struct rebinding rebind;
    rebind.name = "NSLog";
    rebind.replacement = my_NSLog;
    rebind.replaced = (void *)&orig_NSLog;
    
    rebind_symbols((struct rebinding[1]){rebind}, 1);
    
    NSLog(@"test");
}

總結(jié)

fishhook正是通過查找到需要hook的函數(shù)指針,然后替換成自己寫的函數(shù)指針,從而實現(xiàn)hook系統(tǒng)函數(shù)的目的。

fishhook不能hook自定義的函數(shù),是因為自定義的函數(shù)不在__la_symbol_ptr中。

資料

最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

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