【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | RawDexFile.cpp 分析 | dvmRawDexFileOpen函数读取 DEX 文件 )
文章目录
- 前言
- 一、RawDexFile.cpp 中 dvmRawDexFileOpen() 方法分析
前言
上一篇博客 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 查找 DexFile 对应的C代码 | dalvik_system_DexFile.cpp 分析 ) 中 , dalvik_system_DexFile.cpp 的 Dalvik_dalvik_system_DexFile_openDexFileNative() 方法中 , 调用了 RawDexFile.cpp 中的 dvmRawDexFileOpen() 方法 ;
一、RawDexFile.cpp 中 dvmRawDexFileOpen() 方法分析
调用 open 函数 以只读形式 , 打开了 DEX 文件 ;
dexFd = open(fileName, O_RDONLY);
校验 DEX 文件 ;
verifyMagicAndGetAdler32(dexFd, &adler32) < 0
调用 DexPrepare.cpp 中的 dvmOptimizeDexFile() 函数 , 优化 DEX 文件 ;
result = dvmOptimizeDexFile(optFd, dexOffset, fileSize,fileName, modTime, adler32, isBootstrap);
源码示例 :
/** 打开一个未优化的 DEX 文件.*//* 请参阅页眉中的文档注释. */
int dvmRawDexFileOpen(const char* fileName, const char* odexOutputName,RawDexFile** ppRawDexFile, bool isBootstrap)
{/** TODO: 这复制了JarFile.c 中 dvmJarFileOpen() 的大量代码。这应该被重构。*/DvmDex* pDvmDex = NULL;char* cachedName = NULL;int result = -1;int dexFd = -1;int optFd = -1;u4 modTime = 0;u4 adler32 = 0;size_t fileSize = 0;bool newFile = false;bool locked = false;// 调用 open 函数 以只读形式 , 打开了 DEX 文件dexFd = open(fileName, O_RDONLY);if (dexFd < 0) goto bail;/* If we fork/exec into dexopt, don't let it inherit the open fd. */dvmSetCloseOnExec(dexFd);// 校验 DEX 文件 if (verifyMagicAndGetAdler32(dexFd, &adler32) < 0) {ALOGE("Error with header for %s", fileName);goto bail;}if (getModTimeAndSize(dexFd, &modTime, &fileSize) < 0) {ALOGE("Error with stat for %s", fileName);goto bail;}/** 查看缓存的文件是否匹配。如果是这样,optFd将成为一个参考* 到缓存文件,并将被查找到刚刚超过“opt”* 标题。*/if (odexOutputName == NULL) {// 优化的过程 cachedName = dexOptGenerateCacheFileName(fileName, NULL);if (cachedName == NULL)goto bail;} else {cachedName = strdup(odexOutputName);}ALOGV("dvmRawDexFileOpen: Checking cache for %s (%s)",fileName, cachedName);optFd = dvmOpenCachedDexFile(fileName, cachedName, modTime,adler32, isBootstrap, &newFile, /*createIfMissing=*/true);if (optFd < 0) {ALOGI("Unable to open or create cache for %s (%s)",fileName, cachedName);goto bail;}locked = true;/** 如果optFd指向一个新文件(因为没有缓存* 版本,或缓存的版本已过时),生成* 优化的DEX。返回的文件描述符仍处于锁定状态,* 并定位在刚好超过优化标题的位置。*/if (newFile) {u8 startWhen, copyWhen, endWhen;bool result;off_t dexOffset;dexOffset = lseek(optFd, 0, SEEK_CUR);result = (dexOffset > 0);if (result) {startWhen = dvmGetRelativeTimeUsec();result = copyFileToFile(optFd, dexFd, fileSize) == 0;copyWhen = dvmGetRelativeTimeUsec();}if (result) {result = dvmOptimizeDexFile(optFd, dexOffset, fileSize,fileName, modTime, adler32, isBootstrap);}if (!result) {ALOGE("Unable to extract+optimize DEX from '%s'", fileName);goto bail;}endWhen = dvmGetRelativeTimeUsec();ALOGD("DEX prep '%s': copy in %dms, rewrite %dms",fileName,(int) (copyWhen - startWhen) / 1000,(int) (endWhen - copyWhen) / 1000);}/** 映射缓存的版本。这会立即倒带fd,因此* 不需要在任何地方寻找。*/if (dvmDexFileOpenFromFd(optFd, &pDvmDex) != 0) {ALOGI("Unable to map cached %s", fileName);goto bail;}if (locked) {/* unlock the fd */if (!dvmUnlockCachedDexFile(optFd)) {/* uh oh -- this process needs to exit or we'll wedge the system */ALOGE("Unable to unlock DEX file");goto bail;}locked = false;}ALOGV("Successfully opened '%s'", fileName);*ppRawDexFile = (RawDexFile*) calloc(1, sizeof(RawDexFile));(*ppRawDexFile)->cacheFileName = cachedName;(*ppRawDexFile)->pDvmDex = pDvmDex;cachedName = NULL; // don't free it belowresult = 0;bail:free(cachedName);if (dexFd >= 0) {close(dexFd);}if (optFd >= 0) {if (locked)(void) dvmUnlockCachedDexFile(optFd);close(optFd);}return result;
}
【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | RawDexFile.cpp 分析 | dvmRawDexFileOpen函数读取 DEX 文件 )相关推荐
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 查找 DexFile 对应的C代码 | dalvik_system_DexFile.cpp 分析 )
文章目录 前言 一.查找 DexFile 对应的 C++ 代码 1.根据 Native 文件命名惯例查找 C++ 代码 2.根据方法名查找 二.dalvik_system_DexFile.cpp 源码 ...
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexFile loadDexFile 函数 | 构造函数 | openDexFile 函数 )
文章目录 前言 一.DexFile.loadDexFile 函数分析 二.DexFile 构造函数分析 三.DexFile.openDexFile 函数分析 前言 上一篇博客 [Android 逆向] ...
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexPathList 中根据 File 加载 DexFile | loadDexFile 分析 )
文章目录 前言 一.根据 File 加载 DexFile 二.DexPathList.loadDexFile 函数分析 前言 上一篇博客 [Android 逆向]整体加固脱壳 ( DexClassLo ...
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexPathList 构造函数分析 | makeDexElements 函数分析 )
文章目录 前言 一.DexPathList 构造函数分析 二.DexPathList.makeDexElements 函数分析 三.Element 类分析 前言 上一篇博客 [Android 逆向]整 ...
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | 类加载器构造函数分析 | DexPathList 引入 )
文章目录 一.DexClassLoader 类加载器构造函数分析 二.DexPathList 引入 一.DexClassLoader 类加载器构造函数分析 DexClassLoader 是加载 dex ...
- 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )
文章目录 一.DexClassLoader 源码分析 二.参考 Dalvik 下的 DexClassLoader 类加载流程 一.DexClassLoader 源码分析 ART 虚拟机下的 DexCl ...
- 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | oat_file_assistant.cc 中涉及的 oat 文件生成流程 )
文章目录 前言 一.dalvik_system_DexFile.cc#DexFile_openDexFileNative 函数分析 二.oat_file_manager.cc#OpenDexFiles ...
- 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | exec_utils.cc 中执行 Dex 编译为 Oat 文件的 Exec 和 ExecAndReturnC函数 )
文章目录 前言 一.exec_utils.cc#Exec 函数分析 二.exec_utils.cc#ExecAndReturnCode 函数分析 前言 在上一篇博客 [Android 逆向]ART 脱 ...
- java 加载dll后打包_让Jacob从当前路径读取dll文件及相关打包方法
让Jacob从当前路径读取dll文件及相关打包方法 独立观察员2013.08.12 Jacob LibraryLoader.class修改版代码 功能:让jacob可在当前路径下的dll文件夹内读取 ...
最新文章
- ElasticSearch 面试 4 连炮,你顶得住么?
- Windows服务器上Mysql为设置允许远程连接提示:not allowed to connect to this MySQL server
- 好货日报邀请码54321软件的操作逻辑
- C++原子操作 atomic的使用及效率
- linux几种方式来弹哥shell
- Windows Server 2008 R2 Server Core文件操作命令
- 安装软件报:The installer has encountered an unexpected error installing this package....此类错误...
- MATLAB 官方文档
- delphi 剪切板变量_delphi clipbrd剪贴板的读写和清除功能
- 10.计算机基础之程序设计基础
- ong拼音汉字_汉语拼音ang-ong(教案)
- 反射+泛型+注解(demo)
- python三维网格图_python 可视化 ploty 画3dmesh网格图
- 蔚来、小鹏、理想自动驾驶能力的纵向演进与横向比较
- Android8-Settings-BlueTooth
- CollectionView的HeaderView头视图悬停
- 外观html与外观css的区别,用房间和装修来解读html代码与css样式的区别和关系
- GitHub上最火的两份Java面试小册,Star已经超百万
- 聊聊C10K问题及解决方案
- 前端React单点登录的实现