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., [Bbyte[])

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 (P0 typically representing the this operator)

Keyword
Description

.locals

number of local registers

.registers

total number of registers (if virtual method, there is also a register for the implicit parameter this)

Method Type
Java
Smali (.locals)
Smali (.registers)

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 7

  • const/16: 16-bit constant

  • const/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 + vzvx

value = value + 1;

add-int/lit8 v5, v5, 0x1

sub-int vx,vy,vz

vy - vzvx

value = value - 1;

sub-int/lit8 v5, v5, 0x1

mul-int vx,vy,vz

vy * vzvx

value = value * 50;

mul-int/lit8 v6, v1, 0x32

div-int vx,vy,vz

vy / vzvx

value = value / 2;

div-int v4, v1, 0x2

rem-int vx,vy,vz

vy % vzvx

Math.abs(step2 % 4);

rem-int/lit8 v0, p1, 0x4

and-int vx,vy,vz

vy & vzvx

int value = b & 127;

and-int/lit8 v1, p3, 0x1f

or-int vx,vy,vz

vy | vzvx

int result = a | b;

xor-int v1, v2, v3

xor-int vx,vy,vz

vy ^ vzvx

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

Action
Java
Smali

Printing Variables

Base64 encoding of byte array

Toast creation

Last updated