• smali语法笔记


    资料

    在smali里的所有操作都必须经过寄存器来进行:

    • 本地寄存器用v开头数字结尾的符号来表示,如v0、v1、v2、...
    • 参数寄存器则使用p开头数字结尾的符号来表示,如p0、p1、p2、...
    • p0不一定是函数中的第一个参数,在非static函数中,p0代指“this”,p1表示函数的第一个参数,p2代表函数中的第二个参数…
    • 而在static函数中p0才对应第一个参数(因为Java的static方法中没有this方法)

    举例:

    const/4 v0, 0x0  
    //使用了v0本地寄存器,并把值0x0存到v0中
    iput-boolean v0, p0, Lcom/disney/WMW/WMWActivity;->isRunning:Z 
    //用iput-boolean这个指令把v0中的值存放到com.disney.WMW.WMWActivity.isRunning这个成员变量中,相当于:
    //this.isRunning = false;在非static函数中p0代表的是“this”,在这里就是com.disney.WMW.WMWActivity实例 
    

    数据类型

    • B---byte
    • C---char
    • D---double
    • F---float
    • I---int
    • J---long
    • S---short
    • V---void
    • Z---boolean
    • [XXX---array

    数组:在基本类型前加上前中括号“[”,例如int数组和float数组分别表示为:[I、[F;

    • Lxxx/yyy---object

    对象以L作为开头,格式是LpackageName/objectName;(注意必须有个分号跟在最后),例如String对象在smali中为:Ljava/lang/String;

    函数的定义

    Func-Name (Para-Type1Para-Type2Para-Type3...)Return-Type

    参数与参数之间没有任何分隔符
    举例:

    • foo ()V 是 void foo()
    • foo (III)Z 是 boolean foo(int, int, int)
    • foo (Z[I[ILjava/lang/String;J)Ljava/lang/String; 是 String foo (boolean, int[], int[], String, long)

    内部类 MemberClasses

    WMWActivity的内部类 :格式 LpackageName/objectName$subObjectName;。也就是在内部类前加“$”符号

    # annotations
       .annotation system Ldalvik/annotation/MemberClasses;
         value = {
            Lcom/disney/WMW/WMWActivity$MessageHandler;,
            Lcom/disney/WMW/WMWActivity$FinishActivityArgs;
        }
     .end annotation
    
    

    成员变量

    成员变量分静态与非静态的,格式是:.field public/private [static] [final] varName:<类型>

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

    指令

    静态变量指令以s开头,非静态变量(instance)以i开头

    • 静态变量的指令:

    获取指令:sget、sget-boolean、sget-object等
    操作指令: sput、sput-boolean、sput-object等

    • 非静态变量的指令:

    获取指令:iget、iget-boolean、iget-object等
    操作指令:iput、iput-boolean、iput-object等

    • 提示:

    没有“-object”后缀的表示操作的成员变量对象是基本数据类型
    带“-object”表示操作的成员变量是对象类型
    boolean类型则使用带“-boolean”的指令操作
    array类型使用aget和aget-object

    指令操作举例

    • 获取static fields的指令
    sget-object v0, Lcom/disney/WMW/WMWActivity;->PREFS_INSTALLATION_ID:Ljava/lang/String;
    //获取PREFS_INSTALLATION_ID这个String类型的值 并并放到v0
    
    • 获取instance fields
    	iget-object v0, p0, Lcom/disney/WMW/WMWActivity;->_view:Lcom/disney/common/WMWView;  
    	//v0 将获取到的值放到v0, p0 是该变量所在类的实例 this
    
    • put指令
    const/4 v3, 0x0  
    sput-object v3, Lcom/disney/WMW/WMWActivity;->globalIapHandler:Lcom/disney/config/GlobalPurchaseHandler; 
    //相当于:this.globalIapHandler = null;(null = 0x0)
    
    .local v0, wait:Landroid/os/Message;  
    const/4 v1, 0x2  
    iput v1, v0, Landroid/os/Message;->what:I 
    //相当于:wait.what = 0x2;(wait是Message的实例)
    

    smali中的函数调用

    两种类型的方法:

    • direct:是private函数
    • virtual:public和protected函数
      指令:
    • invoke-static 调用static函数的

    invoke-static {}, Lcom/disney/WMW/UnlockHelper;->unlockCrankypack()Z
    {}:是{调用该方法的实例,参数列表}

    invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
    //相当于 static void System.loadLibrary("fmodex")
    
    • invoke-super 调用父类方法用的指令,在onCreate、onDestroy等方法都能看到
    • invoke-direct:调用private函数的
    // getGlobalIapHandler()就是定义在WMWActivity中的一个private函数
    
    • invoke-virtual:用于调用protected或public函数
    sget-object v0, Lcom/disney/WMW/WMWActivity;->shareHandler:Landroid/os/Handler;  
    invoke-virtual {v0, v3}, Landroid/os/Handler;->removeCallbacksAndMessages(Ljava/lang/Object;)V 
    // v0是shareHandler:Landroid/os/Handler,v3是传递给removeCallbackAndMessage方法的Ljava/lang/Object参数
    // {v0 是调用的实例,v3是参数}
    
    • invoke-xxxxx/range:当方法的参数多于5个时(含5个),而是在后面加上“/range”
    invoke-static/range {v0 .. v5}, Lcn/game189/sms/SMS;->checkFee(Ljava/lang/String;Landroid/app/Activity;Lcn/game189/sms/SMSListener;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
    //这里有点迷惑
    

    函数返回值

    const/4 v2, 0x0  
    invoke-virtual {p0, v2}, Lcom/disney/WMW/WMWActivity;->getPreferences(I)Landroid/content/SharedPreferences;  
    move-result-object v1 
    v1保存的就是调用getPreferences(int)方法返回的SharedPreferences实例
    
    invoke-virtual {v2}, Ljava/lang/String;->length()I  
    move-result v2  
    v2保存的则是调用String.length()返回的整型。
    

    .locals

    .locals 0 表示这个函数中最少要用到的本地寄存器的个数 (参考文章第4点讲的挺透彻)

    条件跳转分支 引用

    • if-eqz v0, :cond_0 意思是 如果v0等于0则跳转 :cond_0;(eqz:就是equal zero)
    • if-nez v0, :cond_0 意思是 如果v0不等于0则跳转 :cond_0;(nez:就是inequal zero)
    • switch:参考
    .packed-switch 0x0    #case  区域,从0开始,依次递增  
            :pswitch_0  #case 0  
            :pswitch_1  #case 1  
            :pswitch_2  #case 2  
            :pswitch_3  #case 3  
        .end packed-switch  
    pswitch_data_0 为case 区域,在 case 区域中,第一条指令“.packed-switch”指定了比较的初始值为0 ,pswitch_0~ pswitch_3分别是比较结果为“case 0 ”到“case 3 ”时要跳转到的地址
    
  • 相关阅读:
    从dump看硬件问题
    Pycharm----【Mac】设置默认模板
    python----装饰器(几种常见方式的使用与理解)
    【Mac】打开配置文件,添加/修改环境变量
    Airtest---UI自动化测试项目
    python----PySnooper获取打印日志
    学习类网站
    unittest----assert断言的使用
    Mac---使用tree生成目录结构
    python request 留位置7
  • 原文地址:https://www.cnblogs.com/zhrea/p/6879941.html
Copyright © 2020-2023  润新知