一、比较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是类的名字)
执行结果: