使用 MachOView 探秘 fishhook 的运作原理
2023-11-25 22:42:58
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。