art虚拟机分析

2 篇文章 0 订阅
2 篇文章 0 订阅

art虚拟机将dex编译成ota后,生成oat文件,该文件结构包含如下几部分

1 header 部分,记录一些meta信息(其实header是包含在oatdata部分的,可以通过导出部分找到对应的oatdata,也就可以找到队一个的header部分)

2  oatdata部分,保存各个原始dex信息

3 oatexec部分,保存dex经过llvm编译后的机器代码

4 导出符号部分,用于dlopen解析符号,找到oatdata部分

oat文件分为两种格式,一种是dlfile这种格式可以通过动态链接的方式导入符号,

另外一种是google自定义的格式Elffile,这种格式记录的信息更多,

所以不用动态去加载其他库的导出符号,因为其他库的导出符号会被记录在这个oat文件中

加载oat文件会建立oatdata和oatexec之间的关系,也就是原始dex和编译后的机器码之间的关系,

这样在链接的时候(classload).就可以根据dex的java类信息找到相应的oat了以及该类下的方法字段等.

AndroidRutime启动art的时候,首先会加载运行时环境,相当于jvm中BootClassLoader加载路径下的jar文件,

art创建是时候首先会创建JavaVMExt(用于记录虚拟机的全局信息),也就是实现jni时候经常要传递的参数,

然后创建虚拟机执行的主线程,也就是当前线程,之后为这个线程创建JNIEnvExt(env),该变量也是jni函数必然

传递的参数,env是每个java虚拟机线程一份的.用于传递虚拟机的运行时环境,已经java虚拟机的提供jni调用的方法,

这些方法来自于jin_internal.cc中的 JNI类实现,由此可见,要先hook住java世界可以从这里入手.

启动之后就会加载运行时换件,也就是运行时必须的oat,里面包括Integer等基本类型和Object等以及Android系统的定义的一些类.

加载这些类的过程:

首先判断当前线程的classLoader,由于刚刚启动,所以classloader自然没有设置,所以使用BootClassLoader加载,其实这个加载器并不存在,就是

使用classlinker类进行加载,大家都应该清楚类加载的过程是 findclass->defineclass->loaderclass

首先findclass 会根据方法的棕量以及classloader(这两个信息是定位一个类的唯一标示),去javaenv中维护的一个类加载信息表中,查找该类是否被加载,

如果已经被加载则直接返回,如果没有加载,就去dex_cache中查找(dex_cache还有个机制,如果缓存的类超过一个数量就会刷新到env的类加载信息表中 ),

如果找到就直接返回,如果没有找到就会去classpath中去查找,classpath其实就是指oatdata中的dex原始信息,在classpath如果也找不到相应的类,则会抛出异常.

找到之后就可以进行defineclass,其实defineclass的主要作用就是调用loadclass,loadclass 会根据dex文件中的索引信息找到对应的oatexec中的类机器码,之后填充kclass(kclass oop模型),

kclass包括字段信息,方法信息等.kclass完成之后类就被加载完成了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值