目录
1.准备工作
1.1下载好smali的jar这里使用smali-2.4.0.jar (PS: 执行命令为 java -jar assemble xxx.smali -o xxx.dex)
1.2 root的真机或者模拟器
1.3 安装好JaDex方便自己看看大概写出来的东西是个什么样子,用其它工具也行,不过这个很方便。
2.编写smali文件
首先编写一个简单的smali文件
.class public Lcom/test/smali/HelloWorld;
.super Ljava/lang/Object;
.source "HelloWorld.java"
#static field
.field public static final TAG:Ljava/lang/String;="MY_TAG"
.method public static main([Ljava/lang/String;)V
#局部变量数量
.locals 8
.param p0, "strs"
#开始
.prologue
#定义String变量
const-string v0, ":__TEST__"
const-string v1, "Hello World!"
#创建一个StringBuilder对象用来拼接字符串
new-instance v2, Ljava/lang/StringBuilder;
#调用StringBuilder的构造函数
invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V
#调用StringBuilder对象的append方法拼接字符串
invoke-virtual {v2,v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
#再次调用StringBuilder对象的append方法拼接字符串
invoke-virtual {v2,v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
#将静态域TAG的值赋值给寄存器v4
sget-object v4, Lcom/test/smali/HelloWorld;->TAG:Ljava/lang/String;
#调用StringBuilder的insert方法将TAG插入到前面
const v5,0
invoke-virtual {v2,v5,v4}, Ljava/lang/StringBuilder;->insert(ILjava/lang/String;)Ljava/lang/StringBuilder;
#调用StringBuilder的toString方法获得拼接后的字符串
invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
#将toString方法的结果赋值给寄存器v3
move-result-object v3
#调用安卓日志打印接口打印拼接后的字符串!(运行不了,换System.out.println)
#invoke-static{v4,v3}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
#获取System下的PrintStream类型的静态变量out并赋值给v6
sget-object v6, Ljava/lang/System;->out:Ljava/io/PrintStream;
#调用PrintStream的println方法打印字符串!
invoke-virtual {v6,v3}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
return-void
.end method
3.编译smail文件
编译成功后smali文件同目录会出现一个同名的dex文件。
4.检查并运行
使用jadex查看dex
推送到模拟器上并运行
5.遇到的问题
1.
错误原因:指令错误,当时代码中调用StringBuilder的append方法时花括号后面掉了一个逗号
正确写法:invoke-virtual {v2,v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
2.
错误原因:指令错误,sget-object写成了sget-static
正确情况下应该是sget-object v4, Lcom/test/smali/HelloWorld;->TAG:Ljava/lang/String;
3.
错误原因:指令错误,invoke-static {v4,v3} , 逗号遗漏了
正确情况应该是invoke-static {v4,v3}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String)I
4.
错误原因:指令错误,move-result应该是接收上一个invoke返回的非字符串单字结果,StringBuilder -> toString 返回的是一个对象应该用move-result-object来接收
正确写法应该是 move-result-object v3
5.
不知道咋办,换打印的方法吧!System.out.println