smali是android反编译之后生成文件,是能够非常好的体现出程序运行过程的代码。
比如
.class public LHelloWorld; //表示该类叫HelloWorld,访问权限为public
.super Ljava/lang/object; //super表示指向父类的实例。java都是来源于object这个最大的父类
.parameter //参数,比如 param p0,"args" 表示param表示要传递的参数,参数名为args
.prologue //代码起始位置
return-void //返回是void类型,返回值为空
.end method //方法结束
Java代码
public class add{
public static void main(String[]args)
{
int a=10;
int b=11;
b=a+b;
System.out.println(b);
}
}
Smail代码
.method public static main(Ljava/lang/String;)V
.registers 3
.prologue
.line 4
.line 5
const/16 v0,0x15 //0x15表示16进制的21
.line 7
invoke-virtual{v1, v0},Ljava/io/PrintStream;->println(I)V //输出,其中println(I)中的I应该表示int型
.line 8
return-void
.end method
又比如JAVA代码
public class add{
public static void main(String[]args)
{
float a=1.1f;
System.out.println(a+a);
}
}
.registers 3
.prologue
.line 4
const v0,0x3f8ccccd //0x15表示16进制的21
.line 5
sget-object v1,Ljava/lang/String;->out:Ljava/io/PrintStream; //调用System.out
add-float/2addr v0, v0 //其中“add-float/2addr vx,vy”意思是“vy + vx”
invoke-virtual{v1, v0},Ljava/io/PrintStream;->println(F)V //输出,其中println(F)中的F应该表示float型
.line 6
return-void
.end method
const-string :定义了一个寄存器用来存放这一串字符,其中string可以换成别的数据类型。
move-result-object v2 :将上一条指令的结果存放在v2寄存器中。
if-ne v0, v1, :cond_16 :如果v0==v1就执行接下来的语句,如果不满足跳转的话,就跳转到cond_16,也就是if(v0==v1)
if-ge v1, v5, :cond_17 :如果v1>=v5就跳转到cond_17,如果没有就继续向下运行。也就是if(v1>=v5)
new-array v3, v5, [I :定义一个数组,大小为v5,类型为I也就是int型的数组。
aput v4, v3, v1 :首先是v3是数组的名字。然后v1是数组的索引,v4是存储的值。
add-int/lit8 v1, v1, 0x1 :v1加上1然后在赋值给v1,也就是实现了,v1=v1+1的操作。
array-length v1, v3 :计算出v1的长度。然后赋值给v3。
比如
.class public LHelloWorld; //表示该类叫HelloWorld,访问权限为public
.super Ljava/lang/object; //super表示指向父类的实例。java都是来源于object这个最大的父类
.method public static main(Ljava/lang/String;)V //public static void main(String[] args) 主函数,同时是方法开始
.registers 4 //程序中使用 v0、v1、v2寄存器与一个参数寄存器。而.registers 1表示只用一个寄存器.parameter //参数,比如 param p0,"args" 表示param表示要传递的参数,参数名为args
.prologue //代码起始位置
return-void //返回是void类型,返回值为空
.end method //方法结束
Java代码
public class add{
public static void main(String[]args)
{
int a=10;
int b=11;
b=a+b;
System.out.println(b);
}
}
Smail代码
.method public static main(Ljava/lang/String;)V
.registers 3
.prologue
.line 4
.line 5
const/16 v0,0x15 //0x15表示16进制的21
.line 7
sget-object v1,Ljava/lang/String;->out:Ljava/io/PrintStream;
//调用System.out;
//sget-object 就是用来获取变量值并保存到紧接着的参数的寄存器中。
//前面需要该变量所属的类的类型,后面需要加一个分号和该成员变量的类型,中间是“->”表示所属关系。
//那么这句话的意思就是,System.out的值保存在寄存器v1中。out的类型是Ljava/io/PrintStream;PrintStream是打印输出流。invoke-virtual{v1, v0},Ljava/io/PrintStream;->println(I)V //输出,其中println(I)中的I应该表示int型
.line 8
return-void
.end method
又比如JAVA代码
public class add{
public static void main(String[]args)
{
float a=1.1f;
System.out.println(a+a);
}
}
对应的smali代码
.method public static main(Ljava/lang/String;)V.registers 3
.prologue
.line 4
const v0,0x3f8ccccd //0x15表示16进制的21
.line 5
sget-object v1,Ljava/lang/String;->out:Ljava/io/PrintStream; //调用System.out
add-float/2addr v0, v0 //其中“add-float/2addr vx,vy”意思是“vy + vx”
invoke-virtual{v1, v0},Ljava/io/PrintStream;->println(F)V //输出,其中println(F)中的F应该表示float型
.line 6
return-void
.end method
这里顺便列举一些比较常见的:
const-string :定义了一个寄存器用来存放这一串字符,其中string可以换成别的数据类型。
move-result-object v2 :将上一条指令的结果存放在v2寄存器中。
if-ne v0, v1, :cond_16 :如果v0==v1就执行接下来的语句,如果不满足跳转的话,就跳转到cond_16,也就是if(v0==v1)
if-ge v1, v5, :cond_17 :如果v1>=v5就跳转到cond_17,如果没有就继续向下运行。也就是if(v1>=v5)
new-array v3, v5, [I :定义一个数组,大小为v5,类型为I也就是int型的数组。
aput v4, v3, v1 :首先是v3是数组的名字。然后v1是数组的索引,v4是存储的值。
add-int/lit8 v1, v1, 0x1 :v1加上1然后在赋值给v1,也就是实现了,v1=v1+1的操作。
array-length v1, v3 :计算出v1的长度。然后赋值给v3。