samli语法学习:
什么是smali?
android应用最终执行是爱Davlik虚拟机中执行,而Davalik虚拟机中可执行文件是dex文件,这种dex不能直接查看其逻辑,但是我们使用apktool、dex2jar等工具查看其源代码,然而想在java逻辑代码里面去修改最后在合包时不可能,只能通过解apk包的samli语言来修改并合包,smali类似于davlik的汇编语言,它有它专门的一套语法,使用baksmali工具可以将dex文件转换为samli语言
smali语法介绍:
1. 数据类型:
2. 类的创建和继承等
这些一般写在文件的开头
3. 成员变量
4. 方法:
5. 从上面方法的例子当中,我们得知了一个iput指令,但是smali还有其他很多指令的,下面就分析一下smali语法的各种指令:
a. 条件语句:
b. 获取静态成员:
note: bc两条总结的指令:
获取的指令有:iget、sget、iget-boolean、sget-boolean、iget-object、sget-object等,操作的指令有:iput、sput、iput-boolean、sput-boolean、iput-object、sput-object等。没有“-object”后缀的表示操作的成员变量对象是基本数据类型,带“-object”表示操作的成员变量是对象类型,特别地,boolean类型则使用带“-boolean”的指令操作。
d. 调用方法:
注意:以上只是部分很基础的smali语法,用这些去看smali文件基本足够了,通常我们如果对代码有大的改动时,建议不要直接修改smali代码,而是编写Java代码,将Java代码反编译为smali,在用之前的samli调取我们的smali即可,总之一点,不可深信smali,因为其太复制了
什么是smali?
android应用最终执行是爱Davlik虚拟机中执行,而Davalik虚拟机中可执行文件是dex文件,这种dex不能直接查看其逻辑,但是我们使用apktool、dex2jar等工具查看其源代码,然而想在java逻辑代码里面去修改最后在合包时不可能,只能通过解apk包的samli语言来修改并合包,smali类似于davlik的汇编语言,它有它专门的一套语法,使用baksmali工具可以将dex文件转换为samli语言
smali语法介绍:
1. 数据类型:
B---byte C---char D---double F---float I---int J---long S---short V---void Z---boolean [XXX---array Lxxx/yyy---object // [这表示一个数组[I L表示一个对象的开始Ljava/lang/String
2. 类的创建和继承等
这些一般写在文件的开头
.class public Lcom/gameworks/sdk/standard/core/SDKKitCore; //当前类名
.super Ljava/lang/Object; //父类
.source "SDKKitCore.java" //源文件名
3. 成员变量
.field private amount:I //定义
4. 方法:
.method public onResume(Ljava/lang/String;)V //使用一些类时通常是这样,L开头后面以分号;结束但是一些类的构造方法则是固定的名字, //<span style="font-family: Arial, Helvetica, sans-serif;">通常像这样:.method private</span><span style="font-family: Arial, Helvetica, sans-serif;">constructor <init>()V</span>
//举个例子(获取成员变量变赋值appid = 123):
.method public onResume()V
.locals 1 //该方法所需要使用的寄存器个数 = 局部变量个数(v0~vn) + 函数参数(p1~pn) p0默认是此类的this指针,不占用这个locals变量个数;v开头的占 //用locals的前几个寄存器,p开头占用后面几个寄存器,如local 3,v2个p1个,则local分别是:v0 v1 p1
.prologue
const/16 v0, 0x7b #给v0寄存器赋值0x7b 7b是十六进制的形式
iput v0, p0, Lcom/gameworks/sdk/standard/core/SDKKitCore;->appid:I
.line 463
:cond_0
return-void
.end method
5. 从上面方法的例子当中,我们得知了一个iput指令,但是smali还有其他很多指令的,下面就分析一下smali语法的各种指令:
a. 条件语句:
"if-eq vA, vB, :cond_**" 如果vA等于vB则跳转到:cond_**
"if-ne vA, vB, :cond_**" 如果vA不等于vB则跳转到:cond_**
"if-lt vA, vB, :cond_**" 如果vA小于vB则跳转到:cond_**
"if-ge vA, vB, :cond_**" 如果vA大于等于vB则跳转到:cond_**
"if-gt vA, vB, :cond_**" 如果vA大于vB则跳转到:cond_**
"if-le vA, vB, :cond_**" 如果vA小于等于vB则跳转到:cond_**
"if-eqz vA, :cond_**" 如果vA等于0则跳转到:cond_**
"if-nez vA, :cond_**" 如果vA不等于0则跳转到:cond_**
"if-ltz vA, :cond_**" 如果vA小于0则跳转到:cond_**
"if-gez vA, :cond_**" 如果vA大于等于0则跳转到:cond_**
"if-gtz vA, :cond_**" 如果vA大于0则跳转到:cond_**
"if-lez vA, :cond_**" 如果vA小于等于0则跳转到:cond_**
b. 获取静态成员:
sget-object
sget-object v0, Lcom/disney/WMW/WMWActivity;->PREFS_INSTALLATION_ID:Ljava/lang/String; //获取静态成员,并保存在v0寄存器中,仅需列出类名->变量名; ->表示/<span style="white-space:pre"> </span>//属于关系
c. 获取普通成员,多一个类的实例参数
iget-object v0, p0, Lcom/disney/WMW/WMWActivity;->_view:Lcom/disney/common/WMWView;
note: bc两条总结的指令:
获取的指令有:iget、sget、iget-boolean、sget-boolean、iget-object、sget-object等,操作的指令有:iput、sput、iput-boolean、sput-boolean、iput-object、sput-object等。没有“-object”后缀的表示操作的成员变量对象是基本数据类型,带“-object”表示操作的成员变量是对象类型,特别地,boolean类型则使用带“-boolean”的指令操作。
d. 调用方法:
invoke-super:调用父类方法用的指令,在onCreate、onDestroy等方法都能看到
invoke-direct:调用private函数
invoke-virtual:用于调用protected或public函数
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 // {参数表} 执行的代码
注意:以上只是部分很基础的smali语法,用这些去看smali文件基本足够了,通常我们如果对代码有大的改动时,建议不要直接修改smali代码,而是编写Java代码,将Java代码反编译为smali,在用之前的samli调取我们的smali即可,总之一点,不可深信smali,因为其太复制了