本课只以Dalvik类加载为解说,至于ART类加载,课后自行解决,实际上,从本质和函数来看,基本还是一样的,只是把dexopt过程换成dex2oat过程,在类加载中关键函数名进行变更。
1.DEX文件优化与验证:
run_dexopt:
static const char* Dex_OPT_BIN = "/system/bin/dexopt"
\dexopt\Optmain.cpp:extractAndProcessZip() //读取和抽出dex,加上odex文件头,设置优化选项,可以看作DEX文件优化的主控函数
\vm\analysis\DexPrepare.cpp:dvmContinueOptimization()//写入odex文件,可以说优化与验证工作的完成就是写入odex文件
2.DEX文件解析:
\vm\RawDexFile.cpp:dvmRawDexFileOpen()//DEX文件解析的主控函数
\libdex\OptInvocation.cpp:dexOptGenerateCacheFileName()//生成该dex对应odex文件
\vm\DvmDex.cpp:dvmDexFileOpenFromFd()//完成对DEX文件映射,设置为只读文件,并进一步优化
\libdex\DexFile.cpp:dexFileParse()//解析DEX
在实践中,我们发现并不是所有的dexfileopenpartial都能断下来,但 _Z27dexOptGenerateCacheFileNamePKcS0
dvmdexfileopenfromfd
dvmdexfileparse
这些函数一定能断下来,而dexfileopenpartial常常在有壳时,也就是真正dex出现时才可以断下来,由此可知,其实dalvik很喜欢走的路就是用odex,而不是dex。dex文件只有在odex文件不好用时才去用,这与oat文件一致。
3.DEX类加载
\vm\native\dalvik_system_DexFile.cpp:
Dalvik_dalvik_system_DexFile_defineClassNative //类加载的主控函数
\vm\oo\Class.cpp:dvmDefineClass()//确认类加载描述符进行类加载
\vm\oo\Class.cpp:findClaaNoInit()//完成实际类加载工作
\vm\oo\Class.cpp:loadClassFromDex()//返回值是一个ClassObject结构体,实际加载
往后便是FindClass、GetStaticMthodID、CallStaticMthod、dvmInterpretStd
Dalvik字节码的宏指令
其他如DexDump.cpp也是我们需要注意的一个源码文件,本身就是在解析重组dex文件
image image
网友评论