Hacktricks-skills android-smali-pentest
Android APK decompilation, Smali code modification, and recompilation for security testing. Use this skill whenever the user mentions APK analysis, Android app security testing, decompiling Android applications, modifying Smali code, reverse engineering Android apps, or needs to extract hidden information from Android applications. This skill handles the complete workflow: decompile APKs with APKTool, modify Smali bytecode, recompile, sign, and optimize the modified APK.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/mobile-pentesting/android-app-pentesting/smali-changes/SKILL.MDAndroid Smali Pentesting
A skill for decompiling, modifying, and recompiling Android APKs for security testing and reverse engineering.
Workflow Overview
- Decompile the APK to access Smali code and resources
- Analyze the decompiled code for security issues or hidden data
- Modify Smali code to extract information or bypass protections
- Recompile the modified APK
- Sign the APK with a test key
- Optimize with zipalign (optional but recommended)
Step 1: Decompile the APK
Use APKTool to decompile the APK and access Smali code:
apktool d APP.apk
This creates a folder with:
- Decompiled Smali bytecodesmali/
- Resources (layouts, strings, etc.)res/
- App manifestAndroidManifest.xml
Key files to examine:
- String resources (may contain hardcoded secrets)res/values/strings.xml
- Permissions, activities, servicesAndroidManifest.xml- Any
or.sqlite
files - Databases.db
Troubleshooting APKTool errors:
- Install the latest version: https://ibotpeaches.github.io/Apktool/install/
- If decoding fails, try with
flag (skip resource decoding):-rapktool d -r APP.apk - For framework issues, see: https://ibotpeaches.github.io/Apktool/documentation/#framework-files
Step 2: Analyze and Modify Smali Code
Finding interesting code:
- Search for strings in
to find related Smali filesres/values/strings.xml - Look for hardcoded credentials, API keys, or flags
- Examine authentication logic in activity files
- Check for obfuscated code patterns
Common Smali modifications:
Modify variable values:
# Change a constant value const v9, 0xf4240 # Change to: const v9, 0x0 const-string v5, "wins" # Change to: const-string v5, "LOSE"
Add logging to trace execution:
# Log a variable value iget v5, p0, Lcom/example/Activity;->variable:I invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; move-result-object v1 const-string v5, "DEBUG" invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
Add toast notifications:
# Show a toast with a variable value iget v10, p0, Lcom/example/Activity;->variable:I invoke-static {v10}, Ljava/lang/String;->valueOf(I)Ljava/lang/String; move-result-object v11 const/4 v12, 0x1 invoke-static {p0, v11, v12}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; move-result-object v12 invoke-virtual {v12}, Landroid/widget/Toast;->show()V
Bypass authentication checks:
# Change conditional to always pass if-eq v0, v1, :cond_1 # Original: if not equal, jump # Change to: const/4 v0, 0x1 # Force success condition
Important Smali patterns:
| Pattern | Description |
|---|---|
| Number of registers used in method |
| Number of local variables |
| Set register v0 to value 1 |
| Set register v0 to string |
| Call virtual method |
| Call static method |
| Get instance field |
| Set instance field |
| If equal, jump to label |
| Unconditional jump |
When adding code to a method:
- Increase
count by the number of new variables needed.locals - Use the next available register numbers (e.g., if using v0-v9, use v10, v11)
- Place new code between
declaration and variable declarations.locals
Step 3: Recompile the APK
Navigate to the decompiled folder and recompile:
apktool b .
The compiled APK will be in the
dist/ folder.
Step 4: Sign the APK
Android requires all APKs to be signed. Generate a test key and sign:
Generate signing key:
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias myalias
Sign with jarsigner (before zipalign):
jarsigner -keystore key.jks dist/modified.apk myalias
OR sign with apksigner (after zipalign):
apksigner sign --ks key.jks dist/modified.apk
Note: Sign only once - either with jarsigner before zipalign OR with apksigner after zipalign.
Step 5: Optimize with zipalign (recommended)
zipalign -v 4 dist/modified.apk dist/optimized.apk
If using apksigner, sign after this step.
Common Use Cases
Extract hidden flags or secrets:
- Decompile the APK
- Search
for suspicious stringsres/values/strings.xml - Find the Smali file that uses those strings
- Add logging or toast to reveal values at runtime
- Recompile, sign, and install
Bypass license checks:
- Find the license verification method
- Modify the conditional to always return true
- Recompile and test
Enable debug features:
- Search for debug-related strings or methods
- Modify flags or conditions to enable debug mode
- Recompile and test
Log sensitive data:
- Identify where sensitive data is processed
- Add logging statements to trace the data flow
- Recompile, install, and check logcat
Tools and Resources
- APKTool: https://ibotpeaches.github.io/Apktool/
- APKLab (VS Code extension): https://github.com/APKLab/APKLab
- apk.sh script: https://github.com/ax/apk.sh
- Dalvik Opcodes Reference: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html
- Smali Instruction Set: https://source.android.com/devices/tech/dalvik/dalvik-bytecode
Tips
- Backup the original APK before modifying
- Use VS Code with Smali extension for syntax highlighting and validation
- Test incrementally - make small changes and verify before proceeding
- Check logcat after installing modified APKs to see your logging output
- Keep track of register usage - don't overwrite registers that are still in use
- Update
count when adding new variables to a method.locals