Android Static Analysis Fundamentals: Smali Code Introduction and Modifications

Post Date

Published on
Android Static Analysis Fundamentals: Smali Code Introduction and Modifications

TL;DR: Discover the power of Smali code, a vital skill for Android app analysis and reverse engineering apps. Unveil an app’s inner workings and spot security vulnerabilities with ease. This guide provides practical knowledge and essential skills for navigating Smali effectively.

TL;R2: In this theoretical and practical guide, we will analyze various Smali components and compare them with their Java counterparts for better understanding, and finally for each topic we will provide a real-world example from our security challenge (please watch the video demonstration). You can download the application from here.

What is Smali Code?

Smali code represents the intermediate language of Android application bytecode. When Android apps are compiled from Java/Kotlin source code, they are translated into bytecode, which can then be converted into Smali code, a readable format that allows us to examine an app’s functionality and behavior. By mastering Smali code, you gain valuable insight into an app’s logic, proprietary algorithms, and its interactions with the Android system.

Why is Understanding Smali Code Essential?

In today’s rapidly evolving mobile landscape, securing Android applications is of utmost importance. Understanding Smali code empowers you to analyze an app’s low-level implementation, revealing potential vulnerabilities that may not be apparent at higher abstraction levels. This knowledge is vital for ensuring the privacy and security of sensitive user data against malicious threats.

Summarizing, we’ll be reviewing Smali syntax:

  1. Registers
  2. Instructions
  3. Labels.
  4. Method and Field References

1. Smali Registers

Smali code uses registers (e.g., “v0,” “v1”) to store and manipulate data during Android app execution. These registers are represented by the prefix “v” followed by a number and can be compared to variables in other programming languages.

Smali Registers

Challenge3 example:

Smali Registers Challenge 3 example

2. Smali Instructions

Smali instructions enable flow control in Android apps through conditional branches. These branches direct the program flow based on the evaluation of conditions, allowing the Dalvik VM to execute different code blocks or repeat specific sections as needed during app runtime. In this case, we are analyzing some conditional statements.

Conditional statements

if-eq vA, vB, label   #Evaluates if vA and vB are equal.  
if-ne vA, vB, label   #Evaluates if vA and vB are not equal.  
if-eqz vA, label   #Evaluates if vA is equal to zero (FALSE).  
if-nez vA, label   #Evaluates if vA is not equal to zero (TRUE).
Smali Instructions

Challenge3 example:

Smali Instructions Challenge 3 example
Img. Ref.: if-nez p1, :cond_0 -> if p1 is not equal to 0 or false then jumps to cond_0

3. Smali Labels

Labels serve to mark specific points in the code and enable branching or jumping to those points. They are denoted by a colon (:) at the end. Furthermore, labels are used in conditional statements and loops to control the program flow. Typically, they are placed after a conditional statement to indicate where the program should jump if the condition is met.

Label declaration example (:)


Implementation example:

const v0, 10              ;Assign the value 10 to register v0  
if-nez v0, :not\_zero      ;If v0 is not equal to zero, branch to the label :not\_zero   
goto :end  
:not\_zero           ;Code to execute when v0 is not equal to zero  
:end                ;Code after the conditional statement

Challenge3 example:

Img. Ref: if-nez p1, :cond_0 -> if p1 is not equal to 0 or false then jumps to cond_0
Img. Ref: if-nez p1, :cond_0 -> if p1 is not equal to 0 or false then jumps to cond_0

4. Smali Method and Field References

The format is “class_descriptor/method_name:method_signature” for methods.

In this example, we have an invoke-virtual instruction that is used to invoke the substring method on an instance of the String class.

Smali Method and Field References

Smali Code Components Breakdown

Smali Code Components Breakdown
Smali Code Components Breakdown

Challenge3 Method and Field References example:

Challenge3 Method and Field References example
invoke-static {p0} -> invoke static method and passes p0 as argument  
Lcom/just/mobile/sec/challenge3/RootUtil; -> parent class is RootUtil  
Method Name -> isDeviceRooted  
Parameter Type -> Context  
Returns -> Boolean

You can see the following video with the static modification as an example:

References Steps:

1. Decompiling the APK with APKTOOL:
1.1. $apktool d Challenge_3.apk -o Challenge_3_APKTOOL
2. Making the Static Modification
2.1. Change if-eqz for if-nez  
3. Re-Compiling the APK with APKTOOL
3.1. $apktool b Challenge_3_APKTOOL/ -o Challenge_3_APKTOOL.apk
4. Creating a Debug Keystore for signing the APK
4.1. $ keytool -genkey -v -keystore JustMobileSec.jks -alias JustMobileSec -keyalg RSA -keysize 2048 -validity 10000  
5. Aligning the APK with Zipalign
5.1. $ zipalign -p -f -v 4 Challenge_3_APKTOOL.apk Challenge_3_APKTOOL_aligned.apk
6. Signing the APK with Apksigner
6.1.$ apksigner sign --ks JustMobileSec.jks Challenge_3_APKTOOL_aligned.apk

For more information about the Dalvik opcodes used in Smali code, you can visit this link for the full list.

Stay tuned to the following posts and don’t forget to follow us!

Just Mobile Security | LinkedIn

Juan Urbano Stordeur (@juanurss) / Twitter

Just Mobile Security — Medium