SMALI Cheat Sheet
Little Help with SMALI
Last updated
Little Help with SMALI
Last updated
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.
In Dalvik, registers are always 32 bits and can hold any type of value. For 64-bit types like long
and double
, two registers are used. There are two key types of registers:
Local registers (Vx
): Used for local variables and temporary values.
Parameter registers (Px
): Used for passing parameters in functions, with P0
typically representing the this
operator.
Local registers start from v0
and may go up as needed (e.g., v0
to v6
). Not all of these correspond directly to variables; some registers are used for internal operations by the decompiler.
The type of local registers often starts with L
, indicating a class reference. For example:
Ljava/lang/String
→ String class
The decompiled code also shows the use of extra registers, e.g., v5
, for handling function outputs (like sget-object
).
Here’s a table summarizing the syntax and descriptions for the conditional comparison commands:
Here’s a table summarizing the commands and descriptions for invoking methods in Java/Smali:
Different instructions are used depending on whether you are invoking a method statically, virtually, or on an interface.
invoke-virtual
: Calls a method on an object instance(public method).
invoke-static
: Calls a static method.
invoke-direct
: Calls a method on the current object directly (private)(typically constructors).
Example:
A method in Smali starts with a .method
directive and is followed by the method signature, return type, and parameters.
Example:
Smali allows assigning constant values to registers using the const
family of instructions.
const/4: Load a 4-bit constant into a register.
const/16: Load a 16-bit constant.
const/high16: Load a high 16-bit constant.
Example:
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:
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.
Example:
System.out.println
This is a simple and effective way to print variables such as passwords, secrets, or comparison values to logcat. By injecting a System.out.println
statement into the Smali code, you can monitor the output of specific values in the application logs.
Java Code:
Smali Equivalent:
You can print the value of a variable by loading it into a register (e.g., v0
), then using sget-object
and invoke-virtual
to print it.
After inserting this code into the Smali file, you can run the app and check the logcat output to see the printed value, which can be useful for debugging or extracting sensitive data.
Often, cryptographic functions store sensitive data like keys or initialization vectors (IVs) as byte arrays. To print these byte arrays in a readable format, you can encode them as Base64 strings and output them.
Java Code:
Smali Equivalent:
Insert the following code into the existing Smali code. Ensure that the register (v5
in this case) refers to the correct byte array.
This will print the byte array as a Base64-encoded string, making it easier to inspect and understand cryptographic data. You can insert this snippet into any Smali file where byte arrays are processed.
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
Local (Vx)
Param (Px)
V0
P0
V1
P1
V2
P2
V4
P3
V(...)
P(...)
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. Max value is 7. For higher values, remove /4
to use const vx, value
.
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
Command
Description
Example (Java/Smali)
add-int vx,vy,vz
Calculates vy + vz
and puts the result into vx
.
score = score + 1;
add-int/lit8 v5, v5, 0x1
sub-int vx,vy,vz
Calculates vy - vz
and puts the result into vx
.
score = score - 1;
sub-int/lit8 v5, v5, 0x1
mul-int vx,vy,vz
Multiplies vz
with vy
and puts the result into vx
.
bonus = bonus * 50;
mul-int/lit8 v6, v1, 0x32
div-int vx,vy,vz
Divides vy
by vz
and puts the result into vx
.
bonus = bonus / 2;
div-int v4, v1, 0x2
rem-int vx,vy,vz
Calculates vy % vz
and puts the result into vx
.
Math.abs(step2 % 4);
rem-int/lit8 v0, p1, 0x4
and-int vx,vy,vz
Calculates vy AND vz
and puts the result into vx
.
int result = b & 127;
and-int/lit8 v1, p3, 0x1f
or-int vx,vy,vz
Calculates vy OR vz
and puts the result into vx
.
`int result = b
xor-int vx,vy,vz
Calculates vy XOR vz
and puts the result into vx
.
Key = a ^ b;
xor-int v1, v2, v3
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
Syntax
Description
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
Command
Description
Example (Java/Smali)
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
Command
Description
Example (Java/Smali)
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.
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;