返回

打造钓鱼钩:深入浅出学习 Fishhook 源码

IOS

引言

时隔多日,终于再次提笔写文章,虽然之前文章的阅读量并不高,但写作本身对我来说就是一种享受。最近一段时间,我开始深入学习一些优秀的开源库,其中 Fishhook 就是我的首选。Fishhook 是 Facebook 开源的一款用于修改外部函数的 C 语言库,它通常在应用程序启动时使用 dyld 共享库注入技术实现。

Fishhook 简介

Fishhook 的工作原理是通过修改指向外部函数的指针,从而将外部函数的执行重定向到我们自定义的函数。这个过程涉及到内存操作、汇编和 ARM64 等底层技术。通过 Fishhook,我们可以实现各种功能,例如方法交换、函数劫持和内存修改,从而为 iOS 越狱和安全研究人员提供强大的工具。

源码分析

1. 架构概述

Fishhook 的架构非常简洁,主要包含以下几个部分:

  • fishhook.h: 包含 Fishhook 的公共 API。
  • fishhook.c: 实现 Fishhook 的核心功能,包括指针修改和汇编代码生成。
  • fishhook64.h: 针对 ARM64 架构的特定头文件。
  • fishhook64.c: 针对 ARM64 架构的特定实现。

2. 函数替换

Fishhook 的核心功能是替换函数。这一过程可以通过以下步骤实现:

  • 首先,Fishhook 使用 dlopen 加载目标动态库。
  • 然后,它通过 dlsym 查找要替换的函数。
  • 接下来,Fishhook 使用汇编代码生成一个跳转指令,该指令将指向要替换的函数的指针重定向到自定义函数。
  • 最后,Fishhook 使用 rebind_symbols 函数将跳转指令写入目标动态库。

3. 内存操作

Fishhook 涉及到大量的内存操作,包括指针修改、内存分配和内存释放。这些操作都是通过汇编指令和底层 C 语言函数实现的。

4. 汇编代码

Fishhook 中大量使用了汇编代码,主要是为了生成跳转指令和修改内存。汇编代码可以提供比 C 语言更高的控制权,并允许我们直接操作底层硬件。

实例

为了更好地理解 Fishhook 的用法,我们来看一个简单的示例。假设我们要替换 printf 函数。我们可以使用以下代码:

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

void my_printf(const char *format, ...) {
  // 自定义函数的实现
}

__attribute__((constructor))
static void initialize() {
  rebind_symbols((struct rebinding[1]) {
    "printf", my_printf,
  }, 1);
}

这段代码使用 Fishhook 将 printf 函数替换为 my_printf 函数。需要注意的是,我们使用 __attribute__((constructor)) 声明了 initialize 函数,这确保了它会在应用程序启动时自动执行。

总结

Fishhook 是一个强大的工具,它可以帮助我们深入了解 iOS 越狱、内存操作、汇编、ARM64 和代码注入等技术。通过学习 Fishhook 源码,我们可以掌握这些技术的实际应用,并开发出自己的定制化解决方案。希望这篇博文能帮助大家对 Fishhook 有更深入的理解,并激发你们进一步探索 iOS 安全和逆向工程的领域。