zoukankan      html  css  js  c++  java
  • Smali语言基础语法

    1、Smali语言基础语法-数据类型与描述符

    smali中有两类数据类型:基本类型和引用类型。引用类型是指数组和对象,其它都是基础类型。

    基本类型以及每种类型的描述符:

    Java类型 类型描述符 说明
    boolean 布尔型
    byte 字节型
    short S 短整型
    char 字符型
    int I 整型
    long 长整型
    float F 双精度型
    void V 返回类型

    引用类型分两种,对象类型与数组类型:

    对象类型表示形式为L包名/对象类型,即Lpackagename/ObjectName;(注意分号
    (1) 开始的L表明这是一个对象类型         (2) packagename  使用"/"代替”.“
    (3) ObjectName是对象的名称                 (4) 分号表明对象名的结束
    例:smali代码中String类型的表示:Ljava/lang/String;
    数组类型以 ‘[’ 数据类型加上类型描述符的形式表示:
    例:[I 表示一维整型数组,[[I表示二维数组,    [Ljava/lang/String; 表示String数组

    字段的描述

    Davilk中对字段的描述分为两种,对基本类型字段的描述和对引用类型的描述,但是两者的描述格式一样:
    对象类型描述符->字段名:类型描述符;
    例:com.baidu.Test类中存在String类型的name字段及int类型的age字段,那么其描述为:
    Lcom/baidu/Test;->name:Ljava/lang/String;         Lcom/baidu/Test;->age:I

    方法的描述

    java中方法的签名包括方法名,参数及返回值,在Davilk相应的描述规则为:
    对象类型描述符->方法名(参数类型描述符)返回值类型描述符
    以java.lang.String举例:
    java方法:public char charAt(int index){......}
    Davilk描述:Ljava/lang/String;->charAt(I)C
    
    java方法:public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin){......}
    Davilk描述:Ljava/lang/String;->getChars(II[CI)V
    
    java方法:public boolean equals(Object anObject){......}
    Davilk描述:Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    2、Smali语言基础语法-寄存器与传参以及局部变量

    在smali汇编语言中,同样也有寄存器,寄存器都是32位的,能够支持任何类型。64位类型(Long和Double型)用两个寄存器表示。
    有两种方式指定一个方法中有多少寄存器是可用的。

    .registers指令指定了方法中寄存器的总数        .locals指令表明了方法中非参寄存器的数量

    在方法中使用寄存器传递参数的默认规则如下:
    (1)当一个方法被调用的时候,方法的参数被置于最后N个寄存器中。如果一个方法有2个参数,5个寄存器(v0-v4),那么参数将置于最后2个寄存器--v3和v4中。          (2)非静态方法中的第一个参数总是调用该方法的对象。
    非静态方法LMyobject;->callMe(II)V 有2个整型参数,另外还有一个隐含的LMyobject;参数,所有总共有三个参数。假如在该方法中指定了5个寄存器(v0-v4),以.registers指定5个或者以.locals方式指定2个(即2个local寄存器+3个参数寄存器),当该方法被调用的时候,调用该方法的对象(即this指针引用)存放在v2中,第一个整型参数存放在v3中,第二个整型参数存放在v4中。
    对于静态方法除了没有隐含的this参数外其它都是一样的。
    寄存器的命名方式有两种:
    在下表中我们用两种方式表示上一个例子中有5个寄存器和3个参数的方法:
    V命名方式 P命名方式 说明
    v0 v0 局部变量
    v1 v1 局部变量
    v2 p0 参数0,this指针
    v3 p1 参数1
    v4 p2 参数2
    可以使用任何一种方式来引用参数寄存器----他们没有任何区别。  注意:Baksmali默认对参数寄存器使用P命名方式。
    使用P命名方式是为了防止以后如果在方法中增加寄存器,需要对参数寄存器重新进行编号的缺点。
    看一个成员方法的例子:
    public void callMe0(int a, int b)
    {
            System.out.println(a + b);
    }

    反编译之后的smali汇编代码    smali 代码中#后面是注释

    # virtual methods
    .method public callMe0(II)V
        .locals 2         # 定义局部变量寄存器
        .param p1, "a"    # I 声明参数
        .param p2, "b"    # I
                   
        .line 16          # 源码所在行数
        # 获取out对象
        sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
        # 将参数累加
        add-int v1, p1, p2
        # 输出信息
        invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(I)V
        
        .line 17
        return-void
    .end method
    关于Long/Double值:
    Long和double类型是64位的,需要两个寄存器。
    例:对于非静态方法LMyObject;->MyMethod(IJZ)V,参数分别是LMyObject;,int,long,bool。所有该方法至少需要5个寄存器来存储参数。
    寄存器 说明
    p0 this
    p1 I
    p2,p3 J
    p4 Z
     
  • 相关阅读:
    【BZOJ5286】[HNOI2018]转盘(线段树)
    【BZOJ2003】[HNOI2010]矩阵(搜索)
    【BZOJ2000】[HNOI2000]取石头游戏(贪心,博弈论)
    【BZOJ1998】[HNOI2010]物品调度(并查集,模拟)
    【BZOJ2001】[HNOI2010]城市建设(CDQ分治,线段树分治)
    【BZOJ1925】[SDOI2010]地精部落(动态规划)
    【BZOJ1856】[SCOI2010]字符串(组合数学)
    【BZOJ1826】[JSOI2010]缓存交换(贪心)
    【BZOJ1823】[JSOI2010]满汉全席(2-sat)
    【BZOJ1822】[JSOI2010]冷冻波(二分,网络流)
  • 原文地址:https://www.cnblogs.com/duxie/p/11761785.html
Copyright © 2011-2022 走看看