Smali从入门到精通(二)之方法定义

转载请声明出处 https://blog.csdn.net/YoYo_Newbie/article/details/90745902

根据上一篇内容,我们已经初步了解了Smali以及文件的声明。接下来我们将认识类的方法的定义,请看下面这个类csdn.yoyo_newbie.smalianalyzesample.Test1

package csdn.yoyo_newbie.smalianalyzesample;

import android.util.Log;

public class Test1 {

    private void logger(){
        Log.e("test", "hello smali");
    }

}

反编译后,生成csdn\yoyo_newbie\smalianalyzesample\Test1.smali

.class public Lcsdn/yoyo_newbie/smalianalyzesample/Test1;
.super Ljava/lang/Object;
.source "Test1.java"


# direct methods
.method public constructor <init>()V
    .locals 0

    .prologue
    .line 5
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

.method private logger()V
    .locals 2

    .prologue
    .line 8
    const-string/jumbo v0, "test"

    const-string/jumbo v1, "hello smali"

    invoke-static {v0, v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

    .line 9
    return-void
.end method


来,先看着这一个方法,后面将一步步分析

    private void logger(){
        Log.e("test", "hello smali");
    }

生成对于的smali代码为

.method private logger()V
        .locals 2
    
        .prologue
        .line 8
        const-string/jumbo v0, "test"
    
        const-string/jumbo v1, "hello smali"
    
        invoke-static {v0, v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
    
        .line 9
        return-void
.end method

如下, 下面这2个语法代表包裹的代码是一个方法,.method是方法开始,.end method代表结束.(如果想要加深记忆,你可以想象汇编中的方法的堆栈平衡)

.method

.end method

在这一行中

.method private logger()V

.method方法后面紧接的是方法的作用域的修饰符,代表这个方法是private的,然后private后面紧接的是方法的名称,后面紧接的是方法的参数声明,而()V则是代表无参。对于参数类型,有如下标准的转换

JavaSmali
byteB
charC
doubleD
floatF
intI
shortS
voidV
longJ
booleanZ
classL
无参V

注意!在表格中,long对应不是L,不要搞混乱了,它对应的是J,而class对于的才是L,如java.lang.String对应smali为Ljava/lang/String

如果要表示数组参数,在前面加一个’[’,

JavaSmali
byte数组[B
int数组[I

接下来要解析

.locals 2

locals代表时候多少个局部类型数据,也就是说它的意思是,这个方法是有2个局部类型数据。这时候你就觉得有点奇怪,哪有2个局部类型数据。其实是这样的。

    private void logger(){
        Log.e("test", "hello smali");
    }

这个方法,编译器编译后会变成这样

    private void logger(){
        final String v0 = "test";
        final String v1 = "hello smali";
        Log.e(v0, v1);
    }

所以,真的是2个局部类型数据

接下来,是

.prologue

prologue代表方法名以及参数定义声明完毕,接下来的内容是方法将要执行的内容部分。

然后,接下来是

.line 8

line的值代表当前代码是在java文件中第几行

以下意思是,等价于 final String v0 = “test”;

const-string/jumbo v0, “test”

等价于 final String v1 = “hello smali”;

const-string/jumbo v1, “hello smali”

其中,const-string/jumbo 声明的引用是获取字符串常量池的数据。

接下来是

invoke-static {v0, v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

invoke-static代表调用静态方法调用。后面紧接的是{传参…},然后后面是代表是这个静态方法是谁的以及方法名,参数格式和返回类型。

也就是 invoke-static+{参数}+L类;->方法名(参数类型…)返回类型

最后是,这代表这个方法返回值类型是void类型

return-void

好了,看完这里,你再去看这部分,没错,你已经猜出来了。这是类的构造方法,和其他的方法区别不大,只是用了constructor来声明和初始标识而已


.method public constructor <init>()V
    .locals 0

    .prologue
    .line 5
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

其中,invoke-direct {p0}, Ljava/lang/Object;->()V代表的是,调用父类的无参构造方法,进行初始化。

好了今天内容到此结束,其他知识点将会在下一篇继续进行

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值