admin管理员组文章数量:1574959
一、Dalvik虚拟机特点–掌握Android程序运行原理
1 什么是Dalvik虚拟机?
Google于2007年正式发布Android SDK,Dalvik虚拟机进入人们视野,名字源于一个叫Dalvik的小渔村,还有一种好听的名字叫做冰岛。Dalvik作为Android平台的核心组件,有很多特点:
- 体积小
- 专有的dex可执行文件格式,体积更小,执行速度更快。
- 常量池采用32位索引,拥有一套完整的指令系统。
- 所有的Android程序都运行在Android系统进程里,每个进程对应一个Dalvik虚拟机实例。
2 Dalvik虚拟机和Java虚拟机的区别
1.Java虚拟机运行的是字节码,Dalvik虚拟机运行的是Dalvik字节码
Java程序字节码保存在class文件中,Java虚拟机通过解码运行程序,而Dalvik虚拟机运行的是相应的Dalvik字节码,所有的Dalvik字节码都是由Java字节码转换过来的,被打包到一个dex可执行文件中,通过解释dex文件来执行程序。
2.Dalvik可执行文件体积更小
SDK有一个dx工具可以将Java字节码转换为Dalvik字节码,dx工具可以将Java类文件中常量池分解,冗余的信息剔除,重新组合一个常量池,所有文件共享一个常量池。如下图:
3.Java虚拟机与Dalvik虚拟机架构不同
Java虚拟机基于栈架构,Dalvik虚拟机基于寄存器架构。
Java频繁的从栈上读写数据,需要更多的指令分派和访存次数,开销大,Dalvik虚拟机通过寄存器间直接传递,比栈方式快很多,如下代码通过测试对比:
public class Hello{
public int foo(int a,int b){
return (a+b)*(a-b);
}
public static void main(String[] argc){
Hello hello=new Hello();
System.out.println(hello.foo(5,3));
}
}
用命令
javac Hello.java
将其编译成class文件后,用命令dx(在android-sdk-windows\build-tools\23.0.2下,添加path就行)生成dex文件:
dx --dex --output=Hello.dex Hello.class
可能会提示class文件无效,因为jdk1.8编译的class文件默认会比较低,所以用重新编译
javac -source 1.6 -target 1.6 Hello.java
之后用命令反编译class文件:
javap -c -classpath . Hello
执行后的如下代码(Java class文件):
public int foo(int, int);
Code:
0: iload_1(iload+1->i表示类型 iload表示将int型数据进栈)
1: iload_2
2: iadd
3: iload_1
4: iload_2
5: isub
6: imul
7: ireturn
使用
dexdump.exe -d Hello.dex
整理后的结果(Dalvik dex文件):
Hello.foo:(II)I
0000: add-int v0, v3, v4
0002: sub-int v1, v3, v4
0004: mul-int/2addr v0, v1
0005: return v0
每条指令占一个字节,可以看出:Java占了8个字节,8条指令,而Dalvik用了4条指令就完了。
解读(java-class):
iload_1和iload_2将第一个第二个参数入栈局部变量区,iadd降低一个第二个参数相加结果送入求值栈顶,之后再次将两个参数入栈,isub将两个参数相减送入求值栈顶,imul将求值栈顶两个元素相乘结果压入求值栈顶,做后得到结果16.
解读(dex):
相比Java,Dalvik简单多了,将v3 v4(两个参数)相加值给v0,v3v4相减给v1,最后v0*v1得到结果。
所以Dalvik虚拟机比Java虚拟机代码少,速度会更快一点。
3 Dalvik如何执行程序?
Android程序第一步加载init进程,初始化设备,读取inic.rc文件启动Zygote。Zygote是Android进程孵化器,它启动后首先初始化Dalvik虚拟机,然后启动system_server 进入Zygote模式等候socket命令,当得到命令后会fork自身新建一个Dalvik虚拟机来执行程序的入口函数,这样一个程序就启动了
二、Dalvik汇编语言基础
1 DEX 文件反汇编工具
BakSmali和Dedexer,两种反编译效果都不错,但是推荐用BakSmali,因为BakSmali命名法比较容易区分局部变量(v0,v1…表示)和函数参数(p0,p1…),后者不区分,还支持打包重新生成dex文件,可广泛用于apk修改破解。
2 Dalvik寄存器
Dalvik寄存器都是32位的,64位类型用两个相邻的寄存器表示,根据语法格式:op vAAAA,vBBBB ,一个字母代表4位,最多有2的16次方,65535个寄存器。
3 两种寄存器命名规则-v命名法和p命名法
一个函数用到M个寄存器,函数参数N个,Dalvik虚拟机传参方式规定:参数使用最后面N个寄存器,局部变量从v0开始的M-N个。
v命名法:从局部变量到隐式函数对象占一个寄存器,后面的位函数参数,v0,v1,v2,v3,v4….
p命名法:局部变量用v1,v2… 表示, p0表示对象的引用,p1,p2…表示函数参数
所以p命名法比v命名法好一点易于区分局部变量和函数参数。
4 Dalvik字节码类型,方法,与字段表示方法
详见博客:http://yrldrops.xyz/2018/10/28/Smail语法/#more
相关知识详细参考《Android软件安全与逆向分析》
赏你的支持是我最大的动力!
支付宝 微信版权声明:本文标题:Android Dalvik虚拟机 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dianzi/1725918861a1048957.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论