smali入门学习

smali是android反编译之后生成文件,是能够非常好的体现出程序运行过程的代码。


比如


.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




这里顺便列举一些比较常见的:


扫描二维码关注公众号,回复: 1872616 查看本文章
new-instance :顾名思义,就是新建一个实例。
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。

猜你喜欢

转载自blog.csdn.net/suqi356/article/details/79157911