You’re almost there — sign up to start building in Notion today.
Sign up or login
Control Flows Statements In Smali

Control Flows Statements In Smali

In computer programming, control flow refers to the order in which statements in a program are executed. Control flow determines the sequence in which the instructions in a program are executed based on certain conditions, such as the values of variables or the results of comparisons.

What is branch statement

In computer programming, a branch statement is a statement that alters the normal control flow of a program by directing the execution to a different part of the program. Branch statements are often used in conjunction with conditional statements to create different execution paths based on conditions.
There are several types of branch statements in programming, including:
Unconditional branch statements: These statements always transfer control to the specified target location, without any condition check. Examples include the 
goto
 statement in C/C++ and the 
jmp
 statement in assembly language.
Conditional branch statements: These statements transfer control to the specified target location only if a certain condition is true. Examples include the 
if
 and 
else
 statements in C/C++ and the 
branch-if
 statement in assembly language.
Switch statements: These statements transfer control to one of several possible target locations, based on the value of a given expression. The 
switch
 statement in C/C++ and the 
select
 statement in Ada are examples of switch statements.

Main control flow statements in
Smali
:

In
Smali
, control flow statements are used to modify the flow of execution of the program.
goto
statement: This statement transfers control to a different instruction within the same method. It takes a label as an argument, which is the target instruction.
Conditional branch statements: There are several conditional branch statements in
Smali
that allow you to perform different actions based on the result of a condition. These include:
if-eq
/
if-ne
: These statements compare two values and branch to a specified instruction if they are equal (
if-eq
) or not equal (
if-ne
).
if-lt
/
if-gt
: These statements compare two values and branch to a specified instruction if the first value is less than (
if-lt
) or greater than (
if-gt
) the second value.
if-le
/
if-ge
: These statements compare two values and branch to a specified instruction if the first value is less than or equal to (
if-le
) or greater than or equal to (
if-ge
) the second value.
Switch statement: The switch statement is used to select one of several code blocks to execute based on the value of an expression.
Smali
supports two types of switch statements:
Packed switch: A packed switch is used when the switch cases are consecutive integers. In a packed switch, all the target locations for each case are stored in an array, and the index of the array is calculated based on the value of the expression being switched on. This makes accessing the target location for a given case very fast and efficient.
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState) int value = 3; switch (value){ case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; case 3: System.out.println("3"); break; default: System.out.println("Default"); } }
.method protected onCreate(Landroid/os/Bundle;)V .registers 5 .param p1, "savedInstanceState" # Landroid/os/Bundle; .prologue .line 11 invoke-super {p0, p1}, Landroidx/appcompat/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V .line 14 const/4 v0, 0x3 .line 15 .local v0, "value":I packed-switch v0, :pswitch_data_28 .line 26 sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; const-string v2, "Default" invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V .line 28 :goto_e return-void .line 17 :pswitch_f sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; const-string v2, "1" invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V goto :goto_e .line 20 :pswitch_17 sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; const-string v2, "2" invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V goto :goto_e .line 23 :pswitch_1f sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; const-string v2, "3" invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V goto :goto_e .line 15 nop :pswitch_data_28 .packed-switch 0x1 :pswitch_f :pswitch_17 :pswitch_1f .end packed-switch .end method
Smali
ALT
Sparse switch: A sparse switch is used when the switch cases are not consecutive integers. In a sparse switch, the target locations for each case are stored in a separate table, which is accessed using a binary search algorithm. This makes accessing the target location for a given case slower and less efficient than in a packed switch.
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.activity_main); int value = 10; switch (value){ case 2: System.out.println("2"); break; case 10: System.out.println("10"); break; default: System.out.println("Default"); } }
Java
ALT
# virtual methods .method protected onCreate(Landroid/os/Bundle;)V .registers 5 .param p1, "savedInstanceState" # Landroid/os/Bundle; .prologue .line 11 invoke-super {p0, p1}, Landroidx/appcompat/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V .line 14 const/16 v0, 0xa .line 15 .local v0, "value":I sparse-switch v0, :sswitch_data_20 .line 23 sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; const-string v2, "Default" invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V .line 25 :goto_f return-void .line 17 :sswitch_10 sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; const-string v2, "2" invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V goto :goto_f .line 20 :sswitch_18 sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; const-string v2, "10" invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V goto :goto_f .line 15 :sswitch_data_20 .sparse-switch 0x2 -> :sswitch_10 0xa -> :sswitch_18 .end sparse-switch .end method
Smali
ALT
How switch statement can be based on a String? In Java, a switch on a string can be implemented using the 
String.hashCode()
 method, which returns a hash code for the string. The hash code can be used as the switch value, with cases defined for each possible hash code. When the switch statement is executed, the hash code of the string being switched on is computed, and the corresponding case is executed.
return
statement: This statement is used to terminate the execution of a method and return a value to the calling method.
These control flow statements can be combined to create more complex control flow structures in
Smali
.

How return works

const/16 v1, 0xa const/4 v2, 0x5 invoke-virtual {p0, v1, v2}, Llab/seczone64/smalifilestructure/MainActivity;->giveGraterNumber(II)I move-result v0
Here
v0
will store the return value from
giveGraterNumber
function.

Statement Opcodes

One Register Compare to Zero

Syntax
Descryption
Example
if-eqz vx, target
Equal Zero
if vx == 0
if-nez vx, target
Not Equal Zero
if vx ≠ 0
if-ltz vx, target
Less Than Zero
if vx < 0
if-gez vx, target
Greater Equal Zero
if vx ≥ 0
if-gtz vx, target
Greater Than Zero
if vx > 0
if-lez vx, target
Less Equal Zero
if vx ≤ 0
💡 Callout icon
Comparing a register with Zero.
💡 Callout icon
target = Location to JMP after this check.

One Register Compare To Other Register

Syntax
Descryption
Example
if-eq vx, vy, target
Equal
if vx == vy
if-ne vx, vy, target
Not Equal
if vx ≠ vy
if-lt vx, vy, target
Less Than
if vx < vy
if-ge vx, vy, target
Greater Equal
if vx ≥ vy
if-gt vx, vy, target
Greater Than
if vx > vy
if-le vx, vy, target
Less Equal
if vx ≤ vy
💡 Callout icon
target = Location to JMP after this check.

Example:

# virtual methods .method public giveGraterNumber(II)I .registers 3 .param p1, "a" # I .param p2, "b" # I .prologue .line 19 if-le p1, p2, :cond_3 .line 24 .end local p1 # "a":I :goto_2 return p1 .line 21 .restart local p1 # "a":I :cond_3 if-ne p2, p1, :cond_7 .line 22 const/4 p1, 0x0 goto :goto_2 :cond_7 move p1, p2 .line 24 goto :goto_2 .end method
public int giveGraterNumber(int a, int b){ if (a > b){ return a; } else if (b == a) { return 0; } else { return b; } }

Tasks

Flip the logic of player shield in
spacepeng
app.
Reverse engineer
Spacepeng
app and make player health added by each hit.
Reverse engineer
Spacepeng
app and change the player shot to double shot style.
Solution
Practice
fliping logic
,
removing smali code
and
jump instuction
in SMALI.