fishhook 实现的大致思路是,通过重新绑定符号,可以实现对 c 方法的 hook。dyld 是通过更新 Mach-O 二进制的 __DATA segment 特定的部分中的指针来绑定 lazy 和 non-lazy 符号,通过确认传递给 rebind_symbol 里每个符号名称更新的位置,就可以找出对应替换来重新绑定这些符号。下面,我针对 fishhook 里的关键代码,和你具体说下 fishhook 的实现原理。首先,遍历 dyld 里的所有 image,取出 image header 和 slide。代码如下:
接下来,找到符号表相关的 command,包括 linkedit segment command、symtab command 和 dysymtab command。代码如下:
然后,获得 base 和 indirect 符号表。实现代码如下:
最后,有了符号表和传入的方法替换数组,就可以进行符号表访问指针地址的替换了,具体实现如下:
以上,就是 fishhook 的实现原理了。fishhook 是对底层的操作,其中查找符号表的过程和堆栈符号化实现原理基本类似,了解了其中原理对于理解可执行文件 Mach-O 内部结构会有很大的帮助。
参考:https://time.geekbang.org/column/article/85331