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 加壳的区分 )