zoukankan      html  css  js  c++  java
  • Android Dalvik 虚拟机

    简介

    Android 平台虽然是使用java语言来开发应用程序,但Android程序却不是运行在标准java虚拟机上的。谷歌专门为Android平台设计了一套虚拟机来运行Android程序。它就是Dalvik虚拟机。

    特点

    * 体积小,占用内存空间小。

    * 专有的DEX可执行文件格式,体积更小,执行速度更快。

    * 常量池采用32位索引值,寻址类方法名、字段名、常量更快。

    * 基于寄存器架构,并拥有一套完整的指令系统。

    * 提供了对象生命周期管理、堆栈管理、线程管理、安全和异常管理以及垃圾回收等重要功能。

    * 所有的Android程序都运行在Android系统进程里,每个进程对应着一个Dalvik虚拟机实例。

    Dalvik虚拟机与Java虚拟机的区别

    1、Java虚拟机运行的是java字节码,Dalvik虚拟机运行的是Dalvik字节码。

    2、Dalvik 可执行文件体积更小。

    3、Java虚拟机与Dalvik虚拟机架构不同。


    Dalvik 汇编语言

    1、Dalvik指令

    指令大多由三个字符组成,前两个是数字,最后一个是字母。

    第一个数字是表示指令有多少个16位的字组成。

    第二个数字是表示指令最多使用寄存器的个数。特殊标记‘r’标识使用一定范围内的寄存器。

    第三个字母为类型吗,表示指令用到的额外的数据的类型。


    例如:22x   

    第一个2表示 指令有两个16位字组成

    第二个2表示 指令使用到2个寄存器

    第三个x表示没有使用到额外的数据


    2、DEX文件反汇编工具

    目前DEX可执行文件主流的反汇编工具有BakSmali与Dedexer。

    指令如:

    java -jar baksmali.jar -o baksmaliout hello.dex
    java -jar ddx.jar -d ddxout hello.dex


    3、Dalvik 寄存器

    Dalvik虚拟机是作用于特定架构的CPU上运行的,在设计之初采用了ARM架构,ARM架构的CPU本身继承了多个寄存器,Dalvik将部分寄存器映射到了ARM寄存器上,还有一个部分则通过调用栈进行模拟。.

    Dalvik虚拟机又是如何虚拟地使用寄存器的呢?Dalvik虚拟机为每个进程维护一个调用栈,这个调用栈其中一个作用就是用来‘虚拟’寄存器。


    4、两种不同的寄存器表示方法

    v 命名法采用以小写字母 ‘v’开头的方式表示函数中用到的局部变量与参数,所有的寄存器命名从v0开始,依次递增。

    p 命名法对函数的局部变量寄存器命名没有影响,它的命名规则:函数中引入的参数命名从p0开始,依次递增。

    Dalvik字节码的类型、方法与字段

    1、类型

    Dalvik字节码只有两种类型,基本类型与引用类型。

    2、方法

    Dalvik使用方法名、类型参数与返回值来详情描述一个方法。

    方法格式如下: Lpackage/name/ObjectName;->MethodName(III)Z

    3、字段

    Dalvik虚拟机定位字段与字节码静态分析时会用到它。

    格式如下:Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;

    Dalvik指令集

    1、空操作指令的助记符为nop。它的值为00,通常nop指令被用来作对齐代码只用。

    2、数据操作指令为move。move 指令根据字节码的大小与类型不同,后面会跟上不同的后缀。

    3、返回指令指的是函数结尾时运行的最后一条指令。return-void、return vAA、return-wide vAA、return-object vAA

    4、数据定义指令用来定义程序中用到的常量、字符串、类等数据。它的基础字节码为const。如:const/4 vA,#+B

    5、锁指令多用在多线程程序中对同一对象的操作。如:

    monitor-enter vAA 锁住

    monitor-exit vAA   释放

    6、实例操作指令包括实例的类型转换、检查以及新建等。

    7、数组操作指令包括获取数组长度、新建数组、数组赋值、数组元素取值与赋值等操作。

    8、异常指令集中有一条指令用来抛出异常。如:throw vAA

    9、跳转指令用于从当前地址跳转到指定的偏移处。如:goto、switch、if

    10、比较指令用于对两个寄存器的值进行比较。如:cmpkind vAA,vBB

    11、字段操作指令用来对对象实例的字段进行读写操作。如:iinstanceop vA,vB,field@CCCC 与sstaticop vAA,field@BBBB

    12、方法调用指令负责调用类实例的方法。它的基础指令为invoke。如:invoke-kind/range {vCCCC..vNNNNN}

    13、数据转换指令用于将一种类型的数值转换成另一种类型。如:unop vA,vB

    14、数据运算指令包括算术运算指令与逻辑运算指令。如:binop vAA,vBB,vCC 、add-type、sub-type……。


    Dalvik指令练习

    写一个Dalvik版的Hello World。

    1、编写smali文件

    .class public LHelloWorld;
    .super Ljava/lang/Object;
    .method public static main([Ljava/lang/String;)V
        .registers 4
    	.parameter
        .prologue
    	#空指令
        nop
        nop
        nop
        nop
    	#数据定义指令
    	const/16 v0, 0x8
    	const/4 v1, 0x5
    	const/4 v2, 0x3
    	#数据操作指令
    	move v1, v2
    	#数组操作指令
    	new-array v0, v0, [I
    	array-length v1, v0
    	#实例操作指令
    	new-instance v1, Ljava/lang/StringBuilder;
    	#方法调用指令
    	invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V
    	#跳转指令
    	if-nez v0, :cond_0
    	goto :goto_0
    	:cond_0
    	#数据转换指令
    	int-to-float v2, v2
    	#数据运算指令
    	add-float v2, v2, v2
    	#比较指令
    	cmpl-float v0, v2, v2
    	#字段操作指令
    	sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
    	const-string v1, "Hello World" #构造字符串
    	#方法调用指令
    	invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
    	#返回指令
    	:goto_0
        return-void
    .end method


    2、编译smali文件

    java -jar smali.jar -o classes.dex HelloWorld.smali


    3、使用虚拟机测试


    小结

    了解了Android的运行环境Dalvik虚拟机,为以后的Android的逆向分析打下了一个坚实的基础。

    下载

    实例与工具下载

  • 相关阅读:
    希腊字母写法
    The ASP.NET MVC request processing line
    lambda aggregation
    UVA 10763 Foreign Exchange
    UVA 10624 Super Number
    UVA 10041 Vito's Family
    UVA 10340 All in All
    UVA 10026 Shoemaker's Problem
    HDU 3683 Gomoku
    UVA 11210 Chinese Mahjong
  • 原文地址:https://www.cnblogs.com/james1207/p/3295169.html
Copyright © 2011-2022 走看看