fishhook 實(shí)現(xiàn)的大致思路是,通過重新綁定符號,可以實(shí)現(xiàn)對 c 方法的 hook。dyld 是通過更新 Mach-O 二進(jìn)制的 __DATA segment 特定的部分中的指針來綁定 lazy 和 non-lazy 符號,通過確認(rèn)傳遞給 rebind_symbol 里每個(gè)符號名稱更新的位置,就可以找出對應(yīng)替換來重新綁定這些符號。下面,我針對 fishhook 里的關(guān)鍵代碼,和你具體說下 fishhook 的實(shí)現(xiàn)原理。首先,遍歷 dyld 里的所有 image,取出 image header 和 slide。代碼如下:

接下來,找到符號表相關(guān)的 command,包括 linkedit segment command、symtab command 和 dysymtab command。代碼如下:

然后,獲得 base 和 indirect 符號表。實(shí)現(xiàn)代碼如下:

最后,有了符號表和傳入的方法替換數(shù)組,就可以進(jìn)行符號表訪問指針地址的替換了,具體實(shí)現(xiàn)如下:

以上,就是 fishhook 的實(shí)現(xiàn)原理了。fishhook 是對底層的操作,其中查找符號表的過程和堆棧符號化實(shí)現(xiàn)原理基本類似,了解了其中原理對于理解可執(zhí)行文件 Mach-O 內(nèi)部結(jié)構(gòu)會(huì)有很大的幫助。
參考:https://time.geekbang.org/column/article/85331