我们在做测试的时候,通常需要对app里面的某些方法进行hook。今天介绍一下fishHook的原理,从而说明fishHook的使用场景和局限性。

fishhook中已经将原理介绍的很清楚,如下图所示:

ios hook使用 ios hook原理_fish


跟着箭头流程如下:

1、通过懒加载表Lazy Symbol Pointers找到动态表Dynamic Symbol Table

懒加载表Lazy Symbol Pointers与动态表Dynamic Symbol Table是一一对应的关系(Find entry with same index in indirect symbol table)。如下图所示:

ios hook使用 ios hook原理_懒加载_02


ios hook使用 ios hook原理_懒加载_03


可以发现懒加载表Lazy Symbol Pointers与动态表Dynamic Symbol Table是一一对应的关系

2、动态表的Data值找到Symbol Table->Symbols

在Indirect Symbols中找到Data值 0x81,换成10进制是129。Data值其实就是一个下标,是一个真正符号表的下标。(Treat value as index into symbol table array)

ios hook使用 ios hook原理_fish_04


在Symbols表中找到偏移量Offset为129的值_NSLog

ios hook使用 ios hook原理_动态库_05


这个下标是我一个一个数的,并没有像其他文章那样MachOView会直接在界面上显示。

3、根据Symbols的偏移值Data,在String Table找到字符串

Look up string table entry by adding offset from symbol table entry to string table baseSymbols的偏移为:0x9B

ios hook使用 ios hook原理_动态库_06


String Table的起始值是:0x4F6C

ios hook使用 ios hook原理_动态库_07


字符串的位置:0x4F6C+ 0x9B = 0x5007

根据0x5007可以找到:_NSLog.

ios hook使用 ios hook原理_动态库_08

通过以上fishhook原理介绍可以得出如下结论:
适用场景:

  • 可以hook通过懒加载表Lazy Symbol Pointers加载的符号,这些符号通常是系统库的C语言符号,只能hook 到可执行文件调用动态库或framework,无法hook到动态库和动态库之间的函数调用。所以想hook某些系统函数,可以在MachOview里面的懒加载表Lazy Symbol Pointers里面是否存在符号

局限性

  • 不可以hook自己编写的C函数,因为自己编写的C函数在编译时期已经确定了符号,不会通过懒加载。
  • 不可以hook 静态库里面的符号,因为静态库里面的符号也不是通过懒加载,在编译时期也已经确定了符号。
  • 不可以hook 动态库和动态库之间的函数调用,因为也是加载时就确定了所有符号的地址

参考文章:

1、https://www.jianshu.com/p/883297573063