HOOK原理
1、MachO是被誰加載的?
DYLD動態加載
2、ASLR技術(地址空間布局隨機化):MachO文件加載的時候是隨機地址
3、PIC(位置代碼獨立)
- 如果MachO內部需要調用 系統的庫函數時
- 先在_DATA段中建立一個指針,指向外部函數
- DYLD會動態的進行綁定,將MachO中的DATA段中的指針,指向外部函數(DYLD會告訴MachO要依賴的外部庫的位置)
- _DATA段中建立的指針就是符號(symbols),它是幫你指向內部的函數調用,指向外部的函數地址
所以,fishhook的rebind_symbols(重新綁定符號)函數,它就是將你指向系統的NSLog的符號,給重新進行綁定,變為指向你內部的函數,這樣子就達到修改的目的了;這也是fishhook的底層原理。這也就是為什么使用fishhook時我們內部的函數修改不了,自定義的函數修改不了的原因,只能修改MachO外部的函數。
1、在rebind_symbols處打上斷點,提前加上一行代碼
NSLog(@"123");

運行后,如果在rebind_symbols斷點沒有顯示匯編代碼,可以通過Debug->Debug Workflow->Always Show Disassembly設置


2、在rebind_symbol函數執行之前,NSLog的懶加載符號表的地址是多少
找到可執行文件

用MachOView打開

- Non-Lazy Symbol pointers:MachO只要被加載進來就被綁定了
- Lazy Symbol pointers:第一次調用的時候才會去綁定
前面為什么加上NSLog(@"123");,是為了調用一次NSLog,這樣才能在懶加載表中看到NSLog。

3、怎么查看符號表
Offset偏移量 00003018(在MachO中偏移了3018)
表的位置=MachO相對於內存的偏移地址+表相對於MachO的偏移地址Offset(3018)
MachO相對於內存的偏移地址,通過 image list查看

0x0000000108339000 就是MachO在內存中的真實地址
表的位置=MachO相對於內存的偏移地址(0x0000000108339000)+表相對於MachO的偏移地址Offset(0x3018)
查看內存所指向的地址
x 0x0000000108339000+0x3018
(x 相當於memory read)

反匯編:
dis -s 0x0108690a52

這就通過符號表找到了方法
2、過掉rebind_symbol后,會改變0x0000000108339000+0x3018地址的值,查看地址

查看內存所指向的地址
x 0x0000000108339000+0x3018

反匯編:
dis -s 0x0108339e00

可以看到rebind_symbol后,對應的地址的方法已經發生了改變
那么,在上一篇iOS逆向之fishhookDemo的Demo2中,因為符號表里根本沒有func方法,所以Hook不成功。
