前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Android 逆向】ART 函数抽取加壳 ⑤ ( unistd.h#execve 函数分析 | 使用自定义的 myexecve 函数替换 libc.so#execve 函数 )

【Android 逆向】ART 函数抽取加壳 ⑤ ( unistd.h#execve 函数分析 | 使用自定义的 myexecve 函数替换 libc.so#execve 函数 )

作者头像
韩曙亮
发布2023-03-30 17:22:37
3800
发布2023-03-30 17:22:37
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

两篇博客中 , 简单介绍了 禁用 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 " 头文件中 , 函数原型如下 :

代码语言:javascript
复制
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 的函数 , 其原型如下 :

代码语言:javascript
复制
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 " 函数时 被赋值 ;

复杂函数指针参考博客 【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读) 六. 函数指针 3. 解读 复杂的 指针声明 ( 难点 重点 | ①找出中心标识符 ②先右 后左 看 确定类型 提取 ③ 继续分析 左右看 … ) 进行分析 ;

复杂指针阅读技巧 ( 主要是 区分 函数指针 和 数组指针 ) 右左法则 :

  • 1.最里层标示符 : 先找到最里层的圆括号中的标示符; 数组指针和函数指针的标示符 ( 指针变量名 ) 都在中间的圆括号中, 因此该步骤先找到指针变量名
  • 2.右左看 : 先往右看, 再往左看 ;
  • 3.确定类型 : 遇到 圆括号 “()” 或者 方括号 “[]” 确定部分类型, 调转方向 ; 遇到 * 说明是指针 , 每次确定完一个类型 , 将该类型提取出来 , 分析剩下的 ; 一种可能性 : int (*) 5 , 遇到中括号说明是数组指针类型, int(*)(int, int) , 遇到圆括号 说明是函数指针类型 ;
  • 4.重复 2 , 3 步骤 : 一直重复, 直到 指针 阅读结束 ;

然后 , 定义 自定义的 execve 函数 , 用于 替换 Android 自带的 execve 函数 , 主要用于拦截 dex2oat 字节码文件 ,

  • 这里将需要拦截的字节码都放在 dex2oat 目录中 , 检测到 dex2oat 目录 , 就退出 ;
  • 不需要拦截的 , 直接调用原函数执行 ;

源码示例 :

代码语言:javascript
复制
// 用于接收 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);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、bionic/libc/include/unistd.h#execve 函数分析
  • 二、使用自定义的 myexecve 函数替换 libc.so#execve 函数
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档