smali语法整理
来源:互联网 发布:淘宝丝袜4成是男的买的 编辑:程序博客网 时间:2024/04/30 09:20
1.概续
最近由于工作的需要,研究了下反编译相关,自己整理了些smali语法相关的资料,在这里分享给大家,如果有错误的地方还望大家能指出来,一起讨论学习~
好了,先上代码,咱跟着代码一步一步学习。
.class public Lcom/example/tex/MainActivity;.super Landroid/app/Activity;.source "MainActivity.java"# annotations.annotation system Ldalvik/annotation/MemberClasses; value = { Lcom/example/tex/MainActivity$ProtocolState; }.end annotation# static fields.field private static final LOGIN_TYPE:J# instance fields.field private bb:I.field d:J# direct methods.method static constructor <clinit>()V .locals 2 .prologue .line 16 invoke-static {}, Ljava/lang/System;->currentTimeMillis()J move-result-wide v0 sput-wide v0, Lcom/example/tex/MainActivity;->LOGIN_TYPE:J return-void.end method.method public constructor <init>()V .locals 2 .prologue .line 12 invoke-direct {p0}, Landroid/app/Activity;-><init>()V .line 14 const/4 v0, 0x1 iput v0, p0, Lcom/example/tex/MainActivity;->bb:I .line 48 const-wide/32 v0, 0x87eccb iput-wide v0, p0, Lcom/example/tex/MainActivity;->d:J .line 12 return-void .end method
这是从activity类里截取的一段代码,如果有汇编基础的话,看上面代码应该是没压力的,那么要看懂上面代码,我们需要了解以下几点:
- smali的数据类型
- smali的方法定义和调用
- smali的成员变量定义和调用
- smali的逻辑定义
- smali文件内容分析
1.smali的数据类型
前面几种类型相信大家都清楚,后面两个说一下:数组的表示方式是:在类型前加上前中括号“[”,例如int数组和String数组分别表示为:[I、[Ljava/lang/String;对象的表示则以L作为开头,格式是LpackageName/objectName;
2.smali的方法定义和调用
格式:.method modify FunctionName(ParamType,ParamType1….) ReturnType
例子:.method public setName (Ljava/lang/String;)v 这就是设置名字的方法,返回值为空,对应java方法:public void setName(String name){}
注意地方:当参数是基本类型时,参数之间没有“;”如:
.method public setXXX (ZII)v —> public void setXXX(boolean b,int i,int j){}
调用方式:
- invoke-direct:调用private修饰的方法
- invoke-virtual:调用除private修饰外的方法
- invoke-static : 调用静态方法
- invoke-super:在重写父类方法里,调用父类方法
- invoke-interface:调用接口方法
- invoke-xxxxx/range:当方法的参数大于4个时,用这种方式调用
例子: invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
这就是调用StringBuilder的append(int)方法,其中v1为StringBuilder对象,p2为方法传进来的参数,对应Java代码:v1.append(p2); 需要注意的是当此方法不是静态方法时,第一个参数p0表示该类的对象,如果是静态方法并且有参数的话,则p0表示第一个参数。
3.smali的成员函数定义
格式:.field modify fieldName:fieldType;(如果不是基本类型的话,最后这个“;”不能丢)
例子:.field private final u:Ljava/lang/Runnable; 定义了个全局的runnable对象。
调用方式:sget、iget、sget-boolean、iget-object、iget-boolean、sget-object、sput、iput、sput-boolean、iput-object、iput-boolean、sput-object等。一般地,没有“-object”后缀的表示操作的成员变量对象是基本数据类型,带“-object”表示操作的成员变量是对象类型,而”iget”或“iput”前缀表示得到或设置成员变量值,“sget”或“sput”前缀表示得到或设置静态变量值。
例子:iget v1, p0, Lcom/example/tex/MainActivity;->bb:I 表示:获取MainActivity的成员变量bb的值并赋给v1。
4.smali的逻辑定义
直接看代码:
.line 1452const-string v0, "tag"const-string v1, "demo"if-eqz v0, :cond_0invoke-static {v1, v0}, Landroid/util/Log;->i(Ljava/lang/String;Ljava/lang/String;)Icond_0:return-void
对应的java代码:
String msg = “demo”;
if(msg != null){
Log.i(“tag”,msg);
}
相信大家都已经明白了,这里就不在啰嗦。下面是我整理的一些常用smali逻辑相关语法:
5.smali文件内容分析
咱上面把smali文件中常用的语法都过了一遍,然后接下来我们将内容在分析一遍,基本上你就可以很轻松的看懂smali文件了,废话不多说,上代码~
.class public Lcom/example/tex/MainActivity;//类的全名.super Landroid/app/Activity;//此类的父类.source "MainActivity.java"//文件名# annotations//内部类ProtocolState声明.annotation system Ldalvik/annotation/MemberClasses; value = { Lcom/example/tex/MainActivity$ProtocolState; }.end annotation# static fields.field private static final LOGIN_TYPE:J //long类型的静态变量# instance fields.field private bb:I//int类型的成员变量bb.field d:J//long类型的成员变量d.method static constructor <clinit>()V .locals 2 //表示此方法里用了2个寄存器,寄存器是用来存局部变量的值 .prologue //表示方法开始 .line 16 //行数 invoke-static {}, Ljava/lang/System;->currentTimeMillis()J //获取系统当前时间 move-result-wide v0 //将系统当前时间存入v0 sput-wide v0, Lcom/example/tex/MainActivity;->LOGIN_TYPE:J //将v0赋值给静态变量LOGIN_TYPE return-void //空返回.end method //方法结束标志# direct methods.method public constructor <init>()V //构造函数 .locals 2//表示此方法里用了2个寄存器,寄存器是用来存局部变量的值 .prologue //表示方法开始 .line 12 //行数 invoke-direct {p0}, Landroid/app/Activity;-><init>()V//调用init()方法 .line 14 const/4 v0, 0x1 //定义一个局部变量v0 值为1(十六进制) iput v0, p0, Lcom/example/tex/MainActivity;->bb:I//将v0的值赋给成员变量bb .line 48 const-wide/32 v0, 0x87eccb //将0x87eccb存入32位常量 iput-wide v0, p0, Lcom/example/tex/MainActivity;->d:J//将v0的值赋给成员变量d .line 12 return-void //空返回.end method //方法结束标志
没错,上面就是开篇引入的代码,我都加上注释了,大家跟着看,就不在一行一行解释了。在这里提几个重要的地方:
- 代码中的“#”是smali里面的注释标识。
- 大家看得仔细点就会看到该类有两个构造函数,
constructor <clinit>()
和constructor <init>()
他们有啥区别呢?第一个的作用是在jvm第一次加载class文件时调用,包括静态变量初始化语句和静态块的执行。第二个的作用是在实例创建出来的时候调用,包括调用new操作符。之后找静态变量赋值的地方,就找constructor <clinit>()
就可以了。 - 第一个构造方法里的.locals 2:表示此方法里用了2个寄存器v0,v1。寄存器是用来存局部变量的值,这个字段很重要,当你在植入代码时,如果用到了寄存器,但是没有修改此值,那就很可能报VerifyError错误。
- 第一个构造方法里的.prologue:表示方法的开始。这个也同上面重要,要是你植入的代码在这个字段前就不会达到预期的效果。
到此,smali语法的整理就结束了,这是我利用空余时间写的第一篇博客,前前后后也花了两三天时间,非常荣幸屏前的你能一直看完,相信这篇文章能帮助到你,如果你觉得这篇文章对你有用,那么赞一个或者留个言吧~
接下来我会写一篇如何修改smali文件相关的博客,希望大家前来学习和讨论!
- smali语法整理
- smali语法整理
- SMALI语法
- smali语法
- smali语法
- smali语法
- smali语法
- Smali语法
- Smali语法
- smali语法
- smali语法
- smali语法
- smali语法
- Smali语法
- smali语法
- smali语法
- smali语法
- smali文件语法参考
- Java集合框架阅读笔记
- matlab图像处理基础(二)之点运算
- HDU 5544 Ba Gua Zhen (DFS找环+线性基)
- STL中的set容器的一点总结
- 运动目标检测 帧差法
- smali语法整理
- CURL
- 【2015年第六届蓝桥杯C/C++程序设计本科B组省赛 九数组分数(代码填空)】
- 数组操作
- 文字过长,QLabel显示不全的问题,QLabel怎么自动分行显示
- R语言扩展包dplyr——数据清洗和整理
- C++之对象指针
- 根据中序遍历和前序遍历构建二叉树
- python中的集合dict&set