hook改變函數(shù)的執(zhí)行流程砂心。
1.重定向:ASLR(隨機(jī)值) + 偏移值 = 內(nèi)存值
0x5FCC + 0x0000000102edc000 = 0x102ee1fcc
內(nèi)存中的可執(zhí)行文件叫做鏡像
viewdidload
0x102ee1fcc
可執(zhí)行文件
0x0000000102edc000
0x5FCC
重定向:通過計(jì)算找到內(nèi)部函數(shù)地址.
匯編指令和二進(jìn)制是一一對應(yīng)關(guān)系,如1f 20 03 d5 代表 nop
指針在arm64架構(gòu)下占8個(gè)字節(jié)
2.什么是符號綁定能扒?
本質(zhì)是修改符號表块茁,符號綁定的是外部函數(shù)齿坷。
內(nèi)部函數(shù)是重定向確定調(diào)用地址的桂肌。
3.每次調(diào)用外部符號的過程?
Symbol Stubs -> Lazy Symbol Pointers -> Non-Lazy
Symbol Pointers
1.找樁(Symbol Stubs)永淌,就是根據(jù)懶加載符號表里面的值調(diào)用
2.Lazy Symbol Pointers符號表里面的值(默認(rèn)值是執(zhí)行dyld_stub_binder)
3.首次調(diào)用:dyld_stub_binder,改變符號表里面的值崎场,指向真實(shí)地址.
第二次再次調(diào)用的話就直接調(diào)用符號表里的值了就是NSLog的真實(shí)地址了
Symbol Stubs -> Lazy Symbol Pointers
口述沒用,匯編+lldb調(diào)試才是王道
symbols是個(gè)總表:
內(nèi)部符號遂蛀、
外部符號:懶加載符號Lazy Symbol Pointers(運(yùn)行時(shí)確定地址)谭跨,非懶加載符號Non-Lazy
Symbol Pointers(如dyld_stub_binder,編譯時(shí)就確定了地址)李滴。
每一個(gè)外部函數(shù)都對應(yīng)一個(gè)樁
4.Fishhook如何修改符號螃宙?原理?
Fishhook專門hook外部函數(shù)的
text 只讀的不能改的所坯,所以改的是Lazy Symbol Pointers
5.Fishhook 如何通過字符串找到符號?即Fishhook改符號原理
string Table Index -> symbols Index -> Indirect Symbols Index -> Lazy Symbol Pointers -> 修改Lazy Symbol Pointers值
1谆扎、去MachO 中尋找 string Table 完全可以用 . 來分割! 得到偏移值(string Table Index)
2芹助、通過string Table Index 去找Symbols(符號表)堂湖!得到符號表的偏移值(symbols Index)
3、通過 symbols Index 去找 Indirect Symbols周瞎! 得到符號的偏移值 ( Indirect Symbols Index)
4苗缩、由于Lazy Symbol Pointers 的 Index 和 Indirect Symbols Index 一一對應(yīng)饵蒂! 所以很容易就找到了對應(yīng)的符號I睢!
最后去修改Lazy Symbol 里面的值M硕ⅰ彼乌!
(因?yàn)橥獠糠柕恼{(diào)用,都是找樁渊迁!樁去尋找Lazy Symbol 里面的地址執(zhí)行N空铡)
6.如何去掉符號?
build setting strip style 默認(rèn)去掉符號表中的所有符號
strip style
APP的話選擇 All Symbols 去掉本地符號琉朽,只剩間接符號
動態(tài)庫的話選擇 Non-Global Symbols 去掉本地符號毒租,剩下全局符號、間接符號
Debugging Symbols 去掉調(diào)試符號 剩下本地箱叁、全局墅垮、間接符號
Deployment Postprocessing 設(shè)置 yes debug階段去除符號 no是在打包時(shí)去除符號即默認(rèn)值
本地符號,如果不使用耕漱,符號不會生成
7.如何恢復(fù)符號算色?
在終端執(zhí)行下面語句使用使用restore-symbol工具
./restore-symbol restore-symbol -o SymbolDemo1
- 如何通過函數(shù)調(diào)用棧算出函數(shù)名?
將函數(shù)調(diào)用棧地址-程序的鏡像地址 然后在hopper中搜索改地址
9.兩個(gè)動態(tài)庫中的同名類調(diào)用會沖突嗎螟够?
并不會灾梦,動態(tài)庫方法的調(diào)用峡钓,先找動態(tài)庫,再去里面找符號若河,所以動態(tài)庫不存在符號沖突能岩。
誰在上邊就先找到誰
靜態(tài)庫:
1.當(dāng)靜態(tài)庫沒有使用的符號(符號 的最小單位是類),那么靜態(tài)庫不會被鏈接牡肉。
2.當(dāng)鏈接器找到符號之后捧灰,就不會再鏈接相同的符號了
誰在上邊就先連接到誰
使用靜態(tài)庫中的分類方法會發(fā)生什么?會找不到方法统锤,因?yàn)榉诸悤r(shí)動態(tài)添加的毛俏,靜態(tài)庫中的分類方法默認(rèn)不會鏈接進(jìn)來。如何解決饲窿?在Other Link Flags 添加 -ObjC 就是把所有OC代碼都鏈接進(jìn)來
如何可以發(fā)生靜態(tài)庫沖突煌寇?一個(gè)靜態(tài)庫是-ObjC,另一個(gè)也有同名類方法逾雄,這時(shí)候編譯就會報(bào)錯(cuò)阀溶。
如何解決?在Other Link Flags中加2行鸦泳,-force_load ,絕對路徑(也可以使用環(huán)境變量)
設(shè)置主鏈接
如果用到了2個(gè)靜態(tài)庫银锻,各自又有相同名字的的類目方法,導(dǎo)致了符號沖突怎么解決做鹰?
這個(gè)時(shí)候就只能使用工具llvm-objcopy去添加前綴去修改符號了击纬。