smali语法


本文由 Luzhuo 编写,转发请保留该信息.
原文: https://blog.csdn.net/Rozol/article/details/88368358


smali是什么, 官方的简介

smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android’s Java VM implementation. The syntax is loosely based on Jasmin’s/dedexer’s syntax, and supports the full functionality of the dex format (annotations, debug info, line info, etc.)
smali / baksmali是Android的Java VM实现dalvik使用的dex格式的汇编程序/反汇编程序。语法松散地基于Jasmin的/ dedexer的语法,并支持dex格式的全部功能(注释,调试信息,行信息等)

Java代码

public int show(String str){return 1;
}

smali代码

# virtual methods
.method public show(Ljava/lang/String;)I.locals 1.param p1, "str"    # Ljava/lang/String;.line 22const/4 v0, 0x1return v0
.end method

数据类型 / 对象 / 数组 的写法, 对于经常JNI开发的童鞋肯定非常熟悉, 没错, 跟javap生成签名类型是一样的.

数据类型

smali类型 java类型 Description
V void (用于返回类型) -
Z boolean 不同
B byte -
S short -
C char -
I int -
J long (64 bits) 不同
F float -
D double (64 bits) -

运算

smali

mul-int v0, p1, p2

add-int / add-long / add-float / add-double / add-int/lit16 / add-int/lit8

smali运算符 Description int long float double
add-int v0, p1, p2 v0 = p1 + p2
sub-int v0, p1, p2 v0 = p1 - p2
mul-int v0, p1, p2 v0 = p1 * p2
div-int v0, p1, p2 v0 = p1 / p2
rem-int v0, p1, p2 v0 = p1 % p2
and-int v0, p1, p2 v0 = p1 & p2 × ×
or-int v0, p1, p2 v0 = p1 │ p2 × ×
xor-int v0, p1, p2 v0 = p1 ^ p2 × ×
shl-int v0, p1, p2 v0 = p1 << p2 × ×
shr-int v0, p1, p2 v0 = p1 >> p2 × ×
ushr-int v0, p1, p2 v0 = p1 >>> p2 × ×
add-int/2addr v0, v1 v0 = v0 + v1
sub-int/2addr v0, v1 v0 = v0 - v1
mul-int/2addr v0, v1 v0 = v0 * v1
div-int/2addr v0, v1 v0 = v0 / v1
rem-int/2addr v0, v1 v0 = v0 % v1
and-int/2addr v0, v1 v0 = v0 & v1 × ×
or-int/2addr v0, v1 v0 = v0 │ v1 × ×
xor-int/2addr v0, v1 v0 = v0 ^ v1 × ×
shl-int/2addr v0, v1 v0 = v0 << v1 × ×
shr-int/2addr v0, v1 v0 = v0 >> v1 × ×
ushr-int/2addr v0, v1 v0 = v0 >>> v1 × ×
add-int/lit16 v0, v1, lit16 v0 = v1 + lit16 × × ×
sub-int/lit16 v0, v1, lit16 v0 = v1 - lit16 × × ×
mul-int/lit16 v0, v1, lit16 v0 = v1 * lit16 × × ×
div-int/lit16 v0, v1, lit16 v0 = v1 / lit16 × × ×
rem-int/lit16 v0, v1, lit16 v0 = v1 % lit16 × × ×
and-int/lit16 v0, v1, lit16 v0 = v1 & lit16 × × ×
or-int/lit16 v0, v1, lit16 v0 = v1 │ lit16 × × ×
xor-int/lit16 v0, v1, lit16 v0 = v1 ^ lit16 × × ×
add-int/lit8 v0, v1, lit8 v0 = v1 + lit8 × × ×
sub-int/lit8 v0, v1, lit8 v0 = v1 - lit8 × × ×
mul-int/lit8 v0, v1, lit8 v0 = v1 * lit8 × × ×
div-int/lit8 v0, v1, lit8 v0 = v1 / lit8 × × ×
rem-int/lit8 v0, v1, lit8 v0 = v1 % lit8 × × ×
and-int/lit8 v0, v1, lit8 v0 = v1 & lit8 × × ×
or-int/lit8 v0, v1, lit8 v0 = v1 │ lit8 × × ×
xor-int/lit8 v0, v1, lit8 v0 = v1 ^ lit8 × × ×
shl-int/lit8 v0, v1, lit8 v0 = v1 << lit8 × × ×
shr-int/lit8 v0, v1, lit8 v0 = v1 >> lit8 × × ×
ushr-int/lit8 v0, v1, lit8 v0 = v1 >>> lit8 × × ×

类名

smali类名 java类名
Ljava/lang/String; java.lang.String
Ljava/lang/Object; java.lang.Object
L全/类/名; 全.类.名

smali类名写法要注意, 最前面L开头, 最后;结尾

数组

smali数组 Java数组
[I int[]
[[I int[][]
[Ljava/lang/String; String[]

smali数组在类型左侧加[号, 几维就加几个, 最多255维.

类的定义

Java代码

public class BaseData {public int add(int x, int y){return x * y;}
}

Smali代码

.class public Lme/luzhuo/smalidemo/BaseData; // 本类
.super Ljava/lang/Object; // 父类
.source "BaseData.java" // 文件名# direct methods
// 构造方法, 方法名为<init>
.method public constructor <init>()V.locals 0.line 20invoke-direct {p0}, Ljava/lang/Object;-><init>()Vreturn-void
.end method# virtual methods
// 普通方法 / add:方法名 / II:返回类型 / I:返回类型
.method public add(II)I.locals 1.param p1, "x"    # I  // 参数.param p2, "y"    # I.line 26 // 该函数在原.source中的位置(含注释)mul-int v0, p1, p2return v0
.end method

类的定义: 本类 / 父类 / 文件名

.class public Lme/luzhuo/smalidemo/BaseData; // 本类
.super Ljava/lang/Object; // 父类
.source "BaseData.java" // 文件名

属性的定义: 属性名 / 属性类型

# static fields
// 属性: .field 修饰符 属性名:属性类型
.field private static final TAG:Ljava/lang/String; = "PropActivity"

方法的定义: 方法名 / 参数类型 / 参数名 / 返回类型 / 返回值

// 方法: .method 修饰符 方法名(参数类型)返回类型
.method public add(II)I.locals 1.param p1, "x"    # I  // 参数名.param p2, "y"    # Ireturn v0  // 返回值
.end method
返回指令 Description
return-void 直接返回
return v0 返回v0
return-object v0 返回v0(对象)
return-wide v0 给v0(双寄存器的值)

特殊的方法:

// 构造方法
.method public constructor <init>()V
.end method// 静态方法
.method public static final constructor <clinit>()V
.end method

调用方法:

const/4 v0, 0x3
const/4 v1, 0x5// 调用方法: 类->方法
invoke-virtual {p0, v0, v1}, Lme/luzhuo/smalidemo/BaseData;->add(II)I
调用指令 Description 案例
invoke-virtual 调用一般方法 invoke-virtual {p0, v0, v1}, Lme/luzhuo/smalidemo/BaseData;->add(II)I
invoke-super 调用父类方法 invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V // super.onCreate(savedInstanceState);
invoke-direct 调用private/构造方法 invoke-direct {p0}, Ljava/lang/Object;-><init>()V
invoke-static 调用静态方法 invoke-static {}, Lme/luzhuo/smalidemo/BaseData;->aaa()V
invoke-interface 调用interface方法 invoke-interface {v0}, Lme/luzhuo/smalidemo/Inter;->mul()V

寄存器

方法内部先声明寄存器数量, 然后再写代码

.method public add(II)I.locals 1.param p1, "x"    # I.param p2, "y"    # I// 先完成上面部分的声明, 然后在这些代码.line 26mul-int v0, p1, p2return v0
.end method

寄存器的声明方式

.locals 0  // 声明不算参数, 需要加几个寄存器
.registers 0  // 声明算上参数, 一共需要几个寄存器

寄存器命名规则

v0 v1 v2 v... // .locals 寄存器的命名
p0 p1 p2 p... // .registers 寄存器的命名

.registers不用声明, .locals要声明
有参数, 用p表示第几个参数所占的寄存器, 从1开始

给寄存器赋值:

const/4 v0, 0x3
const-string v0, "\u4f60\u88ab\u6211\u53cd\u7f16\u8bd1\u5566\u002c\u0020\u54c8\u54c8\u54c8\u54c8"
常量指令 Description 案例
const(/4, /16, ,/high16) vx, num 把nun赋给vx寄存器, num为(4bit, 16bit, 32bit(int), 16bit(float)) const v0, 0x3
const-wide(/16, ,/high16) vx, num 把num赋给vx和vx+, num为(?, 64bit(long), 64bit(double)) const-wide v0, 0x123456L
const-string( , -jumbo) vx, string "Unicode"字符串赋给vx (一般, 过长) const-string v0, "\u4f60\u88ab..."
const-class vx, class 将Class赋值给vx const-class v0, LJava/lang/String;
  • boolean

    • const/4赋值, 1true, 0false
  • float/double
    • 0x16进制表示小数
    • long和double的16进制数后加L
// smali 给寄存器赋值, 并起名(带名称的常量)
const/16 v0, 0xa
.local v0, "a":I// java
int a = 0xa;// ---// smali 给寄存器赋值对象
const/4 v2, 0x0
new-array v2, v2, [Ljava/lang/String;// java
new String[]

值的判断指令

// smali
const/16 v0, 0xa
const/16 v1, 0x14if-le v0, v1, :cond_0const/16 v0, 0x1egoto :goto_0:cond_0
const/16 v1, 0x1e:goto_0// java
if (v0 <= v1) {cond_0
}else{const/16 v0, 0x1egoto_0
}
// 翻译成人话: 等式不成立则往下执行
// java中写 a > b, 到这里就相反, 变成 a <= b 了.
指令 Description
if-eq v0, v1, :cond_0 if (v0 == v1) cond_0
if-ne v0, v1, :cond_0 if (v0 != v1) cond_0
if-gt v0, v1, :cond_0 if (v0 > v1) cond_0
if-ge v0, v1, :cond_0 if (v0 >= v1) cond_0
if-lt v0, v1, :cond_0 if (v0 < v1) cond_0
if-le v0, v1, :cond_0 if (v0 <= v1) cond_0
if-eqz v0, :cond_0 if (v0 == 0) cond_0
if-nez v0, :cond_0 if (v0 != 0) cond_0
if-gtz v0, :cond_0 if (v0 > 0) cond_0
if-gez v0, :cond_0 if (v0 >= 0) cond_0
if-ltz v0, :cond_0 if (v0 < 0) cond_0
if-lez v0, :cond_0 if (v0 <= 0) cond_0

移位指令

smali

.method public show()Iconst/16 v0, 0xaconst/16 v1, 0x14const/4 v2, 0x0new-array v2, v2, [Ljava/lang/String;invoke-virtual {p0, v0, v1, v2}, Lme/luzhuo/smalidemo/BaseData;->add(II[Ljava/lang/String;)Imove-result v2return v2
.end method
移位指令 Description
move( , /from16, /16) v0, v1 将v1值移入到v0(4bit(int), 16bit->8bit, 16bit)
move-wide( , /from16, /16) v0, v1 将v1值移入到v0(4bit, 16bit->8bit, 16bit)
move-object( , /from16, /16) v0, v1 将v1对象指针移入到v0(4bit, 16bit->8bit, 16bit)
move-result( , -object, -wide) v0 将上条指令计算结果, 移入到v0(值, 对象指针, 双寄存器值)
move-exception v0 将异常移入到v0

实例字段指令

smali

.method public static final aaa()V.locals 2sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;const-string v1, "sfsdf"invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)Vreturn-void
.end method

iget / aget / sget: 数字 / 数组 / 静态

实例字段指令 Description
iget 取值(int)
iget-wide 取值(双寄存器值)
iget-object 取值(对象指针)
iget-boolean 取值(bool)
iget-byte 取值(字节)
iget-char 取值(字符)
iget-short 取值(short)
iput 赋值(int)
iput-wide 赋值(双寄存器值)
iput-object 赋值(对象指针)
iput-boolean 赋值(bool)
iput-byte 赋值(字节)
iput-char 赋值(字符)
iput-short 赋值(short)

其他

注解

smali

.method protected onCreate(Landroid/os/Bundle;)V.locals 0.param p1    # Landroid/os/Bundle;.annotation build Landroid/support/annotation/Nullable;.end annotation.end param//...return-void
.end method

java

protected void onCreate(Bundle @Nullable savedInstanceState) {
}

创建数组

smali

const/4 v2, 0x0
new-array v2, v2, [Ljava/lang/String;

Android smali语法相关推荐

  1. Android:Smali语法中文介绍

    原文地址:http://jishu521.com/post/annokie/7978799.html dalvik字节码有两种类型,原始类型和引用类型.对象和数组是引用类型,其它都是原始类型. Vvo ...

  2. Android——Smali语法

    文章目录 一.寄存器 二.数据类型 三.Smali文件关键词 Smali类的格式 1. 头文件 2. 接口实现 3. 变量定义 4. 方法定义 5. 注解 四.方法描述 五.变量描述 六.常见Dalv ...

  3. notepad++ smali语法高亮模板分享

    某论坛也有,但是太难看了, 前面介绍了一些工具可以反编译dex文件为smali文件,在Android程序逆向分析中,阅读smali代码已然是十分重要的,但各种代码编辑器都无法较好的支持smali文件的 ...

  4. Smali语法简单介绍

    Smali语言其实就是Davlik的寄存器语言: Smali语言就是android的应用程序.apk通过apktool反编译出来的都有一个smali文件夹,里面都是以.smali结尾的文件,文件的展示 ...

  5. 常用android的smali注入代码,android smali代码注入 实战一

    有同学在通服里面干活,最近一直忙着4g基站搭建的干活,测试设备(android)测量移动网络数据,没有自动保存记录的功能,只能手动记录各种测试参数,不知道测试软件供应商是怎样想的,竟然不提供的这样的功 ...

  6. smali语法中文版

           这是学习Smali重中之中,不过现在有些反编译的软件已经存在相应的插件,可以直接看到这些操作码名称的中文解释(如:Android killer),但是对其进行学习还是非常有必要的.以下是 ...

  7. SMALI语法入门教程

    安卓修改大师可以对任何没有加固过的APK安装包进行反编译,如果要实现破解或者增加功能,需要您有一定的SMALI语法基础.对安卓进行源代码级别的修改必须要在反编译生成的SMALI代码中进行修改.本教程是 ...

  8. 《0基础学安卓逆向》第2集:初始apk文件和smali语法

    1.APK文件 apk=android Application PacKage=APKapk文件是什么:是安卓app的安装文件本质:(apk文件其实就是个)zip压缩包 意味着可以用解压缩工具把apk ...

  9. Android.bp 语法和使用

    1.  Android.bp 文件是什么? Android.bp 文件首先是 Android 系统的一种编译配置文件,是用来代替原来的 Android.mk 文件的.在 Android7.0 以前,A ...

  10. Android 10 根文件系统和编译系统(十八):Android.bp语法

    配套系列教学视频链接: 安卓系列教程之ROM系统开发-百问100ask 说明 系统:AOSP Android10.0 设备:Android x86模拟器 前言 由于make在编译时表现出效率不够高.增 ...

最新文章

  1. 内存错误 处理 [CAlayer release]
  2. 《FPGA全程进阶---实战演练》第一章之如何学习FPGA
  3. matlab图片拼接变成白的,利用matlab实现对图片的拼接
  4. 电纸书kindle相关产品调研(没搞完)
  5. python具有伪代码的本质吗_Python的优点之一是具有伪代码的本质。( )_学小易找答案...
  6. Keras入门之搭建回归神经网络
  7. [原] insert into … on duplicate key update / replace into 多行数据
  8. tmpfs 文件系统介绍
  9. 深入浅出linux驱动,Linux Kernel 字符驱动的深入浅出讲解
  10. 如何更改rhevm中admin的密码
  11. arm linux下交叉编译valgrind工具进行内存泄露检测和性能分析
  12. 新手建站必看,怎么选择主机空间?
  13. c语言中变量属性,C语言学习笔记--C语言中变量的属性关键字
  14. codevs1380 没有丧尸的舞会
  15. 小米手机安装linux视频教程,屏幕失灵的小米5手机安装linuxdeploy centos7记录
  16. 通过WIFI唤醒终端设备
  17. Request 。。。。。 Response
  18. ORACLE 游标 cursor的基本用法
  19. 利用微信小程序(小游戏)API制作适配cocos creator小游戏排行榜的实例程序
  20. 阿里妈妈iconfont矢量图标的使用方法(超详细)

热门文章

  1. 灵棋排盘:一款让人感到惊喜的命理排盘工具
  2. 二战十大致命武器之“喷火”式战斗机
  3. 华硕x8aip_华硕X8AIP可以升级么?如果可以……求升级建议……
  4. java ssh详解_JAVA SSH 框架介绍
  5. 硬盘分区调整:分区助手专业版易我分区大师专业版软件下载
  6. 三星笔记本BIOS文件提取 三星笔记本BIOS降级
  7. 记一次联想Y7000P安装黑apple系统地经历
  8. ScreenToClient
  9. markdown语言练习
  10. 思科网络综合实验(服务器,三层交换机,路由器)