文章目录
- 前言
- 一、DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析
- 二、/bin/dexopt 源码分析
前言
上一篇博客 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | RawDexFile.cpp 分析 | dvmRawDexFileOpen函数读取 DEX 文件 ) 中 , 在 RawDexFile.cpp 中的 dvmRawDexFileOpen() 方法中 , 调用了 DexPrepare.cpp 的 dvmOptimizeDexFile() 函数 , 对 DEX 文件进行了优化 ;
一、DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析
dvmOptimizeDexFile 函数的参数说明 : int fd
是打开的 dex 文件标识符 , long dexLength
是打开的 dex 文件大小 ;
在该函数中 , 调用 /bin/dexopt 程序 , 优化 dex 文件 , 最终产生 odex 文件 ;
代码语言:javascript复制/*
* 给定包含DEX数据的文件的描述符,生成
* 优化版本。
*
* “fd”指向的文件应为锁定的共享资源
* (或私人);我们不努力实施多进程正确性
* 在这里。
*
* “文件名”仅用于调试输出。存储“modWhen”和“crc”
* 在依赖项集中。
*
* “isBootstrap”标志确定优化器和验证器如何处理
* 包范围访问检查。优化时,我们只加载引导
* 类DEX文件和目标DEX,因此该标志确定
* 给目标DEX类一个(合成的)非空类加载器指针。
* 只有当目标DEX包含声明
* 与引导类位于同一个包中。
*
* 优化器需要加载目标DEX文件中的每个类。
* 这通常是不可取的,因此我们启动一个子流程来执行
* 工作并等待它完成。
*
* 成功时返回“true”。所有数据均已写入“fd”。
*/
bool dvmOptimizeDexFile(int fd, off_t dexOffset, long dexLength,
const char* fileName, u4 modWhen, u4 crc, bool isBootstrap)
{
const char* lastPart = strrchr(fileName, '/');
if (lastPart != NULL)
lastPart ;
else
lastPart = fileName;
ALOGD("DexOpt: --- BEGIN '%s' (bootstrap=%d) ---", lastPart, isBootstrap);
pid_t pid;
/*
* 如果我们的bootclasspath中出现了我们认为
* 都优化了,被拒绝了。
*/
if (gDvm.optimizing) {
ALOGW("Rejecting recursive optimization attempt on '%s'", fileName);
return false;
}
pid = fork();
if (pid == 0) {
static const int kUseValgrind = 0;
// 调用 /bin/dexopt 程序 , 优化 dex 文件 , 最终产生 odex 文件
static const char* kDexOptBin = "/bin/dexopt";
static const char* kValgrinder = "/usr/bin/valgrind";
static const int kFixedArgCount = 10;
static const int kValgrindArgCount = 5;
static const int kMaxIntLen = 12; // '-' 10dig '