【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | exec_utils.cc 中执行 Dex 编译为 Oat 文件的 Exec 和 ExecAndReturnC函数 )
2023-09-14 09:07:29 时间
前言
在上一篇博客 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | oat_file_assistant.cc 中涉及的 oat 文件生成流程 ) 中分析到 将 Dex 文件编译为 Oat 文件 , 最终在 oat_file_assistant.cc#Dex2Oat 函数中 , 调用了 exec_utils.cc#Exec 函数 , 在该函数中执行最后的转换操作 ;
一、exec_utils.cc#Exec 函数分析
在 exec_utils.cc#Exec 函数 中 , 调用了 ExecAndReturnCode 方法 ;
bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg) {
// ★ 核心跳转
int status = ExecAndReturnCode(arg_vector, error_msg);
if (status != 0) {
const std::string command_line(android::base::Join(arg_vector, ' '));
*error_msg = StringPrintf("Failed execv(%s) because non-0 exit status",
command_line.c_str());
return false;
}
return true;
}
源码路径 : http://aospxref.com/android-8.0.0_r36/xref/art/runtime/exec_utils.cc#Exec
二、exec_utils.cc#ExecAndReturnCode 函数分析
在该函数中 , 先 fork 一个进程 ,
pid_t pid = fork();
使用 execve 函数 , 执行 Dex 文件编译为 Oat 文件操作 ;
execve(program, &args[0], envp);
exec_utils.cc#ExecAndReturnCode 函数源码 :
int ExecAndReturnCode(std::vector<std::string>& arg_vector, std::string* error_msg) {
const std::string command_line(android::base::Join(arg_vector, ' '));
CHECK_GE(arg_vector.size(), 1U) << command_line;
// 将参数转换为字符指针。
const char* program = arg_vector[0].c_str();
std::vector<char*> args;
for (size_t i = 0; i < arg_vector.size(); ++i) {
const std::string& arg = arg_vector[i];
char* arg_str = const_cast<char*>(arg.c_str());
CHECK(arg_str != nullptr) << i;
args.push_back(arg_str);
}
args.push_back(nullptr);
// fork and exec
pid_t pid = fork();
if (pid == 0) {
// fork和exec之间不允许分配
// 更改流程组,这样我们就不会被ProcessManager收获
setpgid(0, 0);
// (b/30160149): 保护子进程不受对LD_LIBRARY_路径等的修改的影响。
// 使用从创建运行时开始的环境快照。
char** envp = (Runtime::Current() == nullptr) ? nullptr : Runtime::Current()->GetEnvSnapshot();
if (envp == nullptr) {
execv(program, &args[0]);
} else {
execve(program, &args[0], envp);
}
PLOG(ERROR) << "Failed to execve(" << command_line << ")";
// _exit to avoid atexit handlers in child.
_exit(1);
} else {
if (pid == -1) {
*error_msg = StringPrintf("Failed to execv(%s) because fork failed: %s",
command_line.c_str(), strerror(errno));
return -1;
}
// 等待子进程完成
int status = -1;
pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
if (got_pid != pid) {
*error_msg = StringPrintf("Failed after fork for execv(%s) because waitpid failed: "
"wanted %d, got %d: %s",
command_line.c_str(), pid, got_pid, strerror(errno));
return -1;
}
if (WIFEXITED(status)) {
return WEXITSTATUS(status);
}
return -1;
}
}
相关文章
- [Android Pro] linux下查看一个文件的属性(ls,lsattr,file,stat)
- [Android Memory] 使用 Eclipse Memory Analyzer 进行堆转储文件分析
- Android问题-DelphiXE8安装后编译Android提示SDK无法更新问题(XE10也可以解决)
- Android开发学习---android下的数据持久化,保存数据到rom文件,android_data目录下文件访问的权限控制
- android开发学习---linux下开发环境的搭建&& android基础知识介绍
- Android开发之adb无法连接
- Android多媒体开发--资源文件播放
- android 布局页面文件出错故障排除Exception raised during rendering: java.lang.System.arraycopy([CI[CII)V
- 微信抢红包软件-android
- Android App签名(证书)校验过程源码分析
- Android Studio - xml布局文件不显示代码怎么办?
- 【Android笔记02】Android目录结构及相关文件介绍
- android 11.0 设置wifi白名单
- Android 10.0 系统设置开启始终在后台运行的权限
- Android 内存抖动的介绍
- android 堆内存和栈内存详解
- 基于NDK开发Android平台RTSP播放器
- 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | oat_file_assistant.cc 中涉及的 oat 文件生成流程 )
- 【Android 逆向】Android 系统文件分析 ( 外部存储设备文件 | sbin 命令程序目录 | dev 字符设备目录 )
- Android 获取手机IP(3G/4G/WIFI/无网络)
- Android Kotlin 文件工具类 - 沙盒内文件和图像的读写和删除