华为开发者空间
安卓 dex 通用脱壳技术研究(四)
安卓 dex 通用脱壳技术研究(四)
http://my.oschina.net/cve2015/blog/508919摘要 本文剖析安卓Dalvik 解释器 Portable 的原理与实现,并通过修改 Dalvik 虚拟机实现 dex 文件的通用脱壳方案;本方法同样适应于 ART 虚拟机;?1234567
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
*)¶m);
//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);
}
|
- 9462
- 0
- 0
- 0
扫一扫分享内容
- 分享
回到
顶部
顶部
所有评论(0)