Android 逆向ART 函数抽取加壳 ⑤ ( unistd.h#execve 函数分析 | 使用自定义的 myexecve 函数替换 libc.so#execve 函数 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 逆向ART 函数抽取加壳 ⑤ ( unistd.h#execve 函数分析 | 使用自定义的 myexecve 函数替换 libc.so#execve 函数 )相关的知识,希望对你有一定的参考价值。
文章目录
在
- 【Android 逆向】ART 函数抽取加壳 ① ( ART 下的函数抽取恢复时机 | 禁用 dex2oat 机制源码分析 )
- 【Android 逆向】ART 函数抽取加壳 ② ( 禁用 dex2oat 简介 | TurboDex 中禁用 dex2oat 参考示例 )
两篇博客中 , 简单介绍了 禁用 dex2oat 机制 的原理 , 下面开始 实现 dex2oat 禁用功能 ;
在 【Android 逆向】ART 函数抽取加壳 ③ ( 禁用 dex2oat 操作 HOOK 点介绍 | 集成 InLineHook ) 博客中 , 介绍了 HOOK 点 , 以及 集成 HOOK C 代码的库 InLineHook ;
在 【Android 逆向】ART 函数抽取加壳 ④ ( 对 libc.so#execve 函数进行内联 HOOK 操作 ) 博客中 , 对 libc.so#execve 函数 进行了 内联 HOOK 操作 , 可以对该函数进行拦截 ;
本篇博客实现 自定义的 myexecve 函数 替换 libc.so#execve 函数 ;
一、bionic/libc/include/unistd.h#execve 函数分析
libc.so#execve 函数 定义在 android 源码的 " bionic/libc/include/unistd.h " 头文件中 , 函数原型如下 :
int execv(const char* __path, char* const* __argv);
int execvp(const char* __file, char* const* __argv);
int execvpe(const char* __file, char* const* __argv, char* const* __envp) __INTRODUCED_IN(21);
// ★ 此处为 execve 函数原型
int execve(const char* __file, char* const* __argv, char* const* __envp);
源码地址 : http://androidxref.com/8.0.0_r4/xref/bionic/libc/include/unistd.h
" int execve(const char* __file, char* const* __argv, char* const* __envp); " 函数解析 :
- const char* __file 参数 : 表示要运行的 二进制程序文件路径 , 这里指的是 Dex 字节码文件路径 , 如果要拦截 指定路径中的字节码文件不进行 OAT 优化 , 可以再此处进行过滤 , 检测到某个文件路径 , 直接返回空不执行任何代码逻辑 ;
二、使用自定义的 myexecve 函数替换 libc.so#execve 函数
在 博客中 , 介绍了调用 " hook\\include\\inlineHook.h " 中定义的 " registerInlineHook " 函数注册被 Hook 的函数 , 其原型如下 :
enum ele7en_status registerInlineHook(uint32_t target_addr, uint32_t new_addr, uint32_t **proto_addr);
uint32_t target_addr
参数是 execve 函数在 libc.so 的地址 , uint32_t new_addr
参数是自定义替换 execve 函数执行的函数地址 , uint32_t **proto_addr
参数是 execve 原函数的地址 ;
首先 , 定义一个函数指针变量 , 接收
" int execve(const char* __file, char* const* __argv, char* const* __envp); " 函数
的地址 , 之后如果需要真实调用时需要用到 ;
int ( *android_execve )(const char* __file, char* const* __argv, char* const* __envp);
定义指针 , 指向一个函数 , 函数的参数是 const char* __file, char* const* __argv, char* const* __envp
, 返回值是 int
类型 ;
该函数指针在进行 " hook\\include\\inlineHook.h " 中定义的 " registerInlineHook " 函数时 被赋值 ;
复杂指针阅读技巧 ( 主要是 区分 函数指针 和 数组指针 ) 右左法则 :
-
1.最里层标示符 : 先找到最里层的圆括号中的标示符;
数组指针和函数指针的标示符 ( 指针变量名 ) 都在中间的圆括号中, 因此该步骤先找到指针变量名
-
2.右左看 : 先往右看, 再往左看 ;
-
3.确定类型 : 遇到 圆括号 “()” 或者 方括号 “[]” 确定部分类型, 调转方向 ; 遇到 * 说明是指针 , 每次确定完一个类型 , 将该类型提取出来 , 分析剩下的 ;
一种可能性 :
int (*) [5] , 遇到中括号说明是数组指针类型,
int(*)(int, int) , 遇到圆括号 说明是函数指针类型 ; -
4.重复 2 , 3 步骤 : 一直重复, 直到 指针 阅读结束 ;
然后 , 定义 自定义的 execve 函数 , 用于 替换 Android 自带的 execve 函数 , 主要用于拦截 dex2oat 字节码文件 ,
- 这里将需要拦截的字节码都放在 dex2oat 目录中 , 检测到 dex2oat 目录 , 就退出 ;
- 不需要拦截的 , 直接调用原函数执行 ;
源码示例 :
// 用于接收 Android 自带的 execve 函数
int (*android_execve)(const char *__file, char *const *__argv, char *const *__envp);
// 自定义的 execve 函数 , 用于替换 Android 自带的 execve 函数
// 主要用于拦截 dex2oat 字节码文件
int myexecve(const char *__file, char *const *__argv, char *const *__envp)
// 这里将需要拦截的字节码都放在 dex2oat 目录中
if (strstr(__file, "dex2oat"))
return 0;
else
// 不需要拦截的 , 直接调用原函数执行
return android_execve(__file, __argv, __envp);
以上是关于Android 逆向ART 函数抽取加壳 ⑤ ( unistd.h#execve 函数分析 | 使用自定义的 myexecve 函数替换 libc.so#execve 函数 )的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向ART 函数抽取加壳 ④ ( 对 libc.so#execve 函数进行内联 HOOK 操作 )
Android 逆向ART 函数抽取加壳 ③ ( 禁用 dex2oat 操作 HOOK 点介绍 | 集成 InLineHook )
Android 逆向ART 函数抽取加壳 ( ART 下的函数抽取恢复时机 | 禁用 dex2oat 机制源码分析 )
Android 逆向ART 函数抽取加壳 ② ( 禁用 dex2oat 简介 | TurboDex 中禁用 dex2oat 参考示例 )
Android 逆向加壳技术识别 ( 函数抽取 与 Native 化加壳的区分 | VMP 加壳与 Dex2C 加壳的区分 )
Android 逆向脱壳解决方案 ( DEX 整体加壳 | 函数抽取加壳 | VMP 加壳 | Dex2C 加壳 | Android 应用加固防护级别 )