【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | RawDexFile.cpp 分析 | dvmRawDexFileOpen函数读取 DEX 文件 )
生活随笔
收集整理的這篇文章主要介紹了
【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 逆向】整体加固脱壳 (
- 下一篇: 【Android 逆向】整体加固脱壳 (