官方簡介
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).
【簡而言之就是一個很輕量級的庫(就兩個文件),可以動態(tài)的去修改macho可執(zhí)行文件的屬性】
項目地址:FishHook 。
案例一【HOOK 系統(tǒng)函數(shù)】
- 直接把FishHook的兩個文件直接拖進(jìn)項目症虑,并引入頭文件
- 申明一個函數(shù)指針用于保存原NSLog的真實(shí)函數(shù)地址
static void(*origNSLog)(NSString *format, ...);
- 自定義一個新的函數(shù)用于取代NSLog
void newNSLog(NSString *format, ...){
//再調(diào)用系統(tǒng)的nslog
origNSLog(@"就不打印");
}
- 調(diào)用fishhook的rebind_symbols實(shí)現(xiàn)hook
struct rebinding bind;
bind.name = "NSLog";//要HOOK系統(tǒng)函數(shù)的函數(shù)名稱
bind.replacement = newNSLog;//新的函數(shù)去替換系統(tǒng)的NSLog
bind.replaced = (void *)&origNSLog;//把真正的NSLog地址保存到origNSLog
struct rebinding rebs[] = {bind};
rebind_symbols(rebs, 1);
上面這種事傳統(tǒng)的寫法,我們也可以簡寫成
rebind_symbols((struct rebinding [1]){{"NSLog",newNSLog,(void*)&origNSLog}}, 1);
- 這樣就hook成功了归薛,直接看效果
HOOK成功~~~~~~~~~
案例二【HOOK 自定義函數(shù)】
- 在案例一的基礎(chǔ)上繼續(xù)加谍憔,首先聲明一個自定義函數(shù)func
void func(){
NSLog(@"123");
}
- 申明一個函數(shù)指針用于保存原func的真實(shí)函數(shù)地址
static void(*origFunc)();
- 自定義一個新的函數(shù)用于取代func
void newFunc(){
NSLog(@"456");
}
- 調(diào)用fishhook的rebind_symbols實(shí)現(xiàn)hook
rebind_symbols((struct rebinding [1]){{"func",newFunc,(void*)&origFunc}}, 1);
- 查看hook結(jié)果
不難看出hook失敗了匪蝙,hook成功的話,應(yīng)該打印456才對
FishHook的原理
通過以上兩個案例為何FishHook能hook系統(tǒng)函數(shù)习贫,卻hook不了我們自己的函數(shù)逛球,接下來我們對其原理進(jìn)行分析
科普一下
ASLR技術(shù):是一種針對緩沖區(qū)溢出的安全保護(hù)技術(shù),通過對堆苫昌、棧颤绕、共享庫映射等線性區(qū)布局的隨機(jī)化,通過增加攻擊者預(yù)測目的地址的難度祟身。對于我們APP而言奥务,它保證每次MachO文件加載的時候是隨機(jī)地址【這個我們可以通過LLDB指令的image list去查看】
根據(jù)蘋果pic技術(shù)【位置代碼獨(dú)立】,當(dāng)我們Macho需要調(diào)用系統(tǒng)庫函數(shù)的時候袜硫,會在_DATA段中建立一個指針氯葬。DYLD【動態(tài)庫加載】會進(jìn)行動態(tài)的綁定,會將這個指針指向外部函數(shù)
回過頭我們在分析我們之前的兩個案例
根據(jù)PIC技術(shù)婉陷,我們在調(diào)用NSLog的時候帚称,系統(tǒng)會現(xiàn)在_Data段建立一個指針,這個指針在DYLD動態(tài)加載Foundation框架時秽澳,把這個指針指向NSLog的的真實(shí)地址闯睹。
fishhook他實(shí)際就是在改這個指針,讓這個指針向我們本地函數(shù)的地址肝集。
所以fishhook的函數(shù)名字就叫rebind_symbols(重新綁定這個符號【指針】)瞻坝,很貼切蛛壳。而我們本身自己的函數(shù)杏瞻,不存在這個DYLD動態(tài)加載的過程,自然無法HOOK的了衙荐。