脱壳成长之路(2)-2代壳进阶(2)
2020-02-04 12:48:07 Author: bbs.pediy.com(查看原文) 阅读量:313 收藏

样本:很老的x度加固

分析工具:ida、jeb、010、apktool

NativeHook:基于Substrate的Nativehook

Android系统: 4.4

上一篇主要分析了,如何直接进入JNIONLOAD,这篇我们继续分析

修复dexdump后的文件

首先按照国际惯例,直接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编辑 ,原因: 补充一张图片


文章来源: https://bbs.pediy.com/thread-257474.htm
如有侵权请联系:admin#unsafe.sh