smali

作者: lee_08b0 | 来源:发表于2018-01-19 14:29 被阅读0次

    smali 学习的一些记录。


    [图片上传失败...(image-321d9c-1516343230960)]

    数据类型

    • B-->byte
    • C-->char
    • D-->double
    • F-->float
    • I-->int
    • S-->short
    • V-->void
    • J-->long
    • Z-->boolean
      此处需要注意,J/Z两个不是对应类型的首字母。在dalvik字节码中寄存器都是32位的,long,double是64位的需要两个寄存器。

    数组和对象是引用类型

    1.数组的表示方式是在基本类型前面加上"[".

    • int : [I
    • float : [F

    2.对象类型以L作为开头来表示。格式是Lpackage/ClassName;(用分号表示对象必须是结束的)

    • String对象在smali :Ljava/lang/String;
    • Class1对象的一个boolean成员: Lcom/disney/Class1;->isRunning:Z
    • Class1对象的一个String对象成员 :Lcom/disney/Class1;->name:Ljava/lang/String;
    • 内部类: Lpackage/ClassName$innerObjectName;即在内部类前加“$”符号.

    可以总结为格式为:对象类型->成员名:成员类型,->表示所属关系。类型尾部必须包括一个分号

    3.函数

    格式:func-name(para-type1para-type2para-type3...)return-type
    返回类型放在最后,参数之间没有任何分隔符,示例。
    void fun()
    fun()V

    boolean fun(int,int,int)
    fun(III)Z

    String fun(boolean,int[],int[],String,long)
    fun(Z[I[ILjava/lang/String;J)Ljava/lang/String;

    4.语法

    #标记,构造函数的返回类型为V,名字为<init>.     
    # static fields      定义静态变量的标记
    # instance fields    定义实例变量的标记
    # direct methods     定义静态方法的标记
    # virtual methods    定义非静态方法的标记    
    .class public Lcom/disney/WMW/WMWActivity;
    .super Lcom/disney/common/BaseActivity;
    .implements Lcom/burstly/lib/ui/IBurstlyAdListener;
    上面这几行代码表示类名,父类名,源文件名,实现了接口。
    .annotation
        内部类
    .end annotation
    

    此处关于内部类处理有些模糊,annotaition理论上用来标记注解,还需调研

    5.局部变量

    • 本地寄存器:local register (非参寄存器) 用v开头,数字结尾,v0,v1,v2...
    • 参数寄存器:parameter register 以p开头,数字结尾,p0,p1,p2...
    • .registers 用来标明方法中寄存器总数,即参数寄存器和非参寄存器的总数。
    • .local 0 标明在这个函数中最少要用到的本地寄存器个数。出现在方法第一行。此处在植入代码后不要忘记修改.local 的值。如.local 4 则可用到的寄存器是v0-v3。
    • 在实例函数中,p0代表this.p1代表第一个参数,p2代表第二个参数.
    • 在static函数中,p1代表第一个参数,p2代表第二个参数。因为java的static 方法中没有this方法。

    示例:
    const/4 v0, 0x0
    iput-boolean v0, p0, Lcom/disney/Class1;->isRunning:Z
    上面第一句中把0x0 存到v0本地寄存器中。第二句用iput-boolean指令把v0中的值存放到this:isRunning这个成员变量中,即this.isRunning = false;因为在实例函数中 p0代表“this”,Lcom/disney/Class1;是类名,对应实例是p0。

    6.成员变量和指令

    #static fields    
    .field private static final PREFS_INSTALLATION_ID java/lang/String;="installationId"    
    #instance fields
    .field private _activityPackageName java/lang/String;
    

    获取和操作 静态成员变量,实例成员变量 的指令:
    读取:iget,sget,iget-boolean,sget-boolean,iget-object,sget-object
    赋值:iput,sput,iput-boolean,sput-boolean,iput-object,sput-object
    ”-object“表示操作的成员变量是对象类型,没有“-object”表示操作的成员便利对象是基本数据类型,特别的 boolean类型使用“-boolean”此处注意:iget ,iput用于获取,存放instance fields,即实例成员变量。sget,sput,用于获取存放 static fields 即静态成员变量。
    获取static fields的指令:

    sget-object v0 ,Lcom/disney/Class1;->PREFS_INSTALLATION_ID:Ljava/lang/String;
    

    上句中的sget-object把PREFS_INSTALLATION_ID 这个String 成员变量获取并放到寄存器v0中;
    获取instance fields的指令与static fields指令类似,需要指明对象所属的实例:

    iget-object v0 ,p0,Lcom/disney/Class1;->view:Lcom/disney/Class2;
    

    上述iget-object比sget-object多了一个参数p0,就是该变量所在类的实例,在这里p0就是"this"

    #put指令使用和get是统一的。
    const/4 v3,0x0
    sput-object v3, Lcom/disney/Class1;->globalIapHandler:Lcom/disney/config/GLoablPurchaseHandler;
    

    此处相当于Class1.globalIapHandler = null;
    [图片上传失败...(image-e97e69-1516343230960)]插图

    7.函数调用

    smali中函数调用分为direct,virtual两种类型。direct method就是private函数,public和protected函数都属于virtual method.在调用函数时,有invoke-direct,invoke-virtual,invoke-super,invoke-interface等几种。还有invoke-XXX/range指令,这是参数多于4个的时候调用的指令。

    • invoke-static:就是调用static函数的:
    invoke-static {}, Lcom/disney/Class1;->func()Z
    

    上述invoke-static后面有"{}",内部是调用该方法的实例和参数列表,由于这是static方法,也不需要参数,所以"{}"内为空。

    • invoke-super:调用父类方法,。
    • invoke-direct:调用private函数:
    invoke-direct {p0}, Lcom/disney/Class1;->getGlobalIapHandler() Lcom/disney/config/GlobalPurchaseHandler;
    

    上句即 this->getGlobalIapHandler(),函数GlobalPurchaseHandler getGlobalIapHandler()是定义在在Class1中的一个private函数。

    • invoke-virtual:用于调用protected/public函数,示例:
    sget-object v0, Lcom/disney/Class1;->shareHandler:Landroid/os/Handler;    
    invoke-virtual {v0, v3}, Landroid/os/Handler;->removeCallbacksAndMessage(Ljava/lang/String;)V
       
    

    上句v0是shareHandler android/os/Handler,v3是传递给removeCallbackAndMessage方法的Ljava/lang/Object参数。

    8.获取函数的调用

    在smali中调用函数和返回函数结果需要分开来完成。在调用函数返回非void后,用move-result(返回基本数据类型)/move-result-obkect(返回对象)指令获取返回结果。

    const/4 v2, 0x0    
    invoke-virtual {p0, v2} Lcom/disney/Class1;->getSharedPreferences(I) Landroid/content/SharedPreference;    
    move-result-object v1
    

    9.函数体

    [图片上传失败...(image-666f14-1516343230960)]
    .method / .end method 示例:
    .method protecetd onDestroy()V
    .locals 0
    .prologue
    .line 277
    invoke-super {p0}, Lcom/disney/common/BaseActivity;->onDestroy()V
    .line 279
    return-void
    .end method
    其中.line标明代码在原java 文件中的行数,它不是必须的 去掉没有编译问题。

    10.条件语法

    if-eq p1,v0,:cond_8
    :cond_8
    invoke-direct {p0}, Lcom/paul/test/a;->d()V
    

    上段表示如果p1 和v0相等,则执行cond_8的流程。

    相关文章

      网友评论

          本文标题:smali

          本文链接:https://www.haomeiwen.com/subject/gkiooxtx.html