fishhook理解

779 阅读2分钟

fishhook 一、概述 HOOK:钩子、挂钩。让别人的程序执行自己的代码。

1、iOS中HOOK方式 Method Swizzle,利用Runtime,动态改变SEL和IMP的关系,主要用在OC方法中

2、fishhook fackbook提供的一个动态修改链接mach-o文件的工具,利用mach-o文件加载原理,通过修改懒加载和非懒加载表的指针来实现C函数HOOK的功能。

二、原理

1、C语言是静态函数,编译的时候已经确定了函数地址,怎么能HOOK呢?

C语言是静态函数,但是系统的C函数的调用是动态的

系统函数如NSLog,在编译的时候是无法确定地址,因为没有载入到内存,这里涉及到共享动态库的原理,(NSLog在Fundaction库里。动态库的共享缓存,在不同的系统,不同的手机,地址都是不一样的)。

如何调用系统库的呢? 苹果的共享缓存库不会被编译进我们的 MachO 文件,而是在动态链接时才去重新绑定。 苹果采用了PIC(Position-independent code)技术成功让 C 的底层也能有动态的表现

  • 编译时,在mach-o文件_DATA段的符号表中为每一个被引用的系统C函数建立一个指针(8字节)。这个指针的作用是用于动态绑定时,绑定共享库中函数的实现。
  • 运行时,当系统的C函数第一次调用时会进行符号绑定,然后将mach-o文件_DATA段的符号表对应的指针,指向外部函数(共享库中实际的内存地址)

1、在编译的时候,当调用NSLog的时,mach-o(本地)文件会生成一个NSLog符号指针,调用代码会指向这个指针。

2、在运行的时候,dyld链接器加载mach-o文件,载入到内存,载入到内存的时候会询问哪些符号需要绑定,把系统库的地址和函数的真实地址和符号绑定。

3、运行时,首次(懒加载表)NSLog函数的调用,会去找符号,一开始符号是没值的,符号绑定后才会有值。

符号:符号就是函数名称,以函数名称命名的指针

系统的C函数的调用是动态的,通过符号找到真实的地址,fishhook就是利用这个原理,对符号重新绑定,把符号指向的系统函数的真实地址改了,改成了自己定义的函数的地址。

自定义的C函数是无法通过fishhook工具HOOK的(可以通过innerHook内连HOOK,但是要考虑到堆栈平衡,要改动汇编代码),只能HOOK外部函数。