-
-
[旧帖] [原创]自己动手学习smali语法二 0.00雪花
-
发表于: 2016-4-28 21:37 1795
-
原文用markdown语法写的,无法再论坛中显示,原文地址http://blog.csdn.net/u012417380/article/details/51274168
在上篇博文中,我们学习到了.java文件、.dex文件、.smali文件三者之间关系,以及怎样用工具将三种类型文件相互转换。可是.java文件中的类、变量、表达式等各种语法格式转化成.smali文件后会变成什么样的格式呢?smali工程中给出了相应的例子,不过我们也要亲手动实践一下。
一、类的格式
将ClassTest.java文件转化成ClassTest.smali文件。
//ClassTest.java文件
public class ClassTest{ }
//ClassTest.smali文件 .class public LClassTest;
.super Ljava/lang/Object; .source "ClassTest.java" # direct methods .method public constructor <init>()V .registers 1 .prologue .line 1 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method 由此可以看出.java中的类在转化成的.smali文件后,文件中类开头的格式为
.class <访问权限>[修饰关键字] <类名>; .super <父类名> .source <源文件名> 其中 .method public constructor ()V …… .method 应该是默认构造方方法
二、类中的静态域与实例域的格式
在第一小节中ClassTest.java文件中分别添加静态域和实例域,将.java文件转化成smali文件
//ClassTest.java文件 public class ClassTest{ public int a; public static int b; } //ClassTest.smali文件 .class public LClassTest; .super Ljava/lang/Object; .source "ClassTest.java" # static fields .field public static b:I # instance fields .field public a:I # direct methods .method public constructor <init>()V .registers 1 .prologue .line 1 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method 由此可以看出静态域的格式为:
# static fields .field <访问权限> static [修饰关键字] <域名>:<域类型> 实例域的格式为:
# instance fields .field <访问权限> [修饰关键字] <域名>:<域类型>
三、类中的实例方法和静态方法
在第一小节的ClassTest.java文件中添加methodA方法和methodB方法,将其转化为ClassTest.smali文件
//ClassTest.java文件 public class ClassTest{ public void methodA(){} private String methodB(String b){ return ""; } } //ClassTest.smali文件 .class public LClassTest; .super Ljava/lang/Object; .source "ClassTest.java" # direct methods .method public constructor <init>()V .registers 1 .prologue .line 1 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method .method private methodB(Ljava/lang/String;)Ljava/lang/String; .registers 3 .prologue .line 4 const-string v0, "" return-object v0 .end method # virtual methods .method public methodA()V .registers 1 .prologue .line 2 return-void .end method
可以看到, 类中的方法被分成direct methods和 virtual methods,baksmali对这两种类加了#号注释。
其中方法的格式为
.method <访问权限> [修饰关键字] <方法原型> .registers ? //方法用到的寄存器的个数 .prologue //代码开处 .line 2 //代码行号 …… return-void .end method 注:virtual method : 非 private、static、final、方法,非构造方法(constructor),这意味着virtual method 能够被子类复写(override)。 direct method : 一个私有的实例方法,或者一个构造方法,这意味着virtual method 本质上是一个不可复写(override)实例方法。
四、接口的格式
将MyInterface.java文件转换成MyInterface.smali文件
//MyInterface.java文件 public interface MyInterface{ String MyInterfaceMethod(String str); } //MyInterface.smali文件 .class public interface abstract LMyInterface; .super Ljava/lang/Object; .source "MyInterface.java" # virtual methods .method public abstract MyInterfaceMethod(Ljava/lang/String;)Ljava/lang/String; .end method 可以看到,接口的smali文件格式为
.class <访问权限> interface abstract <接口名>; .super Ljava/lang/Object;//如果接口扩展接口的话,这个可能是父接口 .source "MyInterface.java" # virtual methods .method public abstract <方法原型> .end method 可以看到,接口的修饰符abstract,接口中的方法是public abstract,由于接口的方法能够被复写(override),所以接口中的方法被分到了virtual methods中
五、接口的实现
第一小节ClassTest.java中的ClassTest类实现了第四小节中MyInterface.java中MyInterface接口,将ClassTest.java文件转换成ClassTest.smali文件
//ClassTest.java文件 public class ClassTest implements MyInterface{ public String MyInterfaceMethod(String str){ return ""; } } //ClassTest.smali文件 .class public LClassTest; .super Ljava/lang/Object; .source "ClassTest.java" # interfaces .implements LMyInterface; # direct methods .method public constructor <init>()V .registers 1 .prologue .line 1 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method # virtual methods .method public MyInterfaceMethod(Ljava/lang/String;)Ljava/lang/String; .registers 3 .prologue .line 3 const-string v0, "" return-object v0 .end method 可以看到,当类实现接口时,该smali文件中会中多出如下格式的文件
# interfaces .implements LMyInterface;
六、枚举型的格式
七、注解的格式
本文参考自:
[1]smali学习笔记.pdf
[2]Android软件安全与逆向分析 丰生强
在上篇博文中,我们学习到了.java文件、.dex文件、.smali文件三者之间关系,以及怎样用工具将三种类型文件相互转换。可是.java文件中的类、变量、表达式等各种语法格式转化成.smali文件后会变成什么样的格式呢?smali工程中给出了相应的例子,不过我们也要亲手动实践一下。
一、类的格式
将ClassTest.java文件转化成ClassTest.smali文件。
//ClassTest.java文件
public class ClassTest{ }
//ClassTest.smali文件 .class public LClassTest;
.super Ljava/lang/Object; .source "ClassTest.java" # direct methods .method public constructor <init>()V .registers 1 .prologue .line 1 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method 由此可以看出.java中的类在转化成的.smali文件后,文件中类开头的格式为
.class <访问权限>[修饰关键字] <类名>; .super <父类名> .source <源文件名> 其中 .method public constructor ()V …… .method 应该是默认构造方方法
二、类中的静态域与实例域的格式
在第一小节中ClassTest.java文件中分别添加静态域和实例域,将.java文件转化成smali文件
//ClassTest.java文件 public class ClassTest{ public int a; public static int b; } //ClassTest.smali文件 .class public LClassTest; .super Ljava/lang/Object; .source "ClassTest.java" # static fields .field public static b:I # instance fields .field public a:I # direct methods .method public constructor <init>()V .registers 1 .prologue .line 1 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method 由此可以看出静态域的格式为:
# static fields .field <访问权限> static [修饰关键字] <域名>:<域类型> 实例域的格式为:
# instance fields .field <访问权限> [修饰关键字] <域名>:<域类型>
三、类中的实例方法和静态方法
在第一小节的ClassTest.java文件中添加methodA方法和methodB方法,将其转化为ClassTest.smali文件
//ClassTest.java文件 public class ClassTest{ public void methodA(){} private String methodB(String b){ return ""; } } //ClassTest.smali文件 .class public LClassTest; .super Ljava/lang/Object; .source "ClassTest.java" # direct methods .method public constructor <init>()V .registers 1 .prologue .line 1 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method .method private methodB(Ljava/lang/String;)Ljava/lang/String; .registers 3 .prologue .line 4 const-string v0, "" return-object v0 .end method # virtual methods .method public methodA()V .registers 1 .prologue .line 2 return-void .end method
可以看到, 类中的方法被分成direct methods和 virtual methods,baksmali对这两种类加了#号注释。
其中方法的格式为
.method <访问权限> [修饰关键字] <方法原型> .registers ? //方法用到的寄存器的个数 .prologue //代码开处 .line 2 //代码行号 …… return-void .end method 注:virtual method : 非 private、static、final、方法,非构造方法(constructor),这意味着virtual method 能够被子类复写(override)。 direct method : 一个私有的实例方法,或者一个构造方法,这意味着virtual method 本质上是一个不可复写(override)实例方法。
四、接口的格式
将MyInterface.java文件转换成MyInterface.smali文件
//MyInterface.java文件 public interface MyInterface{ String MyInterfaceMethod(String str); } //MyInterface.smali文件 .class public interface abstract LMyInterface; .super Ljava/lang/Object; .source "MyInterface.java" # virtual methods .method public abstract MyInterfaceMethod(Ljava/lang/String;)Ljava/lang/String; .end method 可以看到,接口的smali文件格式为
.class <访问权限> interface abstract <接口名>; .super Ljava/lang/Object;//如果接口扩展接口的话,这个可能是父接口 .source "MyInterface.java" # virtual methods .method public abstract <方法原型> .end method 可以看到,接口的修饰符abstract,接口中的方法是public abstract,由于接口的方法能够被复写(override),所以接口中的方法被分到了virtual methods中
五、接口的实现
第一小节ClassTest.java中的ClassTest类实现了第四小节中MyInterface.java中MyInterface接口,将ClassTest.java文件转换成ClassTest.smali文件
//ClassTest.java文件 public class ClassTest implements MyInterface{ public String MyInterfaceMethod(String str){ return ""; } } //ClassTest.smali文件 .class public LClassTest; .super Ljava/lang/Object; .source "ClassTest.java" # interfaces .implements LMyInterface; # direct methods .method public constructor <init>()V .registers 1 .prologue .line 1 invoke-direct {p0}, Ljava/lang/Object;-><init>()V return-void .end method # virtual methods .method public MyInterfaceMethod(Ljava/lang/String;)Ljava/lang/String; .registers 3 .prologue .line 3 const-string v0, "" return-object v0 .end method 可以看到,当类实现接口时,该smali文件中会中多出如下格式的文件
# interfaces .implements LMyInterface;
六、枚举型的格式
七、注解的格式
本文参考自:
[1]smali学习笔记.pdf
[2]Android软件安全与逆向分析 丰生强
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
看原图
赞赏
雪币:
留言: