FridaHook_initarray 介绍

  1. System.loadLibrary 源码分析
    在 Android 或 Linux 系统中,System.loadLibrary 用于加载 共享库(SO 文件),其底层实现涉及多个关键机制:

III array、IIIT array 和 GNload
这些是 SO 加载过程中涉及的关键结构:

III array(.init_array 段): 存储 初始化函数的数组,系统在 SO 加载完成后逐个执行这些函数。
IIIT array(.init 段): 早期的初始化机制,主要用于单个初始化函数,现在多使用 init_array 代替。
GNload: GNU loader 机制的一部分,负责加载 符号表 并解析依赖项。
GNload 调用时机

打开 SO 文件
解析动态符号表(DOSYM)
调用 GNonload 进行动态加载
IIIT array 和 III array 的调用时机

这些调用发生在 系统内部,并影响库的初始化方式。
init_array 主要用于 用户态的库初始化,而 IIIT 机制更偏向 系统级别的核心构造。
2. SO 加载流程
SO 文件加载的完整流程如下:

查找 SO 文件

find_library 负责定位目标 SO 文件,并将其映射到内存中,返回 SO input 结构体。
解析 ELF 头

解析 ELF(Executable and Linkable Format) 文件的头部信息,确定 .init_array、.text、.data 段的位置。
解析动态符号

解析 SO 内部的 符号表,链接其他库(如 libc.so、libm.so)。
调用构造函数

通过 SI.callConstruct 依次执行构造函数,通常包括:
DT_INIT(.init 段)
DT_INIT_ARRAY(.init_array 段)
DT_INIT 和 DT_INIT_ARRAY

DT_INIT:存储在 .init 段,表示 单个初始化函数。
DT_INIT_ARRAY:存储在 .init_array 段,表示 初始化函数数组,执行时按照数组顺序调用多个构造函数。
3. 选择 Hook 时机
为了确保 Hook 能够在目标函数执行前生效,需要选择合适的时机:

在 callConstruct 之前 Hook

callConstruct 负责执行 DT_INIT 和 DT_INIT_ARRAY 中的函数,因此在其调用前 Hook,才能拦截所有初始化逻辑。
INT 和 INT array 只执行一次

init_array 只在 SO 加载时执行一次,所以 Hook 必须在 SO 被加载时 完成。
最佳 Hook 时机

SO 加载时
在 find_library 执行后、构造函数调用前 Hook。
callConstruct 执行前
通过 Frida Hook callConstruct,修改执行逻辑。
4. 编写 Hook 代码
编写 Hook 代码时,需要注意以下几点:

设置 MDate 和 MayDate

这些数据用于追踪 SO 加载状态,并作为 Hook 的切入点。
Hook dlopen(或 DllOpen)

通过 符号表解析,在 dlopen 执行之前找到目标函数的地址。
使用 link64 工具

解析 ELF 符号表,获取 callConstruct 具体地址,以便 Hook。
5. 替换函数实现
在 Frida 中,可以使用 intercept.replace 来替换目标函数:

拦截 DT_INIT 和 DT_INIT_ARRAY

通过 Frida 替换初始化函数,打印 “Hook 成功” 的日志。
替换函数参数

需要确保 Hook 目标是 int 类型的数组,否则可能导致错误。
示例代码

var libname = "libtarget.so";

Interceptor.attach(Module.findExportByName(null, "dlopen"), {
    onEnter: function (args) {
        var name = Memory.readUtf8String(args[0]);
        if (name.indexOf(libname) !== -1) {
            console.log("[+] Hooking " + libname);
        }
    },
    onLeave: function (retval) {
        console.log("[+] SO Loaded: " + retval.toInt32());
    }
});

Interceptor.replace(Module.findExportByName(libname, "target_function"), new NativeCallback(function (arg1, arg2) {
    console.log("[+] Hooked target_function: " + arg1.toInt32());
    return 0;
}, 'int', ['int', 'int']));

代码解析:

Interceptor.attach 用于拦截 dlopen,检测 SO 何时被加载。
Interceptor.replace 替换 target_function,拦截其执行逻辑并打印日志。
总结
本次学习 Frida Hook init_array 的关键点:
✅ SO 加载流程分析(ELF 解析、符号链接、构造函数调用)
✅ 关键 Hook 时机选择(callConstruct 之前)
✅ Frida Hook 代码编写(dlopen Hook、函数替换)
✅ 目标函数拦截与参数修改(DT_INIT 和 DT_INIT_ARRAY)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值