iOS RE 4 beginners 3 - fishhook
关于
Fishhook是Facebook提供的利用MachO文件惰性加载原理,通过修改懒加载和非懒加载两个表的指针达到C函数HOOK的目的一个轻量级的hook库。理解这个工具和熟悉流程也是可以帮助更好的理解MachO文件格式 :)
原理图如下:
源码阅读
核心其实就是rebind_symbols 这个接口,另一个 rebind_symbols_image
是指定macho中的symbol进行rebind,所以从 rebind_symbols
函数看起就行了。
1 | FISHHOOK_VISIBILITY |
简单看下关键的调用路径:
1 | rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); |
_rebindings_head
指向一个需要重绑定的符号的单项链表:
1 | struct rebinding { |
调试
直接拿官方的demo编译出来调试分析流程:
1 | ~/study/ios_re_link/fishhook cat main.c |
1 | * thread #1, queue = 'com.apple.main-thread', stop reason = step over |
然后找到 LC_SEGMENT_64_DATA
处理 S_LAZY_SYMBOL_POINTERS
和 S_NON_LAZY_SYMBOL_POINTERS
1 | (lldb) n |
这里为了调试,重点关注 S_LAZY_SYMBOL_POINTERS
的处理
首先在rebind之前查看open符号
1 | (lldb) image lookup -va 0x0000000100a3fee0 |
首先备份了原函数地址,确保hook后可以通过 orign_open
调用到原本的函数。
1 | (lldb) p i |
之后找到函数指针,完成替换
1 | Process 2046 stopped |
如果调用 原本的函数会走什么流程?
1 | 0x100a3f448 <+176>: bl 0x100a3fd9c ; symbol stub for: close |