fishhook查找过程
fishhook实现原理
背景
C语言是门静态语言,在编译期就确定了函数地址,而系统的函数由于存放在了共享缓存库中,必须在dyld
加载的时候(运行时)才能确定。
为了解决这个问题,苹果针对 Mach-O
文件提供了一种PIC(Position Independent Code 地址无关代码)技术,即在 Mach-O
的__Data
段中添加懒加载表(Lazy Symbol Pointers)
和非懒加载表 (Non-Lazy Symbol Pointers)
,让系统的函数在编译时先指向懒加载表(Lazy Symbol Pointers)
或非懒加载表(Non-Lazy Symbol Pointers)
中的符号地址;这2个符号表的地址指向0
( 在编译的时候并没有指向任何地方),app启动时被dyld
加载到内存,然后在这个时候进行链接,给这2个表赋值动态缓存库的地址,进行符号绑定。
整个过程
详细查找过程
Lazy Symbol Pointer Table --> Indirect Symbol Table --> Symbol Table --> String Table
如果字符串表中的value与传进来的相同,说明是我们要替换的函数,那么我们就把__DATA
段中的函数地址替换成我们自己的函数地址。
外部的函数存在于共享库中,不是在编译期就固定的,而是在首次调用时,比如 NSLog
函数。这里我们就拿它举例(它存在于懒加载符号表中)。
1、首先从懒加载符号表中找到它,记录它的index
(在这个表中第几个位置,类似数组的下标,后面会用到)
2、然后去动态符号表
中的间接符号表
中根据先前的index
去查找,懒加载符号表
和间接符号表
的顺序是一一对应的;把间接符号表
中找到的那一块数据中的data (0x00007749)
换算成十进制,即30537
,根据这个十进制数到符号表
中去查找;
3、符号表中的位置
4、最后字符串表中查找,这里需要用字符串表的首地址(0x00245528)+ 符号表中的地址(0x0000C02E)
作为NSLog
在字符串表
中位置