样本:很老的x度加固
分析工具:ida、jeb、010、apktool
NativeHook:基于Substrate的Nativehook
Android系统: 4.4
上一篇主要分析了,如何直接进入JNIONLOAD,这篇我们继续分析
首先按照国际惯例,直接hook dvmDexFileOpenPartial 然后dump出dex,拖到010中查看
可以看到,到这个annotations_off就卡住了,解析不了。
我自己的思路,我要先确定壳没有去对其他关键函数做手脚。然后我就去找了一个,加载dex一定会用到的函数dexFindClass函数
if (old_findDex == NULL) { elf_hook("libdvm.so", "_Z12dexFindClassPK7DexFilePKc", (void *) &new_dexFindClass, (void **) &old_findDex); }
void *new_dexFindClass(const void *pDexFile, const char *descriptor) {}
我还特意打印了descriptor,确定了DexFile。然后我就根据pDexFile,将整个dexdump出来
char *file_name = "/data/data/com.qsq.qianshengqian/1.dex"; FILE *dex_file = fopen(file_name, "wb+"); fwrite(dexFile->pHeader, dexFile->pHeader->fileSize, 1, dex_file); fclose(dex_file);
最终发现,两次dump出的dex是一样的,这就说明,系统确实也是用了这个dexFile去加载了。
好的 那么我们回到上面的图片继续分析,可以看到直接卡在了annotation_off就分析不下去了,这里我卡了一段时间,起初我以为是壳做了什么操作,还是分析了so。后来发现并没有,可能是因为有些注解是动态的,所以导致无法解析dex文件,所以我做了一些操作为了能在010中更好的观察,我直接将注解偏移改为0
u4 *off = &(pDef->annotationsOff);
*off = 0;
好了,现在好看很多。
我们继续看010,发现class_data_off出现了超大偏移(实际上是负偏移)
通过hook,打印class_data_off看看
果然很多负数偏移。
这种情况,我的思路,先从内存中dump class_data,dump到一个新文件中,然后原文件重新修复class_data_off地址,最后再拼接两个文件,直接上代码
void *new_dexFindClass(const void *pDexFile, const char *descriptor) { DexFile *dexFile = (DexFile *) pDexFile; if (dexFile->pHeader->fileSize == 5573376 && a == 0 ) { log("%s","start dump"); a = 1; size_t size = dexFile->pHeader->fileSize; DexClassDef *pDef = dexFile->pClassDefs; // log("class def size is %d", dexFile->pHeader->classDefsSize); int classDefSize = dexFile->pHeader->classDefsSize; log("%d",classDefSize); //2.dex保留classdef。 FILE *pFile = fopen("/data/data/com.qsq.qianshengqian/2.dex", "wb+"); u4 currentLength =dexFile->pHeader->fileSize; for (int i = 0; i < classDefSize; ++i) { if (pDef->classDataOff != 0) { const u1 *start = dexGetClassData(dexFile, pDef); DexClassData *pData = ReadClassData(&start); int len = 0; u4 f_off = currentLength + len; uint8_t *string = EncodeClassData(pData, len); fwrite(string, 1, len, pFile); currentLength = currentLength + len; //重置偏移, if (i<4495) { u4 *def_off = &(pDef->classDataOff); *def_off = f_off; } } //重置annotation u4 *off = &(pDef->annotationsOff); *off = 0; pDef++; } log("%s","write compete"); fclose(pFile); char *file_name = "/data/data/com.qsq.qianshengqian/1.dex"; FILE *dex_file = fopen(file_name, "wb+"); fwrite(dexFile->pHeader, dexFile->pHeader->fileSize, 1, dex_file); fclose(dex_file); } return old_findDex(pDexFile, descriptor); }
注:上面dexGetClassData和readClassdata参考了dexhunter的代码。具体代码会在最后面打包给出。
最终会dump出两个文件,然后我们把两个文件拼接到一起,别忘记baksmali/smali一下,因为我拼接的文件并不是一个标准的dex文件,然后拖入jeb
然后发现看得到代码了。
但是,重新打包崩溃了。大概的意思是onCreate中没有调用super.onCreate()
结果仔细查看smali发现,onCreate中调用了onCreate001,但是onCreate001中都是nop
OK,dex的第一步修复就到此为止,下一篇我们继续分析onCreate001.
2020安全开发者峰会(2020 SDC)议题征集 中国.北京 7月!
最后于 10小时前 被GitRoy编辑 ,原因: 补充一张图片