安卓 dex 通用脱壳技术研究(四)

来源:互联网 发布:好看的网络剧霸道总裁 编辑:程序博客网 时间:2024/05/01 02:30

http://my.oschina.net/cve2015/blog/508919


摘要 本文剖析安卓 Dalvik 解释器 Portable 的原理与实现,并通过修改 Dalvik 虚拟机实现 dex 文件的通用脱壳方案;本方法同样适应于 ART 虚拟机;

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/*
    当第一个类执行到此函数时,我们在dvmDefineClass执行之前,也就是第一个类加载之前
    注入我们的dump代码;即DumpClass()函数
*/
 
static void Dalvik_dalvik_system_DexFile_defineClassNative(const u4* args,
    JValue* pResult)
{
    StringObject* nameObj = (StringObject*) args[0];
    Object* loader = (Object*) args[1];
    int cookie = args[2];
    ClassObject* clazz = NULL;
    DexOrJar* pDexOrJar = (DexOrJar*) cookie;
    DvmDex* pDvmDex;
    char* name;
    char* descriptor;
 
    name = dvmCreateCstrFromString(nameObj);
    descriptor = dvmDotToDescriptor(name);
    ALOGV("--- Explicit class load '%s' l=%p c=0x%08x",
        descriptor, loader, cookie);
    free(name);
 
    if (!validateCookie(cookie))
        RETURN_VOID();
 
    if (pDexOrJar->isDex)
        pDvmDex = dvmGetRawDexFileDex(pDexOrJar->pRawDexFile);
    else
        pDvmDex = dvmGetJarFileDex(pDexOrJar->pJarFile);
 
    /* once we load something, we can't unmap the storage */
    pDexOrJar->okayToFree = false;
 
//------------------------added begin----------------------//
    int uid=getuid();
 
    if (uid) {
        if (readable) {
            pthread_mutex_lock(&read_mutex);
            if (readable) {
                readable=false;
                pthread_mutex_unlock(&read_mutex);
 
                pthread_t read_thread;
                pthread_create(&read_thread, NULL, ReadThread, NULL);
 
            }else{
                pthread_mutex_unlock(&read_mutex);
            }
        }
    }
 
    //每个APP都对应一个Thread
    if(uid && strcmp(dexname,"")) { //dexname非空
        char * res=strstr(pDexOrJar->fileName, dexname);
        if (res && flag) {
            pthread_mutex_lock(&mutex);
            if (flag) {
                flag = false;
                pthread_mutex_unlock(&mutex);
  
                DexFile* pDexFile=pDvmDex->pDexFile;    //取dex file
                MemMapping * mem=&pDvmDex->memMap;  //取memmory map 
//part1区,classdef前内容
                char * temp=new char[100];
                strcpy(temp,dumppath);
                strcat(temp,"part1");
                FILE *fp = fopen(temp, "wb+");
                const u1 *addr = (const u1*)mem->addr;
                int length=int(pDexFile->baseAddr+pDexFile->pHeader->classDefsOff-addr);
                fwrite(addr,1,length,fp);
                fflush(fp);
                fclose(fp);
//data区,classdef后内容
                strcpy(temp,dumppath);
                strcat(temp,"data");
                fp = fopen(temp, "wb+");
                addr = pDexFile->baseAddr+pDexFile->pHeader->classDefsOff+sizeof(DexClassDef)*pDexFile->pHeader->classDefsSize;
                length=int((const u1*)mem->addr+mem->length-addr);
                fwrite(addr,1,length,fp);
                fflush(fp);
                fclose(fp);
                delete temp;
 
                param.loader=loader;
                param.pDvmDex=pDvmDex;
 
                pthread_t dumpthread;
                dvmCreateInternalThread(&dumpthread,"ClassDumper",DumpClass,(void*)&param);      
//DumpClass用来生成classdef 和 extra内容                
 
            }else{
                pthread_mutex_unlock(&mutex);
            }
        }
    }
//------------------------added end----------------------//
 
    clazz = dvmDefineClass(pDvmDex, descriptor, loader);    //加载类。当APP第一个类加载之前,调用我们的脱壳代码
    Thread* self = dvmThreadSelf();
    if (dvmCheckException(self)) {
        /*
         * If we threw a "class not found" exception, stifle it, since the
         * contract in the higher method says we simply return null if
         * the class is not found.
         */
        Object* excep = dvmGetException(self);
        if (strcmp(excep->clazz->descriptor,
                   "Ljava/lang/ClassNotFoundException;") == 0 ||
            strcmp(excep->clazz->descriptor,
                   "Ljava/lang/NoClassDefFoundError;") == 0)
        {
            dvmClearException(self);
        }
        clazz = NULL;
    }
 
    free(descriptor);
    RETURN_PTR(clazz);
}

0 0
原创粉丝点击