Smali Opcodes – A Beginner’s Guide

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.

 

Leave a Comment