.dex文件格式
文件格式这个我觉得很死啊,就跟之前分析ELF文件格式一样,按照每个结构体对应的值来找,很无脑但是也很容易出错,我先贴个非虫的图吧,后续有机会再补充。
非虫大佬的神图:
从app_process到AndroidRuntime
一切又要从zygote进程启动开始说起,结合之前的分析,在init.rc中解析zygote的时候,zygote64.rc的内容如下:
1 | 1 service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server |
可以知道zygote要执行的程序是system/bin/app_process64
,他的源码位置在app_main.cpp,截取部分跟dvm相关的代码:
1 | 138int main(int argc, char* const argv[]) |
当执行app_main.cpp的main
函数为zygote进程的时候就会调用AppRuntime的start方法。
AppRuntime这个类如下:
1 | 32class AppRuntime : public AndroidRuntime |
继承自AndroidRuntime,跟进父类的start方法瞅瞅
1 | 797/* |
JniInvocation:加载libdvm.so
JniInvocation.cpp中的Init方法
1 | 4 static const char* kLibraryFallback = "libdvm.so"; |
粗略看下即可,针对5.0之前的系统,通过line67的dlopen
来加载"libdvm.so"
,同时还查找了三个函数,记着阿,下面要用。
##startVm:启动虚拟机
1 | 435int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) |
最核心的方法:JNI_CreateJavaVM,肯定是要略过不讲的,等以后另开一篇,反正这里虚拟机就启动了。
JniEnv加载
在startVm
方法返回之后,就拿到了虚拟机的JNI接口JNIEnv* env;
,就可以通过下面的FindClass和GetStaticMethodID来加载参数classname 值为com.android.internal.os.ZygoteInit
以及其main函数。
1 | 876 jclass startClass = env->FindClass(slashClassName); |
类的加载
todo: 上面的Jni调用到类的加载,这个过程我暂时还没梳理清楚
但这并不妨碍我分析下面2个函数 -m-
Jvm对new操作符对应的OP_NEW_INSTANCE处理如下,地址在/dalvik/vm/mterp/out/InterpC-portable.cpp
1 | 1649/* File: c/OP_NEW_INSTANCE.cpp */ |
dvmResolveClass
1 | 63ClassObject* dvmResolveClass(const ClassObject* referrer, u4 classIdx, |
总体流程已经注释好了,主要跟进dvmFindClassNoInit函数中进一步了解流程
1 | 1285ClassObject* dvmFindClassNoInit(const char* descriptor, |
继续跟进函数 findClassFromLoaderNoInit
1 | 1316 static ClassObject* findClassFromLoaderNoInit(const char* descriptor, |