深入理解bytedance/bhook项目:Native Hook技术手册

深入理解bytedance/bhook项目:Native Hook技术手册

【免费下载链接】bhook :fire: ByteHook is an Android PLT hook library which supports armeabi-v7a, arm64-v8a, x86 and x86_64. 【免费下载链接】bhook 项目地址: https://gitcode.com/gh_mirrors/bh/bhook

项目概述

bytedance/bhook是一个强大的Android Native Hook框架,它提供了灵活可靠的函数拦截能力,可以帮助开发者监控和修改Native层函数调用行为。本文将全面解析该项目的Native API使用方法和核心概念。

核心功能与初始化

初始化配置

bytedance/bhook支持两种初始化模式:

#define BYTEHOOK_MODE_AUTOMATIC 0  // 自动模式
#define BYTEHOOK_MODE_MANUAL    1  // 手动模式

int bytehook_init(int mode, bool debug);

使用建议

  • 大多数情况下无需手动调用bytehook_init(),推荐通过Java层初始化
  • 纯Native进程场景才需要显式调用此函数

调试与日志控制

框架提供了灵活的调试控制接口:

bool bytehook_get_debug(void);
void bytehook_set_debug(bool debug);

这些接口与Java层的getDebug()setDebug()功能一致,便于开发者根据需要开启或关闭调试日志。

Hook核心机制

Hook存根与回调

Hook操作返回的存根(stub)定义如下:

typedef void* bytehook_stub_t;

Hook完成后的回调函数原型:

typedef void (*bytehook_hooked_t)(
    bytehook_stub_t task_stub,     // 唯一存根,用于unhook
    int status_code,               // 执行状态码
    const char *caller_path_name,  // 调用者路径或名称
    const char *sym_name,          // 函数符号名
    void *new_func,                // 新函数地址
    void *prev_func,               // 原函数地址
    void *arg);                    // 自定义参数

Hook操作类型

bytedance/bhook提供了三种粒度的Hook方式:

  1. 单调用者Hook - 精确控制特定调用者
bytehook_stub_t bytehook_hook_single(
    const char *caller_path_name,
    const char *callee_path_name,
    const char *sym_name,
    void *new_func,
    bytehook_hooked_t hooked,
    void *hooked_arg);
  1. 部分调用者Hook - 通过过滤器选择调用者
bytehook_stub_t bytehook_hook_partial(
    bytehook_caller_allow_filter_t caller_allow_filter,
    void *caller_allow_filter_arg,
    const char *callee_path_name,
    const char *sym_name,
    void *new_func,
    bytehook_hooked_t hooked,
    void *hooked_arg);
  1. 全调用者Hook - 拦截所有调用者
bytehook_stub_t bytehook_hook_all(
    const char *callee_path_name,
    const char *sym_name,
    void *new_func,
    bytehook_hooked_t hooked,
    void *hooked_arg);

Hook任务管理

bytedance/bhook以task为单位管理Hook操作:

  • 每个task对应一个目标函数符号
  • 支持添加回调通知Hook执行结果
  • 三种调用者维度控制粒度
  • 同步执行,不创建额外线程

自动完成机制

  • 对于单调用者Hook:立即查找并执行,未找到则等待后续加载
  • 对于部分/全调用者Hook:持续监控新加载的ELF并执行Hook

路径名称处理

bytedance/bhook支持两种名称格式:

  • pathname:完整路径(如/system/lib/libc.so)
  • basename:文件名(如libc.so)

兼容性注意

  • Android 5.x/6.x设备可能只返回basename
  • 在过滤器和回调中需要自行处理兼容性
  • 建议唯一性库使用basename,可能冲突的使用pathname

处理Linker Namespace

Android 8.0+引入了linker namespace机制,导致同basename的多个库被加载。bytedance/bhook通过callee_path_name参数精确指定目标库:

// 只Hook特定路径的库函数
bytehook_hook_all(
    "/system/lib64/libcutils.so",  // 精确指定被调用者
    "atrace_begin_body",
    my_new_func,
    my_hooked_callback,
    my_hooked_callback_arg);

Unhook操作

保存Hook返回的存根,用于后续解除Hook:

int bytehook_unhook(bytehook_stub_t stub);

使用规范

  • 同步执行,返回0表示成功
  • 操作后应将stub置为NULL避免误用

Proxy函数编写指南

调用原函数

使用BYTEHOOK_CALL_PREV宏安全调用原函数:

C++示例

size_t my_strlen(const char* const str) {
    BYTEHOOK_STACK_SCOPE();
    return BYTEHOOK_CALL_PREV(my_strlen, str);
}

C示例

typedef size_t (*strlen_t)(const char* const);

size_t my_strlen(const char* const str) {
    size_t result = BYTEHOOK_CALL_PREV(my_strlen, strlen_t, str);
    BYTEHOOK_POP_STACK();
    return result;
}

栈清理

必须确保执行栈清理:

  • C++:使用BYTEHOOK_STACK_SCOPE(推荐RAII方式)
  • C:在每个返回点调用BYTEHOOK_POP_STACK

获取返回地址

使用专用宏获取真实返回地址:

void* lr = BYTEHOOK_RETURN_ADDRESS();

特殊场景:Hook dlopen系列函数

bytedance/bhook提供了专用API监控so加载:

void bytehook_add_dlopen_callback(
    bytehook_pre_dlopen_t pre,
    bytehook_post_dlopen_t post,
    void *data);

特性

  • 不区分Android版本和具体函数(dlopen/android_dlopen_ext)
  • 提供加载前后回调点
  • 自动处理兼容性问题

最佳实践建议

  1. 路径处理

    • 唯一性库使用basename
    • 可能冲突的使用完整pathname
    • 自行处理Android 5.x/6.x兼容性
  2. Proxy函数

    • 必须进行栈清理
    • 使用专用宏调用原函数
    • 多SDK场景协商hook顺序
  3. 性能考虑

    • 合理使用callee_path_name加速符号查找
    • 避免不必要的全量Hook
  4. 错误处理

    • 检查Hook/Unhook返回值
    • 正确处理回调中的状态码

bytedance/bhook框架通过精细的设计,在Android各版本上提供了稳定可靠的Native Hook能力。理解其核心机制和最佳实践,可以帮助开发者构建更强大的Native层监控和修改功能。

【免费下载链接】bhook :fire: ByteHook is an Android PLT hook library which supports armeabi-v7a, arm64-v8a, x86 and x86_64. 【免费下载链接】bhook 项目地址: https://gitcode.com/gh_mirrors/bh/bhook

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值