iOS逆向之旅(進階篇) — HOOK(FishHook)

洪呵呵發表於2018-10-26

官方簡介

fishhook is a very simple library that enables dynamically rebinding symbols in Mach-O binaries running on iOS in the simulator and on device. This provides functionality that is similar to using DYLD_INTERPOSE on OS X. At Facebook, we've found it useful as a way to hook calls in libSystem for debugging/tracing purposes (for example, auditing for double-close issues with file descriptors).
【簡而言之就是一個很輕量級的庫(就兩個檔案),可以動態的去修改macho可執行檔案的屬性】 專案地址:FishHook 。

案例一【HOOK 系統函式】

  • 直接把FishHook的兩個檔案直接拖進專案,並引入標頭檔案

image.png

  • 申明一個函式指標用於儲存原NSLog的真實函式地址 static void(*origNSLog)(NSString *format, ...);
  • 自定義一個新的函式用於取代NSLog
void newNSLog(NSString *format, ...){
    //再呼叫系統的nslog
    origNSLog(@"就不列印");
}
複製程式碼
  • 呼叫fishhook的rebind_symbols實現hook
struct rebinding bind;
bind.name = "NSLog";//要HOOK系統函式的函式名稱
bind.replacement = newNSLog;//新的函式去替換系統的NSLog
bind.replaced = (void *)&origNSLog;//把真正的NSLog地址儲存到origNSLog
struct rebinding rebs[] = {bind};
rebind_symbols(rebs, 1);
複製程式碼

上面這種事傳統的寫法,我們也可以簡寫成
rebind_symbols((struct rebinding [1]){{"NSLog",newNSLog,(void*)&origNSLog}}, 1);

  • 這樣就hook成功了,直接看效果

image.png
HOOK成功~~~~~~~~~

案例二【HOOK 自定義函式】

  • 在案例一的基礎上繼續加,首先宣告一個自定義函式func
void func(){
    NSLog(@"123");
}
複製程式碼
  • 申明一個函式指標用於儲存原func的真實函式地址 static void(*origFunc)();
  • 自定義一個新的函式用於取代func
void newFunc(){
    NSLog(@"456");
}
複製程式碼
  • 呼叫fishhook的rebind_symbols實現hook rebind_symbols((struct rebinding [1]){{"func",newFunc,(void*)&origFunc}}, 1);
  • 檢視hook結果

image.png
不難看出hook失敗了,hook成功的話,應該列印456才對

FishHook的原理

通過以上兩個案例為何FishHook能hook系統函式,卻hook不了我們自己的函式,接下來我們對其原理進行分析

科普一下

ASLR技術:是一種針對緩衝區溢位的安全保護技術,通過對堆、棧、共享庫對映等線性區佈局的隨機化,通過增加攻擊者預測目的地址的難度。對於我們APP而言,它保證每次MachO檔案載入的時候是隨機地址【這個我們可以通過LLDB指令的image list去檢視】

image.png

根據蘋果pic技術【位置程式碼獨立】,當我們Macho需要呼叫系統庫函式的時候,會在_DATA段中建立一個指標。DYLD【動態庫載入】會進行動態的繫結,會將這個指標指向外部函式

回過頭我們在分析我們之前的兩個案例

根據PIC技術,我們在呼叫NSLog的時候,系統會現在_Data段建立一個指標,這個指標在DYLD動態載入Foundation框架時,把這個指標指向NSLog的的真實地址。
fishhook他實際就是在改這個指標,讓這個指標向我們本地函式的地址。
所以fishhook的函式名字就叫rebind_symbols(重新繫結這個符號【指標】),很貼切。而我們本身自己的函式,不存在這個DYLD動態載入的過程,自然無法HOOK的了。

相關文章