Android:Smali语法(下)

[这篇总结的比较乱,不过干货很多。]

一、需要知道的小知识点

所有的局部变量用v开头,方法的顶部.locals 8表示这个方法使用8个局部变量。所有的参数用p开头,局部变量和参数都是从0开始编号。对于非静态方法来说,p0就是对象本身的引用,即this指针。

对于Java文件中的每一个内部类,都会产生一个单独的smali文件,比如ActivityThread$1.smali,这些文件的命名规范是如果是匿名类,外部类+$+数字。否则的话是外部类+$+内部类的名字。

在smali里的所有操作都必须经过寄存器来进行:本地寄存器用v开头数字结尾的符号来表示,如v0、v1、v2、…,参数寄存器则使用p开头数字结尾的符号来表示,如p0、p1 …
本地寄存器没有限制,理论上是可以任意使用的,下面是例子:

const/4 v0, 0x0  
iput-boolean v0, p0, Lcom/disney/WMW/WMWActivity;->isRunning:Z 

在上面的两句中,使用了v0本地寄存器,并把值0x0存到v0中,然后第二句用iput-boolean这个指令把v0中的值存放到com.disney.WMW.WMWActivity.isRunning这个成员变量中。即相当于:this.isRunning = false;(上面说过,在非static函数中p0代表的是“this”,在这里就是com.disney.WMW.WMWActivity实例)。

.line这个标识是标记行号用的,乱改也没事,只不过报错的时候的行号会是你乱改的,容易找不到出错的实际位置。

二、常见语法

1、获取|操作指令

一般来说,获取的指令有:iget、sget、iget-boolean、sget-boolean、iget-object、sget-object等,
操作的指令有:iput、sput、iput-boolean、sput-boolean、iput-object、sput-object等。
没有“-object”后缀的表示操作的成员变量对象是基本数据类型,带“-object”表示操作的成员变量是对象类型,特别地,boolean类型则使用带“-boolean”的指令操作。
——获取static fields的指令类似是:

sget-object v0, Lcom/disney/WMW/WMWActivity;->PREFS_INSTALLATION_ID:Ljava/lang/String;
                          该变量所属的类的类型;->变量名:变量类型
这句话的意思就是:将WMWActivity类中的静态字符串变量PREFS_INSTALLATION_ID赋值给v0

解释:sget-object就是用来获取变量值并保存到紧接着的寄存器中,在这里,把上面出现的PREFS_INSTALLATION_ID这个String成员变量获取并放到v0这个寄存器中.
注意:前面需要该变量所属的类的类型,后面需要加一个冒号和该成员变量的类型,中间是“->”表示所属关系。

——获取instance fields的指令与static fields的基本一样,只是由于不是static变量,不能仅仅指出该变量所在类的类型,还需要该变量所在类的实例。看例子:

iget-object v0, p0, Lcom/disney/WMW/WMWActivity;->_view:Lcom/disney/common/WMWView;  
                    v0<<<---------------------------------p0._view
这句话的意思就是:WMWActivity类中的WMWView类型的p0实例的普通变量_view 赋值给v0

——put和get使用方式是一样的,看例子:

const/4 v3, 0x0  
sput-object v3, Lcom/disney/WMW/WMWActivity;->globalIapHandler:Lcom/disney/config/GlobalPurchaseHandler; 
                    v3----------------------------->>>WMWActivity.globalIapHandler

这段代码相当于:WMWActivity.globalIapHandler = null (v3 等于 0x0 等于 null)
解释:先创建了4个字节的常量 v3 = null,然后将null赋值给WMWActivity类的globalIapHandler静态变量。

总结:put 是将寄存器中的值保存到变量中,get是将变量值保存到寄存器中。

2、smali中的函数调用

smali中的函数也分为两种:direct methodvirtual method
direct method就是private函数,
所以在调用函数时,有invoke-direct,invoke-virtual,另外还有invoke-static、invoke-super以及invoke-interface等几种不同的指令。
1)、invoke-static:就是调用static函数的,因为是static函数,所以比起其他调用少一个参数,例如:

invoke-static {}, Lcom/disney/WMW/UnlockHelper;->unlockCrankypack()Z  

这里注意到invoke-static后面有一对大括号“{}”,其实是调用该方法的实例+参数列表,由于这个方法既不需参数也是static的,所以{}内为空。
2)、invoke-super:调用父类方法用的指令,在onCreate、onDestroy等方法内部都能看到。
3)、invoke-direct:调用private函数的,例如:

invoke-direct {p0}, Lcom/disney/WMW/WMWActivity;->getGlobalIapHandler()Lcom/disney/config/GlobalPurchaseHandler; 

这里GlobalPurchaseHandler getGlobalIapHandler()就是定义在WMWActivity中的一个private函数,如果修改smali时错用invoke-virtual或invoke-static将在回编译后程序运行时引发一个常见的VerifyError。

4)、invoke-virtual:用于调用protected或public函数,同样注意修改smali时不要错用invoke-direct或invoke-static,例子:

sget-object v0, Lcom/disney/WMW/WMWActivity;->shareHandler:Landroid/os/Handler;  
invoke-virtual {v0, v3}, Landroid/os/Handler;->removeCallbacksAndMessages(Ljava/lang/Object;)V 

解释:先将静态对象v0赋值为WMWActivity.shareHandler,然后调用v0这个实例的 public void removeCallbacksAndMessages(Object) 方法,传入参数v3.

5)、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  

解释:调用static checkFee(6个参数)方法,传入v0,v1,v2,v3,v4,v5   6个参数

——取函数返回值:
在Java代码中调用函数和返回函数结果是一条语句完成的,而在smali里则需要分开来完成。在使用上述指令后,如果调用的函数返回非void,那么还需要用到move-result(返回基本数据类型)和move-result-object(返回对象)指令:

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实例。

参考链接:http://blog.csdn.net/lpohvbe/article/details/7981386

——衷心感谢参考链接的作者们——

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

outer199

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值