/*
当第一个类执行到此函数时,我们在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);
}
安卓 dex 通用脱壳技术研究(四)