LSPosed_mod Native层Hook实现:基于Dobby的Inline Hook技术应用

LSPosed_mod Native层Hook实现:基于Dobby的Inline Hook技术应用

【免费下载链接】LSPosed_mod My changes to LSPosed 【免费下载链接】LSPosed_mod 项目地址: https://gitcode.com/GitHub_Trending/ls/LSPosed_mod

技术架构概述

LSPosed_mod作为Android平台上的模块化Hook框架,其Native层实现基于Dobby内联钩子库构建核心拦截能力。框架通过拦截动态链接器do_dlopen函数实现对目标进程的精确控制,在core/src/main/jni/src/native_api.cpp中定义了完整的钩子注册与回调分发机制。

核心技术组件

Inline Hook实现原理

钩子注册流程

框架在初始化阶段通过InstallNativeAPI函数完成关键系统函数的Hook安装:

bool InstallNativeAPI(const lsplant::HookHandler & handler) {
    auto *do_dlopen_sym = SandHook::ElfImg("/linker").getSymbAddress(
        "__dl__Z9do_dlopenPKciPK17android_dlextinfoPKv");
    LOGD("InstallNativeAPI: {}", do_dlopen_sym);
    if (do_dlopen_sym) [[likely]] {
        HookSymNoHandle(handler, do_dlopen_sym, do_dlopen);
        return true;
    }
    return false;
}

这段代码实现了三个关键步骤:

  1. 解析链接器(/linker)的ELF符号表定位do_dlopen函数
  2. 使用Dobby引擎创建内联钩子
  3. 将目标函数重定向至自定义实现do_dlopen(core/src/main/jni/src/native_api.cpp#L135-L144)

内存保护设计

为确保API入口表安全,框架采用内存页保护机制:

std::unique_ptr<void, std::function<void(void *)>> protected_page(
    mmap(nullptr, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0),
    [](void *ptr) { munmap(ptr, 4096); });

const auto[entries] = []() {
    auto *entries = new(protected_page.get()) NativeAPIEntries{
        .version = 2,
        .hookFunc = &HookFunction,
        .unhookFunc = &UnhookFunction,
    };

    mprotect(protected_page.get(), 4096, PROT_READ);
    return std::make_tuple(entries);
}();

通过mmap创建可读写内存页存储API结构体,初始化完成后立即通过mprotect设置为只读模式,防止恶意篡改(core/src/main/jni/src/native_api.cpp#L56-L69)。

模块化Hook机制

模块加载回调系统

框架实现了基于白名单的模块加载监控机制,在do_dlopen钩子中:

for (std::string_view module_lib: moduleNativeLibs) {
    if (hasEnding(ns, module_lib)) [[unlikely]] {
        LOGD("Loading module native library {}", module_lib);
        void *native_init_sym = dlsym(handle, "native_init");
        if (native_init_sym == nullptr) [[unlikely]] {
            LOGD("Failed to get symbol \"native_init\" from library {}", module_lib);
            break;
        }
        auto native_init = reinterpret_cast<NativeInit>(native_init_sym);
        auto *callback = native_init(entries);
        if (callback) {
            moduleLoadedCallbacks.push_back(callback);
            return handle;
        }
    }
}

当系统加载目标模块时,会自动调用模块导出的native_init函数,并注册模块回调函数(core/src/main/jni/src/native_api.cpp#L108-L125)。

多回调管理

框架支持同时注册多个模块回调,通过链表结构维护:

std::list<NativeOnModuleLoaded> moduleLoadedCallbacks;
// ...
for (auto &callback: moduleLoadedCallbacks) {
    callback(name, handle);
}

每个新加载的共享库都会触发所有已注册回调,实现模块化的钩子逻辑扩展(core/src/main/jni/src/native_api.cpp#L129-L131)。

关键实现文件

功能模块实现文件
钩子API定义core/src/main/jni/include/native_api.h
钩子实现核心core/src/main/jni/src/native_api.cpp
ELF符号解析core/src/main/jni/include/elf_util.h
日志系统core/src/main/jni/include/logging.h
内存工具core/src/main/jni/include/utils.h

技术优势分析

  1. 兼容性设计:通过动态符号解析适配不同Android版本链接器实现
  2. 安全性保障:内存页保护与权限控制防止恶意篡改
  3. 模块化架构:支持多模块并行Hook,独立回调互不干扰
  4. 性能优化:使用Dobby内联钩子技术,相比传统PLT Hook减少性能开销

使用指南

开发环境配置

  1. 克隆项目仓库:
git clone https://gitcode.com/GitHub_Trending/ls/LSPosed_mod
  1. 配置NDK开发环境,确保支持C++17标准

模块开发示例

#include "native_api.h"

void native_init(void *api) {
    auto *entries = static_cast<NativeAPIEntries *>(api);
    // 注册自定义Hook回调
    entries->registerModuleLoadedCallback([](const char *name, void *handle) {
        LOGD("Module loaded: %s", name);
        // 实现自定义Hook逻辑
    });
}

在模块的Android.mk中声明导出符号:

LOCAL_LDFLAGS += -Wl,--version-script=$(LOCAL_PATH)/exports.lds

总结与展望

LSPosed_mod的Native层Hook架构通过Dobby内联钩子技术构建了高效、安全的二进制拦截系统。其核心优势在于模块化设计与跨版本兼容性,使得开发者能够专注于业务逻辑实现而非底层Hook细节。

未来版本将重点优化:

  • 钩子冲突检测机制
  • 多架构支持完善
  • 内存占用优化

完整实现细节可参考项目源码,特别是core/src/main/jni目录下的相关文件。

【免费下载链接】LSPosed_mod My changes to LSPosed 【免费下载链接】LSPosed_mod 项目地址: https://gitcode.com/GitHub_Trending/ls/LSPosed_mod

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

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

抵扣说明:

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

余额充值