Files
knowledge-kit/Chapter1 - iOS/1.88.md
杭城小刘 e89fe0ca1c docs: 内容
2020-11-08 15:51:47 +08:00

3.3 KiB
Raw Blame History

fishhook 原理

  1. image: 代码编译后的可执行文件,被加载到内存中,就叫做镜像文件。

  2. MachO 可执行文件被 dyld 加载到内存中,加载时并不是所有的符号都可以确定地址,有些是通过 lazy bind 在真正调用的时候绑定的。

  3. iOS 代码在编译时没有办法确定方法的实现地址。动态库共享缓存里面有动态库。NSLog 属于 Foundation 框架,每个手机内部中的地址不一定。

    image-20200810182447587

  4. DYLD 动态链接器负责将可执行文件加载到内存中。App 启动后DYLD 将 Foundation、UIKit 等加载进动态库共享缓存中,但是加载到的位置不确定。

  5. 可执行文件头有 Load Commands:加载命令。告诉 DYLD 依赖了什么。

  6. 从 NSLog 找到代码实现经历过2种方式。早期重定向。现在PIC 技术(位置代码独立)。

  7. 可执行文件:

    • 代码段:可读可执行
    • 数据段:可读可写
  8. 写的业务代码里面假如某一行调用了 NSLog,那么在编译阶段,使用 NSLog 只是 IDE 提供了功能,让你可以看到声明而已。编译后的可执行文件,还是不知道 NSLog 的具体函数地址,它指向了一个表(类似一个应用程序的外部函数名,函数真正实现地址),去这个表里面找地址,这个表叫做符号表

当 DYLD 加载当前可执行文件的时候,才将这个表每个编号对应的函数地址去填上去,这个动作叫做符号绑定

当真正去调用 NSLog 函数的时候才去这个符号表中去寻找函数地址,去调用实现。

编号(符号) 地址
NSLog 0xaabbcc
... ...

image-20200810201822593

  1. fishhook 做的事情就是将系统的符号表,将符号表中的特定符号对应的地址,修改为自定义的函数地址。起到了 hook 作用。也就是说外部的 c 函数,在 iOS 中的调用属于动态调用

    https://www.bilibili.com/video/BV1UZ4y1u7Ba?from=search&seid=14997461811427810898

fishhook去 hook c 函数的原理。

假如我们的代码中调用了 NSLog 函数,因为 NSLog 的实现是在 Foundation 库中,动态库在内存中的地址是不固定的, ASLR 机制下, 所以在编译阶段是没办法确定

fishHook 不能 hook 自定义函数

可执行文件、动态链接库,加载到内存中的时候,会存在多种文件格式,系统为了统一标准,让加载到内存中的文件必须是 Mach-O 文件格式。

Hopper Disassembler v4

  • Mach-O 的定义?结构组成

fishhook 可以 hook c 函数的原因?

  1. 函数符号 数据段 被修改

  2. 函数符号为何位于数据段?

  3. 动态库每次被加载到内存中,地址都是随机不确定的。所以需要符号地址的修正。符号重定位、重绑定

  4. Lazy Symbol Pointers 懒汉模式Non-Lazy Symbol Pointers 启动就去绑定

  5. 可以 hook c++吗?为什么

  6. linux 平台下能否 hook c/c++