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

Posted 韩曙亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | native 函数查询 | dalvik_system_DexFile.cpp#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

以上是关于Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | native 函数查询 | dalvik_system_DexFile.cpp#defineClassNative 函数 )(代的主要内容,如果未能解决你的问题,请参考以下文章

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

Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | DexPathList#findClass 函数分析 | DexFile#loadClassBinaryName 函数 )(代码

Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | Class.cpp#findClassNoInit 函数 | DexFile.cpp#dexFindClass 函数分析 )(代

Android 逆向Dalvik 函数抽取加壳 ( 类加载流程分析 | ClassLoader#loadClass 函数分析 | BaseDexClassLoader#findClass 分析 )(代

Android 逆向ART 函数抽取加壳 ⑥ ( 函数抽取后续操作 “ 还原被抽取的函数 “ | LoadClass 类加载 | LoadClassMembers 类成员加载 )

Android 逆向加壳技术识别 ( 函数抽取 与 Native 化加壳的区分 | VMP 加壳与 Dex2C 加壳的区分 )