返回

使用 MachOView 探秘 fishhook 的运作原理

IOS

fishhook X MachOView:源码阅读

简介

鱼钩(fishhook)是一个著名的开源库,它为iOS平台提供了强大的内存重映射功能,可以动态地改变二进制文件中的函数地址,从而实现函数hook。通过fishhook,我们可以轻松地对目标应用程序进行修改,以实现特定的需求。

MachOView 是一个功能强大的二进制文件解析工具,可以帮助我们深入了解Mach-O文件的结构和内容。借助 MachOView,我们可以方便地查看Mach-O文件中的节段、符号、重定位表等信息。

fishhook 的基本原理

fishhook 的基本原理是通过更新Mach-O二进制文件中特定__DATA段的指针来绑定惰性和非惰性符号。当目标应用程序加载时,dyld 会将__DATA段映射到内存中。fishhook通过传递给rebind_symbols的符号名来确定需要更新的位置,然后用相应的替换项重新绑定这些符号。

使用 MachOView 分析 fishhook

我们可以使用 MachOView 来分析 fishhook 的运作原理。首先,我们需要找到 fishhook 的二进制文件。通常情况下,fishhook会被安装到/usr/lib/fishhook.dylib。

使用 MachOView 打开 fishhook.dylib 文件后,我们可以看到它的结构如下:

__TEXT
__DATA
__LINKEDIT
__la_symbol_ptr

其中,__DATA段是鱼钩中最重要的部分,它包含了fishhook用于更新符号地址的代码和数据。

动态改变符号地址

fishhook 的 rebind_symbols 函数可以动态地改变符号地址。该函数的原型如下:

int rebind_symbols(const char **name, void *replacement, void ** old_ptr)
  • name :需要修改的符号名
  • replacement :新的符号地址
  • old_ptr :旧的符号地址

当我们调用 rebind_symbols 函数时,fishhook 会首先在__DATA段中找到需要修改的符号,然后将符号的地址更新为新的地址。

利用 fishhook 实现函数hook

我们可以利用 fishhook 来实现函数hook。首先,我们需要创建一个新的函数,作为原函数的替换函数。然后,使用 rebind_symbols 函数将原函数的地址更新为替换函数的地址。

#include <stdio.h>
#include <fishhook.h>

// 替换函数
void new_function() {
  printf("Hello, world!\n");
}

int main() {
  // 获取原函数的地址
  void *original_function = dlsym(RTLD_MAIN, "function");

  // 将原函数的地址更新为替换函数的地址
  rebind_symbols((const char **)&original_function, new_function, NULL);

  // 调用原函数
  function();

  return 0;
}

在上述代码中,我们首先定义了一个新的函数 new_function,然后使用 rebind_symbols 函数将函数 function 的地址更新为 new_function 的地址。最后,我们调用函数 function,此时实际调用的是 new_function。

结语

鱼钩是一个非常强大的库,它可以帮助我们轻松地对目标应用程序进行修改,以实现特定的需求。通过结合 MachOView,我们可以深入了解 fishhook 的运作原理,并利用它来实现函数hook。