smali/baksmali是dalvik (Android的Java VM实现)使用的dex格式的汇编/反汇编程序。该语法松散地基于Jasmin的/dedexer的语法,并支持dex格式的全部功能(注释、调试信息、行信息等)。本文主要介绍使用baksmali.jar及smali.jar反编译classes.dex和修改后进行编译。

项目地址:https://github.com/JesusFreke/smali

1、使用baksmali.jar反编译classes.dex

下载地址:https://bitbucket.org/JesusFreke/smali/downloads/

命令语法:

java -jar baksmali-2.1.3.jar -o [输出文件夹] dex文件

反编译:

java -jar baksmali.jar -o classout/ classes.dex 

注意:classout目录下的smali文件,可以进行修改,修改后在通过下面方法进行编译。

2、使用smali.jar编译成classes.dex

下载地址:https://bitbucket.org/JesusFreke/smali/downloads/

命令语法:

java -jar smali-2.1.3.jar -o 目标dex文件 [smali文件夹] 

编译:

java -jar smali.jar classout/ -o classes.dex 

3、smali文件简介

smali语言是Davlik的寄存器语言,语法上和汇编语言差不多,Dalvik VM与JVM的最大的区别之一就是Dalvik VM是基于寄存器的。基于寄存器也就是在smali里的所有操作都必须经过寄存器来进行。smali 可以看成是虚拟机的汇编语言,在逆向时可以看懂smali可以提升不少效率。

1)基本数据类型

smali类型

java类型

V

void

Z

boolean

B

byte

S

short

C

char

I

int

J

long (64位 需要2个寄存器存储)

F

float

D

double (64位 需要2个寄存器存储)

2)对象

smali对象

java对象

Lpackage/name/ObjectName;

package.name.ObjectName

Ljava/lang/String;

java.lang.String

3)数组

smali数组

java数组

[I

int[] 一维数组

[[I

int[][] 二维数组

[Ljava/lang/String

String[] 对象数组

4)类字段/变量

Lpackage/name/ObjectName;——>FieldName:Ljava/lang/String;

smali字段

java字段

public f1:Z

public boolean f1;

public f2:I

public int f2;

public f3:L

java/lang/String; public String f3;

5)类方法/函数

smali方法

java方法

myMethod([I)Ljava/lang/String;

String myMethod(int[])

6)条件判断语句(if)

if条件

说明

if-gt

大于

f-ge

大于等于

if-lt

小于

f-le

小于等于

if-eq vA, vB, :cond_**

如果vA等于vB则跳转到:cond_**

if-lt vA, vB, :cond_**

如果vA小于vB则跳转到:cond_**

if-eqz vA, :cond_**

如果vA等于0则跳转到:cond_**

if-ltz vA, :cond_**

如果vA小于0则跳转到:cond_**