在上一篇 fishHook原理----(1) 中,我们讲了fishHook的HOOK流程,当第一次调用NSLog的时候,首先会到找桩去执行一段代码,这段代码就是去找到懒加载里面的值去执行,然后它默认会b到另一段代码,就是去找non_Lazy Symbol去找dyld_stub_binder的真实函数的地址完成符号绑定,第一次绑定完成之后,完成了第一次调用;
3、当第二次调用NSLog的时候,还是会找到桩去执行一段代码,代码会跳到懒加载里面的Data的值去执行,但是这个时候,Data里面的值指向了NSLog的真实地址,不再是指向查找dyld_stub_binder的真实函数的地址完成符号绑定;
使用fishHook的核心代码就这几行,rebinding结构体有一个name成员变量,那它是如何通过name找到NSLog符号的呢?
struct rebinding psyLog;
psyLog.name = "NSLog";
psyLog.replacement = psy_Log;
// 原函数
psyLog.replaced = (void *)&sysLog;
struct rebinding psysh[] = {
psyLog
};
rebind_symbols(psysh, 1);
以下是官方给的在懒加载表或非懒加载表中查找给定name的过程:
查找过程
看着可能看不大懂,我们先撇开这个图,看一下MachO,从懒加载表开始,因为懒加载是外部函数,_NSLog的下表是第0位,对应的在间接符号表也是第0位。
懒加载表
间接符号表
找到间接符号表的对应index,得到Data段数据0xB2(对应的十进制是178),还有Description是Symbol符号表,意思就是在Symbol表的178标号位置
Symbol表
然后对应的找到
Symbol表的对应#178,得到Data段数据0xD7,还有Description是String Table Index字符串表,意思就是在String Table Index表的偏移0xD7位置。
String Table
来到String Table根据刚刚得到的偏移量0xD7,通过初始位置+偏移量定位到对应的位置,0xD3D0 + 0xD7 = 0xD4A7,终于查到我们需要的字符串ASCII码5F 4E 53 4C 6F 67 ,Value是_NSLog。 至此,再返回去看一下官方给的查找流程图,就很明了了。















网友评论