SMALI

Smali is the assembly language used to represent Android's DEX bytecode. This guide organizes the most important instructions and concepts into a comprehensive and easy-to-understand format, providing clarity on the various components of Smali code.
Smali File Structure

Data types
Syntax
Meaning
V
Void
Z
Boolean
B
Byte
S
Short
C
Char
F
Float
I
Int
J
Long (64-bit)
D
Double (64-bit)
\[
Array (e.g., [B → byte[])
L
Fully qualified class name (e.g. Ljava/lang/Object)
Annotations
Purpose
Java code
Smali equivalent
Inner / member classes
(implicit, compiler adds when you declare inner classes)
smali .annotation system Ldalvik/annotation/MemberClasses; value = { Lcom/example/Outer$Inner;, Lcom/example/Outer$Nested; } .end annotation
Enclosing class
(added automatically for inner classes)
smali .annotation system Ldalvik/annotation/EnclosingClass; value = Lcom/example/Outer; .end annotation
Enclosing method
(added for anonymous/local classes inside a method)
smali .annotation system Ldalvik/annotation/EnclosingMethod; value = Lcom/example/Outer;->myMethod()V .end annotation
Generics (Signature)
java class MyClass<T> { }
smali .annotation system Ldalvik/annotation/Signature; value = { "<T:", "Ljava/lang/Object;", ">","Ljava/lang/Object;" } .end annotation
Throws (declared exceptions)
java void read() throws IOException, InterruptedException;
smali .annotation system Ldalvik/annotation/Throws; value = { Ljava/io/IOException;, Ljava/lang/InterruptedException; } .end annotation
Annotation default (in annotation interface)
java @interface MyAnnotation { String value() default "defaultText"; }
smali .annotation system Ldalvik/annotation/AnnotationDefault; value = .subannotation Lcom/example/MyAnnotation; value = "defaultText" .end subannotation .end annotation
Deprecated (runtime)
java @Deprecated class OldClass { }
smali .annotation runtime Ljava/lang/Deprecated; .end annotation
Nullable (runtime)
java @Nullable String name;
smali .annotation runtime Landroidx/annotation/Nullable; .end annotation
SerializedName (runtime)
java @SerializedName("user_name") String userName;
smali .annotation runtime Lcom/google/gson/annotations/SerializedName; value = "user_name" .end annotation
SuppressLint (build)
java @SuppressLint({"NewApi","Recycle"}) void foo() { }
smali .annotation build Landroid/annotation/SuppressLint; value = { "NewApi", "Recycle" } .end annotation
Custom annotation
java @MyCustomAnnotation("Hello") class MyClass {}
smali .annotation runtime Lcom/example/MyCustomAnnotation; value = "Hello" .end annotation
Registers
In Dalvik, the registers are 32 bits long for any type of data. For 64-bit data types, (e.g. long,double), two registers are used.
Local registers (
vx): local variables and temporary values (some registers are used for internal operations by the decompiler)Parameter registers (
px): Used for passing parameters in functions (P0typically representing thethisoperator)
.locals
number of local registers
.registers
total number of registers (if virtual method, there is also a register for the implicit parameter this)
Static
Virtual
Initialization and return
Command
Description
Example (Java/Smali)
move vx,vy
Moves the content of vy into vx.
int a = 12;
mov v0, 0xc
const/4 vx,lit4
Puts the 4-bit constant into vx
Alternatives:
const vx, value: values higher than 7const/16: 16-bit constantconst/high16:high 16-bit constant
int level = 3;
const/4 v0, 0x5
new-array vx,vy,type_id
Generates a new array of type_id type and vy element size, then stores the reference in vx.
byte[] bArr = {0, 1, 2, 3, 4};
const/4 v0, 0x5
new-array v0, v0, [B
const vx, lit32
Puts a 32-bit integer constant into vx.
int level = 10000;
const vx, 0x2710
const-string vx,string_id
Puts a reference to a string constant identified by string_id into vx.
String name = "Player";
const-string v5, "Player"
iget vx, vy, field_id
Reads an instance field into vx, where the instance is referenced by vy.
return this.highScore;
iget v0, p0, Lde/fgerbig/spacepeng/services/Profile;->highScore:I
return v0
iput vx,vy, field_id
Puts vx into an instance field, where the instance is referenced by vy.
this.lastPlayedLevel = lastPlayedLevel2;
iput p1, p0, Lde/fgerbig/spacepeng/services/Profile;->lastPlayedLevel:I
Arrays
In Smali, arrays are handled with the new-array instruction, which creates an array and stores it in a register. Elements are accessed via the aget and aput instructions.
Example:
Arithmetic and binary operators
Operation
Description
Java example
Smali example
add-int vx,vy,vz
vy + vz → vx
value = value + 1;
add-int/lit8 v5, v5, 0x1
sub-int vx,vy,vz
vy - vz → vx
value = value - 1;
sub-int/lit8 v5, v5, 0x1
mul-int vx,vy,vz
vy * vz → vx
value = value * 50;
mul-int/lit8 v6, v1, 0x32
div-int vx,vy,vz
vy / vz → vx
value = value / 2;
div-int v4, v1, 0x2
rem-int vx,vy,vz
vy % vz → vx
Math.abs(step2 % 4);
rem-int/lit8 v0, p1, 0x4
and-int vx,vy,vz
vy & vz → vx
int value = b & 127;
and-int/lit8 v1, p3, 0x1f
or-int vx,vy,vz
vy | vz → vx
int result = a | b;
xor-int v1, v2, v3
xor-int vx,vy,vz
vy ^ vz → vx
int result = a ^ b;
xor-int v1, v2, v3
Flow operations
Comparison
Syntax
Description
if-eqz vx, target
Jumps to target if vx == 0
if-nez vx, target
Jumps to target if vx != 0
if-ltz vx, target
Jumps to target if vx < 0
if-gez vx, target
Jumps to target if vx >= 0
if-gtz vx, target
Jumps to target if vx > 0
if-lez vx, target
Jumps to target if vx <= 0
if-eq vx, vy, target
Jumps to target if vx == vy
if-ne vx, vy, target
Jumps to target if vx != vy
if-lt vx, vy, target
Jumps to target if vx < vy
if-ge vx, vy, target
Jumps to target if vx >= vy
if-gt vx, vy, target
Jumps to target if vx > vy
if-le vx, vy, target
Jumps to target if vx <= vy
GOTO
Command
Description
Smali example
goto :label
Unconditionally jumps to the specified label in the code.
goto :label_1
goto/16 :label
Unconditionally jumps to a label, used when the target is far in code.
goto/16 :label_2
goto/32 :label
Unconditionally jumps to a label for even farther targets.
goto/32 :label_3
Methods
Command
Description
Java example
Java example
invoke-virtual {parameters}, methodtocall
Invokes a virtual method with parameters
this.ds.increaseScore(value)
invoke-virtual {v5, v6}, Lde/fgerbig/spacepeng/systems/DirectorSystem;->increaseScore(I)V
invoke-direct {parameters}, methodtocall
Invokes a method with parameters without virtual method resolution (private methods)
DoubleShot doubleShot = new DoubleShot();
invoke-direct {v0}, Lde/fgerbig/spacepeng/components/powerup/DoubleShot;-><init>()V
invoke-static {parameters}, methodtocall
Invokes a static method with parameters
MathUtils.random((float) MIN_DELAY, (float) MAX_DELAY);
invoke-static {v0, v1}, Lcom/example/MathUtils;->random(FF)F
invoke-interface {parameters}, methodtocall
Invokes an interface method
itrt.hasNext();
invoke-interface {v3}, Ljava/util/Iterator;->hasNext()Z
Sget-object
Retrieves the value of a static object field and puts it into a register
String name = MyClass.staticField;
sget-object v0, Lcom/example/MyClass;->staticField:Ljava/lang/String;
Method Definitions
A method in Smali starts with a .method directive and is followed by the method signature, return type, and parameters.
Example:
Other Instructions
move: Moves the value from one register to another.return-void: Returns from a method with no value.return: Returns a value from a method.
SMALI snippets
Printing Variables
Base64 encoding of byte array
Toast creation
Last updated