3.Dalvik汇编

本文介绍了从JAVA字节码到Dalvik字节码的转换过程,通过dx工具将.java编译为.dex文件。接着详细展示了如何使用smali汇编语言编写程序,包括处理smali文件中的错误,生成classes.dex文件,并通过adb工具将其推送到手机进行执行。最后,通过adb登录shell并切换到root权限,用dalvik虚拟机运行dex文件,展示实际运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、比较JAVA字节码和Dalvik字节码

1.新建文件 Hello.java

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));
	}
}
2.编译为class文件

命令行:  javac -source 1.6 -target 1.6 Hello.java   (我的JDK版本为1.8,但是这里编译需指定版本为1.6)

3.编译为dex文件

命令行: dx --dex --output=Hello.dex Hello.class (dx即为SDK下build-tools中的dx.bat,我使用的是4.4w下的)

4.JAVA反汇编

命令行: javap -c -classpath . Hello.class

Compiled from "Hello.java"
public class Hello {
  public Hello();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public int foo(int, int);
    Code:
       0: iload_1
       1: iload_2
       2: iadd
       3: iload_1
       4: iload_2
       5: isub
       6: imul
       7: ireturn

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class Hello
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: astore_1
       8: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      11: aload_1
      12: iconst_5
      13: iconst_3
      14: invokevirtual #5                  // Method foo:(II)I
      17: invokevirtual #6                  // Method java/io/PrintStream.println:(I)V
      20: return
}

5.DEX反汇编

命令行: dexdump -d Hello.dex  (dexdump.exe 跟 dx.bat 在同一个目录当中,位于SDK中)

Processing 'G:\Android\HelloWorldsmali\Hello.dex'...
Opened 'G:\Android\HelloWorldsmali\Hello.dex', DEX version '035'
Class #0            -
  Class descriptor  : 'LHello;'
  Access flags      : 0x0001 (PUBLIC)
  Superclass        : 'Ljava/lang/Object;'
  Interfaces        -
  Static fields     -
  Instance fields   -
  Direct methods    -
    #0              : (in LHello;)
      name          : '<init>'
      type          : '()V'
      access        : 0x10001 (PUBLIC CONSTRUCTOR)
      code          -
      registers     : 1
      ins           : 1
      outs          : 1
      insns size    : 4 16-bit code units
00014c:                                        |[00014c] Hello.<init>:()V
00015c: 7010 0400 0000                         |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // method@0004
000162: 0e00                                   |0003: return-void
      catches       : (none)
      positions     : 
        0x0000 line=1
      locals        : 
        0x0000 - 0x0004 reg=0 this LHello; 

    #1              : (in LHello;)
      name          : 'main'
      type          : '([Ljava/lang/String;)V'
      access        : 0x0009 (PUBLIC STATIC)
      code          -
      registers     : 5
      ins           : 1
      outs          : 3
      insns size    : 17 16-bit code units
000164:                                        |[000164] Hello.main:([Ljava/lang/String;)V
000174: 2200 0100                              |0000: new-instance v0, LHello; // type@0001
000178: 7010 0000 0000                         |0002: invoke-direct {v0}, LHello;.<init>:()V // method@0000
00017e: 6201 0000                              |0005: sget-object v1, Ljava/lang/System;.out:Ljava/io/PrintStream; // field@0000
000182: 1252                                   |0007: const/4 v2, #int 5 // #5
000184: 1233                                   |0008: const/4 v3, #int 3 // #3
000186: 6e30 0100 2003                         |0009: invoke-virtual {v0, v2, v3}, LHello;.foo:(II)I // method@0001
00018c: 0a00                                   |000c: move-result v0
00018e: 6e20 0300 0100                         |000d: invoke-virtual {v1, v0}, Ljava/io/PrintStream;.println:(I)V // method@0003
000194: 0e00                                   |0010: return-void
      catches       : (none)
      positions     : 
        0x0000 line=7
        0x0005 line=8
        0x0010 line=9
      locals        : 

  Virtual methods   -
    #0              : (in LHello;)
      name          : 'foo'
      type          : '(II)I'
      access        : 0x0001 (PUBLIC)
      code          -
      registers     : 5
      ins           : 3
      outs          : 0
      insns size    : 6 16-bit code units
000198:                                        |[000198] Hello.foo:(II)I
0001a8: 9000 0304                              |0000: add-int v0, v3, v4
0001ac: 9101 0304                              |0002: sub-int v1, v3, v4
0001b0: b210                                   |0004: mul-int/2addr v0, v1
0001b2: 0f00                                   |0005: return v0
      catches       : (none)
      positions     : 
        0x0000 line=3
      locals        : 
        0x0000 - 0x0006 reg=2 this LHello; 

  source_file_idx   : 1 (Hello.java)


二、使用smali汇编编写程序

1.新建文件 HelloWorld.smali

.class public LHelloWorld;
.super Ljava/lang/Object;
.method public static main([Ljava/lang/String;)V
	.registers 2
	.parameter
	.prologue
	
	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
	
	return-void

.end method
2.编译

命令行: java -jar smali.jar HelloWorld.smali -o classes.dex  (smali-2.1.2.jar 会出现 HelloWorld.smali[5,1] Error for input '.parameter': Invalid directive 的错误,只需把.parameter' 去掉,再把 .registers 2 改为 .registers 3 即可,应该是不能使用P命名法)
3.将dex  push到手机中(我的是4.4.4,传到目录  /data/local/tmp)

命令行: adb push classes.dex /data/local/tmp

4.给dex文件加上777权限  (-rwxrwxrwx shell    shell         648 2016-10-09 21:15 classes.dex ,即让dex文件可以执行)

命令行: adb shell chmod 777 /data/local/tmp/classes.dex

5.adb登录shell,并切换到root权限 (手机需要root,只有root用户能正常使用 dalvik -cp  这个命令,否则会出错)

命令行1: adb shell

命令行2: cd /data/local/tmp

命令行3: su

6.运行dex

命令行:  dalvik -cp classes.dex HelloWorld (HelloWorld是类的名字)

执行结果:




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值