【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 自定义控件开发入门(二)
- 《Gradle权威指南》--Android Gradle NDK支持
- 从代码分析Android-Universal-Image-Loader的图片加载、显示流程
- android 动画基础绘——view 动画
- android系统插入硬件盘流程日志log
- android 升级ota 命令方式
- Android音量设置流程及调试方法
- Android WiFi —softAP流程分析
- android系统电源管理分析
- Android app 自定义可横竖滑动的RecyclerView(一)
- android Q(10.0)拨打电话(拨号)功能屏蔽流程(一)
- Android 自定义View关于measure流程的基本思路整理
- 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | oat_file_assistant.cc 中涉及的 oat 文件生成流程 )
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | RawDexFile.cpp 分析 | dvmRawDexFileOpen函数读取 DEX 文件 )
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexFile loadDexFile 函数 | 构造函数 | openDexFile 函数 )
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexPathList 构造函数分析 | makeDexElements 函数分析 )
- 【Android 逆向】逆向修改游戏应用 ( APK 解析工具 | 解包 -> 分析 -> 重打包 -> 签名 流程 )
- 【Android 逆向】ELF 文件格式 ( ELF 文件当前版本号 | 操作系统 ABI 信息 | ABI 版本 | 文件头校验 | 文件头长度信息 )
- 【Android 进程保活】应用进程拉活 ( JobScheduler 拉活 | JobScheduler 使用流程 | JobService 服务 | 不同版本兼容 | 源码资源 )
- Android深入源代码分析理解Aidl总体调用流程(雷惊风)
- Android图像篇
- Android 输入法框架流程整理
- Android 11.0 系统framework发送悬浮通知的流程分析
- Android判断是否使用MediaCodec硬解码(十二)
- Android OpenGL/Gralloc到framebuffer和LCD流程(六)