博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
smali语法小结
阅读量:5292 次
发布时间:2019-06-14

本文共 7490 字,大约阅读时间需要 24 分钟。

smali语言是Davlik的寄存器语言,语法上和汇编语言相似,Dalvik VM与JVM的最大的区别之一就是Dalvik VM是基于寄存器的。基于寄存器的意思是,在smali里的所有操作都必须经过寄存器来进行。

 

Smali-数据类型

Davlik字节码中,寄存器都是32位的,能够支持任何类型,64位类型(Long/Double)用2个寄存器表示。Dalvik字节码有两种类型:原始类型;引用类型(包括对象和数组)@。

M1.基本数据类型

V voidZ booleanB byteS shortC charI intJ long(64位)F floatD double(64位)J、Z两个不是对应类型的首字母
基本数据类型示例:.method public final pubFinalMethod()V //返回值.field private boType:Z    // boolean.field private byteType:B  // byte.field private shortType:S // short.field private charType:C  // char.field private intType:I   // int.field private longType:J  //long.field private floatType:F // float.field private doubleType:D // double

M2.对象类型

Lpackage/name/ObjectName; 相当于java中的package.name.ObjectName; L 表示这是一个对象类型

 

package/name 该对象所在的包 ,ObjectName 对象名称 , 标识对象名称的结束。

.method private priParamsOne(Ljava/lang/String;)V // 对象参数类型new-instance v1, Ljava/lang/StringBuilder;        // 对象实例化invoke-direct {v1}, Ljava/lang/StringBuilder;->
()V // 对象调用invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; // 返回值类型

M3.数组类型

[I :表示一个整形的一维数组,相当于javaint[];

对于多维数组,只要增加[ 就行了,[[I = int[][];注:每一维最多255个;

对象数组的表示形式:

 

[Ljava/lang/String 表示一个String的对象数组;

.method private varargs priParamsUncertain(Ljava/lang/String;[Ljava/lang/String;)V

Smali-方法

smali方法结构 link#direct methods.method 
<访问权限>
[修饰关键字]
<方法原型>
<.registers> [.param] [.prologue] [.line] <.local>
<代码体>
.end method#direct methods是注释,是baksmali添加的,访问权限和修饰关键字跟字段是一样的。方法原型描述了方法的名称、参数与返回值。.registers 指令指定了方法中寄存器的总数,这个数量是参数和本地变量总和。.param表明了方法的参数,每个.param指令表示一个参数,方法使用了几个参数就有几个.parameter指令。.prologue指定了代码的开始处,混淆过的代码可能去掉了该指令。.line指明了该处代码在源代码中的行号,同样,混淆后的代码可能去掉了行号。.local 使用这个指定表明方法中非参寄存器s1.方法声明private void priParamsUncertain(String str0, String... params) // java.method private varargs priParamsUncertain(Ljava/lang/String;[Ljava/lang/String;)V // smali格式:.method + 访问修饰符 + 方法名(参数表) + 返回值类型s2.调用结构(StringBuilder)v1.append(v2); // JAVAinvoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;invoke-virtual调用方法声明{v1, v2}数据寄存器对象 -> 方法名(参数类型)返回值invoke-virtual 非静态方法调用invoke-static 静态方法调用invoke-direct 构造方法调用?invoke-super 调用父类方法invoke-interface 调用接口s3.寄存器本地寄存器(local register,非参寄存器)用v开头数字结尾的符号来表示,如v0、v1、v2、…,参数寄存器(parameter register)用p开头数字结尾的符号来表示,如p0、p1、p2、…,.registers 用来标明方法中寄存器的总数,即参数寄存器和非参寄存器的总数。.local 0,标明在这个函数中最少要用到的本地寄存器的个数,出现在方法中的第一行。如 .local 4,则可以使用的寄存器是v0-v3。当一个方法被调用的时候,方法的参数被置于最后N个寄存器中。在实例函数中,p0代指“this”,p1表示函数的第一个参数,p2代表函数中的第二个参数…,在static函数中,p1表示函数的第一个参数,p2代表函数中的第二个参数…,因为Java的static方法中没有this方法。s4.其他.method // 方法的开始.end method // 方法结束move-result(返回基本数据类型)和move-result-object(返回对象)获取和操作静态成员变量和实例成员变量有不同的指令。读取的指令有:iget、sget、iget-boolean、sget-boolean、iget-object、sget-object等,赋值的指令有:iput、sput、iput-boolean、sput-boolean、iput-object、sput-object等。带“-object”表示操作的成员变量是对象类型,没有“-object”后缀的表示操作的成员变量对象是基本数据类型,特别地boolean类型则使用带“-boolean”的指令操作。
Smali与java声明方法参考.method private priParamsVoid()V // smaliprivate void priParamsVoid()     // java.method private varargs priParamsUncertain(Ljava/lang/String;[Ljava/lang/String;)Vprivate void priParamsUncertain(String str0, String... params).method private priParamsType(ILjava/lang/Long;Ljava/lang/String;Ljava/lang/Object;)Vprivate void priParamsType(int var, Long varL, String str, Object object).method private priParamsInf(Lcom/simple/dec/basic/basic/basic1/ClazzInterface;)Vprivate void priParamsInf(ClazzInterface clazzInterface)smali与java方法声明结构非常相似

Smali-对象

头文件.class 
<访问权限>
[关键修饰字]
<类名>
;.super
<父类名>
;.source
<源文件名>
.implements
<实现接口>
构造方法# direct methods.method static constructor
()V // 初始化静态变量构造方法 .locals 1 .prologue .line 10 const/4 v0, 0x0 sput-boolean v0, Lcom/simple/dec/basic/basic/basic2/StateTry;->isLoop:Z return-void.end method.method public constructor
()V // 默认构造方法 .locals 0 .prologue .line 8 invoke-direct {p0}, Ljava/lang/Object;->
()V return-void.end methodsuper-implements.super Lcom/disney/common/BaseActivity;.implements Lcom/burstly/lib/ui/IBurstlyAdListener;内部类# annotations.annotation system Ldalvik/annotation/MemberClasses; value = { Lcom/simple/dec/basic/basic/basic1/ClazzJava$InnerInterface;, Lcom/simple/dec/basic/basic/basic1/ClazzJava$InnerAbsClazz;, Lcom/simple/dec/basic/basic/basic1/ClazzJava$InnerPubStaticClazz;, Lcom/simple/dec/basic/basic/basic1/ClazzJava$InnerPubClazz;, Lcom/simple/dec/basic/basic/basic1/ClazzJava$InnerDefClazz;, Lcom/simple/dec/basic/basic/basic1/ClazzJava$InnerPriClazz; }.end annotation

Smali-语句

M1.if判断语句

 

if判断一共有12条指令:

if-eq vA, VB, cond_** 如果vA等于vB则跳转到cond_**。相当于if (vA==vB)if-ne vA, VB, cond_** 如果vA不等于vB则跳转到cond_**。相当于if (vA!=vB)if-lt vA, VB, cond_** 如果vA小于vB则跳转到cond_**。相当于if (vA
vB)if-ge vA, VB, cond_** 如果vA大于等于vB则跳转到cond_**。相当于if (vA>=vB)if-eqz vA, :cond_** 如果vA等于0则跳转到:cond_** 相当于if (VA==0)if-nez vA, :cond_** 如果vA不等于0则跳转到:cond_**相当于if (VA!=0)if-ltz vA, :cond_** 如果vA小于0则跳转到:cond_**相当于if (VA<0)if-lez vA, :cond_** 如果vA小于等于0则跳转到:cond_**相当于if (VA<=0)if-gtz vA, :cond_** 如果vA大于0则跳转到:cond_**相当于if (VA>0)if-gez vA, :cond_** 如果vA大于等于0则跳转到:cond_**相当于if (VA>=0)

M2.switch分支语句

 

Switch语句的smali文件解释结构

整形顺序结构switch(int)    :pswitch_data_0    .packed-switch 0x0        :pswitch_0        :pswitch_1.end packed-switch整形非顺序结构switch(int)    :sswitch_data_0    .sparse-switch        0x0 -> :sswitch_0        0x1 -> :sswitch_1        0xa -> :sswitch_2.end sparse-switchswitch(String)    :pswitch_data_0    .packed-switch 0x41        :pswitch_0        :pswitch_1    .end packed-switch    :pswitch_data_1    .packed-switch 0x0        :pswitch_2        :pswitch_3    .end packed-switch

M3.循环语句

 

常用的循环结构有:迭代器循环,for/foreach循环,while/do-while循环。

# virtual methods.method public statementFor()Z    .locals 4    .prologue    .line 17    const/4 v0, 0x0    .local v0, "a":I    :goto_0    const/16 v1, 0x64    if-ge v0, v1, :cond_0 // 结束循环条件    .line 18    const-string v1, "StateLoop"    new-instance v2, Ljava/lang/StringBuilder;    invoke-direct {v2}, Ljava/lang/StringBuilder;->
()V const-string v3, "" invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v2 invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; move-result-object v2 invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; move-result-object v invoke-static {v1, v2}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I .line 17 add-int/lit8 v0, v0, 0x1 goto :goto_0 // 通过goto实现循环 .line 20 :cond_0 const/4 v1, 0x0 return v1.end methodfor/foreach循环,while/do-while 几种循环结构smali语法均通过goto实现,内部嵌入if-xxx 实现跳出循环。

M4.try/catch语句

# virtual methods.method public statementTry()Z    .locals 4    .prologue    .line 14    const-wide/16 v2, 0x3e8    :try_start_0    invoke-static {v2, v3}, Ljava/lang/Thread;->sleep(J)V    :try_end_0    .catch Ljava/lang/InterruptedException; {:try_start_0 .. :try_end_0} :catch_0    .line 18    :goto_0    const/4 v1, 0x1    return v1    .line 15    :catch_0    move-exception v0    .line 16    .local v0, "e":Ljava/lang/InterruptedException;    invoke-virtual {v0}, Ljava/lang/InterruptedException;->printStackTrace()V    goto :goto_0.end method

工具:

    dex/smali

 

参考:

    

     小菜的爱

     最早介绍

     CSDN

 

     推酷

V void

Z boolean

B byte

S short

C char

I int

J long64位)

F float

D double64位)

转载于:https://www.cnblogs.com/zhen-android/p/7259434.html

你可能感兴趣的文章
区间DP 等腰三角形
查看>>
mysql 存储引擎对索引的支持
查看>>
Linq 学习(1) Group & Join--网摘
查看>>
asp.net 调用前台JS调用后台,后台掉前台JS
查看>>
【转】iOS 宏(define)与常量(const)的正确使用-- 不错
查看>>
【转】iOS开发UI篇—iPad和iPhone开发的比较
查看>>
【转】Android底层库和程序
查看>>
Comparación para 2019 Nueva Lonsdor K518S y K518ISE
查看>>
论文笔记——MobileNets(Efficient Convolutional Neural Networks for Mobile Vision Applications)
查看>>
从今天开始
查看>>
Attribute(特性)与AOP
查看>>
第三次作业
查看>>
Codeforces 962 /2错误 相间位置排列 堆模拟 X轴距离最小值 前向星点双连通分量求只存在在一个简单环中的边...
查看>>
Matrix快速幂 模板
查看>>
laravel command调用方法命令
查看>>
20162302 - 20162319 结对编程项目-四则运算(第一周)
查看>>
用python2和python3伪装浏览器爬取网页
查看>>
MySQL开启远程连接权限
查看>>
tomcat7.0.27的bio,nio.apr高级运行模式
查看>>
SAP HANA 三大特点
查看>>