Smali is the assembly language for the Dalvik Virtual Machine (DVM) used by Android.
It’s more like the language of the applications executing on an Android device. While developing applications, they’re coded in high-level languages like Java.
These apps are then converted into bytecode, which the Android device understands. Smali is a human-readable representation of this bytecode.
Understanding Smali Opcodes
An opcode is an “operation code” part of an instruction in machine language that tells the part of the operation to be performed. In Smali, opcodes tell the virtual machine what to do.
Common Smali Opcodes and Their Meanings
Basic Opcodes
const
Usage: Load a constant value into a register
Example: const v0, 0x1
This sets register v0
to the constant value 1
.
move
Usage: Move the value from one register to another
Example: move v1, v0
This copies the value in register v0
to register v1
.
return-void
Usage: Return from a function with no value
Example: return-void
This indicates the end of a function that does not return a value.
return
Usage: Return from a function with a value
Example: return v0
This indicates the end of a function, returning the value in v0
.
Arithmetic Opcodes
add-int
Usage: Add two integers
Example: add-int v0, v1, v2
This adds the values in v1
and v2
, and stores the result in v0
.
sub-int
Usage: Subtract two integers
Example: sub-int v0, v1, v2
This subtracts the value in v2
from the value in v1
, and stores the result in v0
.
mul-int
Usage: Multiply two integers
Example: mul-int v0, v1, v2
This multiplies the values in v1
and v2
, and stores the result in v0
.
div-int
Usage: Divide two integers
Example: div-int v0, v1, v2
This divides the value in v1
by the value in v2
, and stores the result in v0
.
Conditional Opcodes
if-eq
Usage: Compare if two values are equal
Example: if-eq v0, v1, :label
This checks if v0
equals v1
, and if true, jumps to :label
.
if-ne
Usage: Compare if two values are not equal
Example: if-ne v0, v1, :label
This checks if v0
does not equal v1
, and if true, jumps to :label
.
if-gt
Usage: Compare if one value is greater than another
Example: if-gt v0, v1, :label
This checks if v0
is greater than v1
, and if true, jumps to :label
.
if-ge
Usage: Compare if one value is greater than or equal to another
Example: if-ge v0, v1, :label
This checks if v0
is greater than or equal to v1
, and if true, jumps to :label
.
if-lt
Usage: Compare if one value is less than another
Example: if-lt v0, v1, :label
This checks if v0
is less than v1
, and if true, jumps to :label
.
if-le
Usage: Compare if one value is less than or equal to another
Example: if-le v0, v1, :label
This checks if v0
is less than or equal to v1
, and if true, jumps to :label
.
goto
Usage: Jump to another part of the code
Example: goto :label
This makes the code jump to :label
.
Object-Oriented Opcodes
new-instance
Usage: Create a new instance of a class
Example: new-instance v0, Lcom/example/MyClass;
This creates a new instance of MyClass
and stores it in v0
.
invoke-direct
Usage: Call a method directly
Example: invoke-direct {v0}, Lcom/example/MyClass;->()V
This calls the constructor of MyClass
.
invoke-virtual
Usage: Call a virtual method
Example: invoke-virtual {v0}, Lcom/example/MyClass;->myMethod()V
This calls the myMethod
method on an instance of MyClass
.
check-cast
Usage: Check the type of an object
Example: check-cast v0, Lcom/example/MyClass;
This checks if the object in v0
is of type MyClass
.
throw
Usage: Throw an exception
Example: throw v0
This throws an exception stored in v0
.
Complex Opcodes
aget
Usage: Get an element from an array
Example: aget v0, v1, v2
This gets the element at index v2
from the array in v1
and stores it in v0
.
aput
Usage: Put an element into an array
Example: aput v0, v1, v2
This puts the value in v0
into the array v1
at index v2
.
iget
Usage: Get a field value from an object
Example: iget v0, v1, Lcom/example/MyClass;->myField:I
This gets the integer field myField
from the object in v1
and stores it in v0
.
iput
Usage: Put a field value into an object
Example: iput v0, v1, Lcom/example/MyClass;->myField:I
This puts the integer value in v0
into the field myField
of the object in v1
.
sget
Usage: Get a static field value from a class
Example: sget v0, Lcom/example/MyClass;->myStaticField:I
This gets the static integer field myStaticField
from MyClass
and stores it in v0
.
sput
Usage: Put a static field value into a class
Example: sput v0, Lcom/example/MyClass;->myStaticField:I
This puts the integer value in v0
into the static field myStaticField
of MyClass
.
filled-new-array
Usage: Create a new array and fill it with values
Example: filled-new-array {v0, v1, v2}, [I
This creates a new integer array with values from v0
, v1
, and v2
.
array-length
Usage: Get the length of an array
Example: array-length v0, v1
This gets the length of the array in v1
and stores it in v0
.
instance-of
Usage: Check if an object is an instance of a class
Example: instance-of v0, v1, Lcom/example/MyClass;
This checks if the object in v1
is an instance of MyClass
and stores the result (0 or 1) in v0
.
Conclusion
In this guide, you will learn about a range of Smali opcodes, starting from basic ones to more complex types. Each opcode performs one specific function; understanding them will help you read and manipulate Android bytecode easily.
You can check out our tutorials on how to mod android applications.
Smali can be complex, but breaking it down into these simple instructions can make it easier to grasp. If you have any questions then let me know in the comments below.