首页
社区
课程
招聘
[原创]Android6.0 dex加载之dexClassLoader分析
发表于: 2020-3-26 19:15 6735

[原创]Android6.0 dex加载之dexClassLoader分析

2020-3-26 19:15
6735

http://androidxref.com/6.0.0_r1

​ 首先,掠过一些步骤分析,这些代码很简单,一步一步跟就能进来了,这里只列出跟踪流程

​ dexClassLoader->BaseDexClassLoader->DexPathList->makePathElements->loadDexFile->DexFile

开始脱发!

DexFile

xref: /libcore/dalvik/src/main/java/dalvik/system/DexFile.java

其中有这样一句代码 mCookie = openDexFile(sourceName, outputName, flags)

是否意味我们只要将mCookie值正确获取返回即可成功完成dexClassLoader的初始化呢,我们接着往下面跟

openDexFile

xref: /libcore/dalvik/src/main/java/dalvik/system/DexFile.java

里面调用了一个openDexFileNative函数获取cookie的返回值

openDexFileNative

函数原型:

gMethods

xref: /art/runtime/native/dalvik_system_DexFile.cc

内容:

可以看到,追踪到了c++代码中,此处有一个数组gMethods[] 存放着接口方法的地址,这里和4.4的源码不同,没有直接传递内存数组的方法,所以只能继续往下面走。

注册宏的定义

xref: /art/runtime/jni_internal.h

翻译一下:

​ 函数地址:className_funtionName

即我们要找的函数名为:DexFile_openDexFileNative

下面的宏定义REGISTER_NATIVE_METHODS,注册函数

DexFile_openDexFileNative

xref: /art/runtime/native/dalvik_system_DexFile.cc

其中,有一句很关键
dex_files = linker->OpenDexFilesFromOat(sourceName.c_str(), outputName.c_str(), &error_msgs);

OpenDexFilesFromOat:从oat中获取Dex文件数组,然后把他转成java的数组,返回数组指针,也就是我们得分析如何将自己的dex文件放到这个数组中去,继续跟。

OpenDexFilesFromOat

xref: /art/runtime/class_linker.cc

还好是从后往前看的,最后一行注释,如果没有从oat文件中找到dex文件,我们就执行下面的代码!!ohohohoh!!

下面做了什么呢?

翻译翻译?

如果dex文件数组为空,调用DexFile::Open(dex_location, dex_location, &error_msg, &dex_files)

如果返回值是true,则啥也不干,返回dex_files数组,程序正常结束,如果返回值是false,输出错误日志,往error_msgs中存入错误信息。

DexFile::Open

xref: /art/runtime/dex_file.cc

ok,这段代码就是判断一下当前是什么文件,若是dex文件,则调用DexFile::OpenFile(fd.release(), location, true,error_msg),构造dex文件,并将其放入文件数组中,返回值为文件数组。

DexFile::OpenFile

xref: /art/runtime/dex_file.cc

关键点来了:

std::unique_ptr<const DexFile> dex_file(OpenMemory(location, dexheader->checksum, map.release(),error_msg));

调用OpenMemory函数完成了dex文件的加载

OpenMemory

这里有2个OpenMemory重载函数,我们终于找到了我们想要的一个,也就是能够直接传递数组指针的那个,代码如下

xref: /art/runtime/dex_file.cc

第一个重载函数是传递的文件名,然后直接将其映射到内存,调用第二个函数加载。第二个重载函数,则是传入的内存中的缓冲区指针,第二个参数为缓冲区大小。

在6.0系统下,该方法和5.0,4.4系统都差不多,返回一个mCookie值,存放至classLoader中

具体流程:

findClass

DexPathList.findClass

xref: /libcore/dalvik/src/main/java/dalvik/system/DexPathList.java

loadClassBinaryName


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2020-3-26 19:19 被夜航星编辑 ,原因: 排版错误
收藏
免费 4
支持
分享
最新回复 (6)
雪    币: 1636
活跃值: (653)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
大佬
2020-3-27 12:36
0
雪    币: 5235
活跃值: (3260)
能力值: ( LV10,RANK:175 )
在线值:
发帖
回帖
粉丝
3
支持大佬,可以结合我的c++层分析一块看https://bbs.pediy.com/thread-257893.htm
2020-3-28 17:53
0
雪    币: 137
活跃值: (418)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
鹏总牛比
2020-3-28 23:25
0
雪    币: 1657
活跃值: (924)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
情趣杜蕾斯 鹏总牛比
老哥别奶我。
2020-3-29 11:59
0
雪    币: 866
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
分析到位,对我这样的新手很有收获,赞
2020-3-29 16:32
0
雪    币: 1620
活跃值: (2405)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
7
鹏总强
2020-10-7 23:17
0
游客
登录 | 注册 方可回帖
返回
//