Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | exec_utils.cc 中执行 Dex 编译为 Oat 文件的 Exec 和 ExecAndReturnC函数 )(代
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | exec_utils.cc 中执行 Dex 编译为 Oat 文件的 Exec 和 ExecAndReturnC函数 )(代相关的知识,希望对你有一定的参考价值。
前言
在上一篇博客 【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 逆向ART 脱壳 ( DexClassLoader 脱壳 | exec_utils.cc 中执行 Dex 编译为 Oat 文件的 Exec 和 ExecAndReturnC函数 )(代的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向ART 脱壳 ( InMemoryDexClassLoader 脱壳 | DexFile 构造函数及相关调用函数 | Android 源码中查找 native 函数 )
Android 逆向ART 脱壳 ( 修改 /art/runtime/dex_file.cc#OpenCommon 系统源码进行脱壳 )
Android 逆向ART 脱壳 ( InMemoryDexClassLoader 脱壳 | InMemoryDexClassLoader 类加载器脱壳点总结 )
Android 逆向ART 脱壳 ( InMemoryDexClassLoader 脱壳 | 加固厂商在 ART 下使用的两种类加载器 | InMemoryDexClassLoader 源码 )(代码
Android 逆向ART 脱壳 ( InMemoryDexClassLoader 脱壳 | dex_file.cc 中创建 DexFile 实例对象的相关函数分析 )
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段