zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

【Android 逆向】Dalvik 函数抽取加壳 ④ ( 类加载流程分析 | native 函数查询 | dalvik_system_DexFile.cpp#defineClassNative函数)

Android流程 函数 分析 查询 加载 system native
2023-09-14 09:07:29 时间

前言


上一篇博客 【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