文章目录
- 一、对 libc.so#execve 函数进行内联 HOOK 操作
在
- 【Android 逆向】ART 函数抽取加壳 ① ( ART 下的函数抽取恢复时机 | 禁用 dex2oat 机制源码分析 )
- 【Android 逆向】ART 函数抽取加壳 ② ( 禁用 dex2oat 简介 | TurboDex 中禁用 dex2oat 参考示例 )
两篇博客中 , 简单介绍了 禁用 dex2oat 机制 的原理 , 下面开始 实现 dex2oat 禁用功能 ;
在 【Android 逆向】ART 函数抽取加壳 ③ ( 禁用 dex2oat 操作 HOOK 点介绍 | 集成 InLineHook ) 博客中 , 介绍了 HOOK 点 , 以及 集成 HOOK C 代码的库 InLineHook ;
一、对 libc.so#execve 函数进行内联 HOOK 操作
要 HOOK libc 函数库 中的 exec_utils.cc#execve 函数 , 首先要查找到 libc 库的基地址 , 然后查找 exec_utils.cc#execve 函数的地址 ;
execve 函数 定义在 bionic/libc/include/unistd.h 中 , 在 exec_utils.cc 中进行调用 ;
使用 在 【Android 逆向】ART 函数抽取加壳 ③ ( 禁用 dex2oat 操作 HOOK 点介绍 | 集成 InLineHook ) 博客中继承的 InLineHook 函数库 实现上述 native 中的 HOOK 操作 ;
首先 , 调用 hookdlfcndlfcn_compat.h 中的 dlopen_compat 函数 , 传入 libc 库的文件名即 " libc.so " 作为第一个参数 , 传入 RTLD_NOW 作为第二个参数作为标志位 , 该函数的原型如下 :
代码语言:javascript复制void *dlopen_compat(const char *filename, int flags);
该操作也可以使用 dlopen 函数 , 这里对该函数进行封装 , 是因为在 Android 7.0 之后 , 这些函数都受 命名空间限制 , 对于某些函数库可能执行失败 ;
然后 , 调用 hookdlfcndlfcn_compat.h 中的 dlsym_compat 函数 查找 exec_utils.cc#execve 函数 在 " libc.so " 函数库 中的地址 , 第一个参数是 " libc.so " 函数库的基地址 , 第二个参数是函数名称即 " execve " , 该函数的原型如下 :
代码语言:javascript复制void *dlsym_compat(void *handle, const char *symbol);
该操作也可以使用 dlsym 函数 , 这里对该函数进行封装 , 是因为在 Android 7.0 之后 , 这些函数都受 命名空间 限制 , 对于某些函数库可能执行失败 ;
再后 , 注册内联 HOOK 操作 , 调用 " hookincludeinlineHook.h " 中定义的 " registerInlineHook " 函数 , 传入的参数含义如下 :
- uint32_t target_addr 参数 : execve 函数在 " libc.so " 函数库中的地址 ;
- uint32_t new_addr 参数 : HOOK 后要替换的函数地址 , 使用自定义的函数替代原函数执行 ;
- uint32_t **proto_addr 参数 : 保存原函数地址 , 用于在新函数中调用原函数 , 实现代理模式 ;
enum ele7en_status registerInlineHook(uint32_t target_addr, uint32_t new_addr, uint32_t **proto_addr);
最后 , 执行内联 HOOK 操作 , 注册完毕后 , 调用 " hookincludeinlineHook.h " 中定义的 " inlineUnHook " 函数 , 传入被 HOOK 的函数地址 , 也就是 exec_utils.cc#execve 函数在 " libc.so " 函数库中的地址 ;
代码语言:javascript复制enum ele7en_status inlineUnHook(uint32_t target_addr);
执行成功 , 该函数返回 0 , 失败返回其它值 ;
本部分代码示例如下 :
代码语言:javascript复制// 导入 inLineHook 头文件
extern "C" {
#include "hook/dlfcn/dlfcn_compat.h"
#include "hook/include/inlineHook.h"
}
// 注册执行 Hook 操作
void hookLibc() {
// 查找 libc.so 函数库的基地址
void *libc_addr = dlopen_compat("libc.so", RTLD_NOW);
// 查找 execve 在 libc.so 函数库的偏移地址
void *execve_addr = dlsym_compat(libc_addr, "execve");
// 地址不为空才能向后执行
if (execve_addr != NULL) {
// 注册内联 Hook 函数 , 传入参数
// ① execve 在 libc.so 函数库的偏移地址 ,
// ② 自己实现的 myexecve 函数
// ③ Android 自带的原始的 execve 函数地址
// 返回 0 即注册成功
if (ELE7EN_OK == registerInlineHook((uint32_t) execve_addr, (uint32_t) myexecve,
(uint32_t **) &android_execve)) {
// 正式执行 Hook 操作
if (ELE7EN_OK == inlineHook((uint32_t) execve_addr)) {
LOGD("Hook Success");
} else {
LOGD("Hook Fail");
}
}
}
}