文章目录
前言
一、查询 defineClassNative 函数
二、dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative 函数分析
前言
上一篇博客 【Android 逆向】Dalvik 函数抽取加壳 ( 类加载流程分析 | DexPathList#findClass 函数分析 | DexFile#loadClassBinaryName 函数 ) 中 , 分析到了调用到 DexFile#loadClassBinaryName 函数 , 该函数是 native 函数 ;
一、查询 defineClassNative 函数
在 Android 源码页面 http://androidxref.com/4.4.4_r1 , 选中 dalvik 工程 , 然后在 " Full Search " 中搜索 defineClassNative 函数 ;
查询出的对应的 native 函数是 /dalvik/vm/native/dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative ,
二、dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative 函数分析
在 /dalvik/vm/native/dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative 函数中 , 如果加载的是 dex 文件 , 则调用 dvmGetRawDexFileDex 函数 ;
// 如果加载的是 dex 文件 , 走这个分支 pDvmDex = dvmGetRawDexFileDex(pDexOrJar->pRawDexFile);
dvmGetRawDexFileDex 函数定义在 /dalvik/vm/RawDexFile.h#dvmGetRawDexFileDex 中 , 该函数实现很简单 :
/* * 从 RawDexFile 中撬出 DexFile。 */ INLINE DvmDex* dvmGetRawDexFileDex(RawDexFile* pRawDexFile) { return pRawDexFile->pDvmDex; }
在之后 , 调用了 Class.cpp#dvmDefineClass 函数 ;
dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative 函数源码 :
/* * 私有静态类defineClassNative(字符串名称、类加载器、, * int cookie) * * 从DEX文件加载类。这大致相当于defineClass() * 在常规VM中——类装入器调用它以导致 * 创建特定类。不同之处在于,搜索和 * 字节的读取是在VM中完成的。 * * 类名是一个“二进制名称”,例如“java.lang.String”。 * * 如果找不到类,则返回空指针,无异常。 * 在其他失败时引发异常。 */ 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; // 获取 cookie 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) // 如果加载的是 dex 文件 , 走这个分支 pDvmDex = dvmGetRawDexFileDex(pDexOrJar->pRawDexFile); else pDvmDex = dvmGetJarFileDex(pDexOrJar->pJarFile); /* 一旦加载了某些内容,就无法取消映射存储 */ pDexOrJar->okayToFree = false; // 此处加载类 clazz = dvmDefineClass(pDvmDex, descriptor, loader); Thread* self = dvmThreadSelf(); if (dvmCheckException(self)) { /* * 如果我们抛出了一个“未找到类”异常,请扼杀它,因为 * 较高方法中的contract表示,如果 * 找不到该类。 */ 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); }
源码路径 : /dalvik/vm/native/dalvik_system_DexFile.cpp#Dalvik_dalvik_system_DexFile_defineClassNative
