Java层 Dex加载流程 网上 有很多帖子 都写得很不错 如果感兴趣的话 可以 找几篇看看
大概描述:
DexClassLoader ->
父类BaseDexClassLoader的构造->
new DexPaseList->
makeDexElements->将dex分割 可能有多个Dex(返回一个 Elements[]),赋值给成员变量
LoadDexFile->
DexFile->
OpenDexFile->返回mCookie(DexOrJar)
OpenDexFileNative->
最终调用 OpenDexFileNative-> 进行dex解析
下面一起分析一下 4.4 Dvm虚拟机中 openDexFileNativie
到底做了什么
路径/aosp/dalvik/vm/mk文件/编译 最终 生成 libdvm.so
找到 OpenDexFileNative-> 函数
先判断是否有无文件 没有 进行 加载 调用 dvmRawDexFileOpen
判断是否需要提取odex文件 odex文件 是 优化后的 dex文件 第一次启动时候 会进行优化 拿到 缓冲文件的名字 (此函数 是生成 odex 文件 的 函数 ) 将Odex进行打开 从optFd里面打开 这个 odex文件 把结果 放到 pDvmDex的结构体中 结构体详情 (Dvm虚拟机 表示dex文件的结构体) 如果 返回成功 就会将 dexFile结构体 作为参数 初始化到 dvm虚拟机里面(结构体是DvmDex) ,作为结果进行返回 (allocateAuxStructures)继续跟进dexFileParse-> 三个参数
1,odex的地址
2,文件长度
3,flag
先创建指定大小的 内存 ,然后对 地址的 前四个字节 是否是 dey进行判断 (判断是否是odex文件 ) Dex_OPT_MAGIC的具体字符串(结合上图) 都通过以后 会调用 进行加载 加载成功 会对 Header偏移重新计算 ,拿到 真正dex头的偏移, 然后继续调用 把其他位置的偏移 进行 赋值到 dex 。具体函数 如下
初始化 完事后 进行 效验 文件头是否合法 此时已经是dex文件 下面 会进行 checksum 和 SHA值进行校验 检测是否合法 如果都通过了 会返回 dexFile(DexFile结构体 ) 到此结束 返回 到 openDexFileNative->函数 读取成功以后读取成功 以后 将 pDexOrJar->fileName 进行赋值
将加载以后的mCookie通过调用 addToDexFileTable 添加到 Table中
通过调用 dvmHashTableLookup函数 把mCookie 复制到 hashTable中去 hashTable是gDvm中的 变量 如下图 这也是个脱壳点 可以 通过遍历HashTable 拿到全部的 dex信息到这openDexFileNative 函数 跑完了
最后 返回的就是mCookie
其实返回是一个 DexOrJar
如果 java层 用到某一个类的话 会调用findClass
从mCookie 进行加载
在代码中 有一个 *gDvm变量,简单说明一下
* gDvm(主要保存了 程序 在 dvm虚拟机的一些数据,
是全局变量,每一个 dvm上面的程序 创建的时候 必须初始化的变量
,也会存放 dex的一些数据 进行缓存 来达到 优化的作用 )
如果对 逆向,脱壳,新技术 感兴趣的 同学 可以加 我Q群 欢迎各位能人志士 一起讨论
欢迎加入故事,群聊号码:773642813
珍惜
2018年10月08日10:32:45
-----------------------------------------------------------------------------------------------------------------------------------------
网友评论