安卓逆向入门——smali语法(上)

smali语法部分已经完结,感兴趣的可以访问下面这个链接阅读下一部分:安卓逆向入门——smali语法(下)_不会算法的小白的博客-CSDN博客

smali和Java基本数据类型对比

smali

java

B

byte

S

short

I

int

J

long

F

float

D

double

C

char

Z

boolean

V

void

[

数组

L+全类名路径用/分割

object

注释

使用`#`表示

类声明

.class + 权限修饰符 + 类名; # 以分号结尾

比如如下Java代码:

public class Test implements CharSequence{
    
}

使用smali代码表示为:

.class public LTest; # 声明类 (必须)
.super Ljava/lang/Object; # 声明父类 默认继承Object (必须)
.implements Ljava/lang/CharSequence; # 如果实现了接口 则添加接口代码
.source "Test.java" # 源码文件 (非必须)

关于分号:

凡是L开头全包名路径结尾都需要加分号

字段声明(成员/全局变量)

.field+权限修饰符+静态修饰符 + 变量名:变量全类名路径;

比如以下Java代码:

public class Test{
    private static String a;
}

用smali代码表示为:

.class public LTest;		# 声明类 (必须)
.super Ljava/lang/Object;	# 声明父类 默认继承Object (必须)
.source "Test.java"			# 源码文件 (非必须)

# 如果是非静态,将static去掉即可
.field private static a:Ljava/lang/String;

常量声明

.field 权限修饰符 + 静态修饰符 + final + 变量名:变量全类名路径; = 常量值

比如以下Java代码:

public class Test{
	private static final String a = "Hello World";
}

用smali代码表示为:

.class public LTest;
.super Ljava/lang/Object;

.field private static final a:Ljava/lang/String; = "Hello World"

成员方法/函数声明:

.method 权限修饰符 + 静态修饰符 + 方法名(参数类型)返回值类型

        #方法体

.end method # 方法结尾标志

无参无返回值类型:

public class Test{
	public static void getName(){
    
	}
}

用smali代码表示为:

.class public LTest;
.super Ljava/lang/Object;

.method public static getName()V
	return-void
.end method

带参并且带有返回值的方法:

比如以下Java代码:

public String getName(String p){
    return "hello";
}

用smali代码表示为:

.method public getName(Ljava/lang/String;)Ljava/lang/String;
	const-String v0, "hello"

	return-object v0
.end method

关于方法返回关键字

主要有以下四种

return-void

return-object

return

return-wide

数据类型对应关系表如下:

smali方法返回关键字

java数据类型

return

byte

return

short

return

int

return-wide

long

return

float

return-wide

double

return

char

return

boolean

return-void

void

return-object

数组

return-object

object

构造方法/构造函数声明

.method 权限修饰符 + constructor <init>(参数类型)返回值类型

#方法体

.end method

#构造方法返回值固定是void

比如以下Java代码:

public class Test{
	public Test(String a){
        
	}
}

用smali代码表示为:

.class public LTest;
.super Ljava/lang/Object; # 声明父类

.method public constructor <init>(Ljava/lang/String;)V
	invoke-direct {p0}, Ljava/lang/Object;-><init>()V	# 调用父类构造方法
	return-void
.end method

静态代码块的声明

.method 权限修饰符 static constructor <clinit>()V

#方法体

.end method

比如以下Java代码:

public class Test{
	static{
    
    }
}

用smali代码表示为:

.class public LTest;
.super Ljava/lang/Object;

.method public static constructor <clinit>()V

	return-void
.end method

方法调用

关键字

invoke-virtual # 用于非私有实例方法的调用

invoke-direct # 用于构造方法以及私有方法的调用

invoke-static # 调用静态方法

invoke-super # 调用父类的方法

invoke-interface # 调用接口方法

非私有实例方法的调用

invoke-virtual {参数}, 方法所属类名;->方法名(参数类型)返回值类型

比如以下Java代码:

public class Test{
    public Test(String a){
        getName();
    }
    public String getName(){
        return "hello";
    }
}

用smali代码表示为:

.class public LTest;
.super Ljava/lang/Object;

.method public constructor <init>(Ljava/lang/String;)V
	invoke-direct {p0}, Ljava/lang/Object;-><init>()V	# 调用父类构造方法
	invoke-virtual {p0}, LTest;->getName()Ljava/lang/String;	# 调用普通成员getName方法
	# p0指的是Java中的this,表示当前对象
	return-void
.end method

.method public getName()Ljava/lang/String;
	const-string v0, "hello"	# 定义局部字符串常量

	return-object vo	# 返回常量
.end method

私有方法以及构造方法的调用

invoke-direct {参数}, 方法所属类名;->方法名(参数类型)返回值类型

私有方法的调用

比如以下Java代码:

public class Test{
    public Test(String a){
        getName();
    }
    // 私有方法
    private String getName(){
        return "hello";
    }
}

用smali代码表示为:

.class public LTest;
.super Ljava/lang/Object;

.method public constructor <init>(Ljava/lang/String;)V
	invoke-direct {p0}, Ljava/lang/Object;-><init>()V	# 调用父类构造方法
	invoke-direct {p0}, LTest;->getName()Ljava/lang/String;	# 调用私有实例方法

	return-void
.end method

.method private getName()Ljava/lang/String;
	const-string v0, "hello"	# 定义局部字符串常量

	return-object vo	# 返回常量
.end method

构造方法的调用

比如以下Java代码:

public class Test{
    public Test(String a){
        new Test2("hello");
    }
    public class Test2{
        public Test2(String a){
        }
    }
}

用smali代码表示为:

.class public LTest;
.super Ljava/lang/Object;

# 匿名内部类的声明
.annotation system Ldalvik/annotation/MemberClass;
	value = {
    	LTest$Test2;
    }
.end annotation

# 构造方法
.method public constructor <init>(Ljava/lang/String;)V
	# 初始化父类构造方法
	invoke-direct {p0}, Ljava/lang/Object;-><init>()V
	# 创建对象
	new-instance vo, LTest$Test2;
	# 定义常量
	const-String v1, "hello"
	# 调用构造方法
	invoke-direct {v0, p0, v1}, LTest$Test2;-><init>(LTest;Ljava/lang/String;)v

    return-void
.end method

静态方法的调用并获取返回值(不区分私有共有 静态优先)

invoke-static {参数}, 方法所属类名;->方法名(参数类型)返回值类型

比如以下Java代码:

public class Test{
    public Test(String a){
        String b = getName();
        System.out.println(b);
    }

    private static String getName(){
        return "hello";
    }
}

用smali代码表示为:

.class public LTest;
.super Ljava/lang/Object;

.method public constructor <init>(Ljava/lang/String;)V
	invoke-direct {p0}, Ljava/lang/Object;-><init>()V
	invoke-static {}, LTest;->getName()Ljava/lang/String;
	move-result-object v0	# 将返回值赋给v0
	return-void
.end method

.method private static getName()Ljava/lang/String;
	const-string v0, "hello"	# 定义局部字符串常量
	return-object v0	# 返回常量
.end method

父类成员方法的调用

invoke-super {参数}, 方法所属类名;->方法名(参数类型)返回值类型

比如以下Java代码:

@Override
protected void onCreate(Bundle savedInstanceState){
	super.onCreate(savedInstanceState);
}

用smali代码表示为:

.method protected onCreate(Landroid/os/Bundle;)V
	.registers 2

	invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
	return-void
.end method

接口的调用

invoke-interface {参数}, 方法所属类名;->方法名(参数类型)返回值类型

比如以下Java代码:

public class Test{
    private InterTest a = new Test2();
    public Test(String a){
    }
    public void setAa(){
        InterTest aa = a;
        # 调用接口方法
        aa.est2();
    }
    public class Test2 implements InterTest{
        public Test2(){}

        public void est2(){}
    }
    interface InterTest{
        public void est2();
    }
}

用smali代码表示为:

.class public LTest;
.super Ljava/lang/Object;

.method public constructor <init>(Ljava/lang/String;)V
	invoke-direct {p0}, Ljava/lang/Object;-><init>()V

	return-void
.end method

# 声明setAa方法
.method public setAa()V
	.registers 2

	iget-object v0, p0, LTest;->a:LTest$InterTest;
	# 调用接口方法
	invoke-interface {v0}, LTest$InterTest;->est2()V

	return-void
.end method 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值