android运行smali代码,Android学习心得(4) --- MAC下smali文件编写与运行

我在博客上发表一些我的Android学习心得,希望对大家能有帮助。

在前一章我们学习了如何进行Android源代码下载,这一章学习基本的Dalvik指令集编写

这一章我们就从一个基本的例子来开始Dalvik指令集的学习

1、编写smali文件

我们编写一个smali文件来学习Dalvik指令集

先学习一下HelloWorld类的框架

.class public LHelloWorld; //public class HelloWorld

.super Ljava/lang/Object; //定义父类java.lang.Object

.method public static main([Ljava/lang/String;)V

//public static void main(String[] args) 静态main()方法

.registers * //#寄存器数量待定

.parameter //高版本的baksmali需要删除,否则编译失败

.prologue //指定函数代码起始处

return-void //函数返回

.end method

这个就是一个smali文件的整体框架

为了更好的理解,我决定从一个基本的java文件反汇编为smali文件

从而更好的理解Dalvik指令与java代码对应关系

首先先在目录下面通过创建Hello.java

//测试Hello.java文件源代码

public class Hello{

int add(int a, int b) {

return a+b;

}

public static void main(String[] args) {

Hello hello = new Hello();

System.out.println(hello.add(1,1));

}

}

通过javac编译成Hello.class字节码文件(注:我的版本jdk为1.7,使用dx生成Hello.dex文件时候出现错误,强制使用1.6来进行)

在使用dx工具生成Hello.dex文件

使用baksmali.jar反汇编Hello.dex生成Hello.smali

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

下面我们查看baksmaliout中Hello.smali文件

//p命名法:v*表示局部变量寄存器,p*表示参数寄存器

.class public LHello;

.super Ljava/lang/Object;

.source "Hello.java"

# direct methods

.method public constructor ()V

.registers 1

.prologue

.line 1

#调用Object的构造方法,p0相当于"this" 指针

invoke-direct {p0}, Ljava/lang/Object;->()V

return-void

.end method

.method public static main([Ljava/lang/String;)V

#使用了四个寄存器

.registers 4

.prologue

#把1数据存入v2寄存器中

const/4 v2, 0x1

new-instance v0, LHello;

#调用实例的直接方法初始化

invoke-direct {v0}, LHello;->()V

#把java.io.PrintStream类的对象out获取并放入v1寄存器中

sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;

#调用add(1,1)方法,

invoke-virtual {v0, v2, v2}, LHello;->add(II)I

#并把方法调用返回值放入v0寄存器中

move-result v0

#调用PrintStream中println()方法把v0的值输出

invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(I)V

return-void

.end method

# virtual methods

.method add(II)I

.registers 4

.prologue

#将p1,p2参数寄存器中的值相加,保存到v0寄存器中

add-int v0, p1, p2

#函数返回v0寄存器中的值

return v0

.end method

下面我们自己进行编写smali文件来从终端接收两个参数

并相加通过PrintStream.println()函数输出结果

下面给出我写的Hello.smali源代码

.class public LHello;

.super Ljava/lang/Object;

.source "Hello.java"

# direct methods

#初始化函数

.method public constructor ()V

.registers 1

.prologue

invoke-direct {p0}, Ljava/lang/Object;->()V

return-void

.end method

#主函数

.method public static main([Ljava/lang/String;)V

.registers 4

.prologue

const/4 v0, 0x0

const/4 v1, 0x1

#接收两个传入的参数放入v0,v1

aget-object v0, p0, v0

aget-object v1, p0, v1

#强制转化成int类型

invoke-static {v0}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I

move-result v0

invoke-static {v1}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I

move-result v1

#两个参数相加,值存在vo

add-int/2addr v0, v1

#将v0的值输出

sget-object v2, Ljava/lang/System;->out:Ljava/io/PrintStream;

invoke-virtual {v2, v0}, Ljava/io/PrintStream;->println(I)V

return-void

.end method

2、编译smali文件并测试运行

打开Android模拟器,将打包好的Hello.zip文件传输到模拟器中,可用DBMS查看

将编译出来的classes.dex文件压缩成Hello1.zip文件

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

最终查看结果,输出结果为5正确!

最后附上工具的百度云连接

baksmali.jar

smali.jar

链接: http://pan.baidu.com/s/1prwRW 密码: bq6w

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值