Smali and native code review: dex bytecode and .so libraries
Where jadx gives up you read smali, get to know the dex format, follow the JNI bridge and statically audit native libraries for compiler protections, embedded secrets and risky functions.
Level 301 · 22 lessons · 18 practice labs
Lessons
Dex and smali
- The dex file format: classes, methods, the string table
- Smali syntax: registers, types and invocations
- Reading control flow in smali: conditions, loops, exceptions
- Mapping smali to Java: reading the same method in both forms
- Multidex and traces of dynamic code loading
- Short task: explain what a licence check written in smali does
Obfuscated code
- Recognising R8 output: inlining and class merging
- Deobfuscating a stack trace with the mapping file and retrace
- Recognising string encryption patterns
- Reflection and dynamic calls: the blind spot of static analysis
- Short task: make an obfuscated crash record readable with the mapping file
JNI and native libraries
- The JNI bridge: native methods and JNI_OnLoad
- ELF and ABIs: arm64-v8a, armeabi-v7a, x86_64
- Getting to know a library with readelf, nm and strings
- Compiler protections: PIE, RELRO, stack protector, FORTIFY
- Short task: tabulate the compiler protections of three .so files
Reading native code
- ARM64 reading basics: registers and the calling convention
- Decompiling a .so with Ghidra: function list and pseudocode
- Risky C functions and signs of buffer overflow
- Embedded keys and hand-rolled crypto in native code
- Short task: find the API key embedded in a native library and say why that is no protection
Capstone
- Capstone: write the smali and native code review note for a payment SDK
Practice labs
- Find what a smali method returns: Read a short smali method and write its return value with the Java equivalent.
- Explain a licence check written in smali: Follow the conditions and branches and write step by step when the check passes.
- Rewrite a method jadx could not decompile from smali: Read a validation method that failed to decompile from smali, turn it into pseudocode and comment on its security.
- List the dex files and class counts in an APK: Extract the class count of each dex file in a multidex APK.
- Search the string table for suspicious values: Dump the dex string table and pick out URL-like and key-like values.
- Find traces of dynamic code loading: Find class loader use in the code and the extra dex file hidden in assets and report the risk.
- Find a class's real name in the mapping file: Extract the original name of an obfuscated class from the mapping file.
- Deobfuscate a crash record with retrace: Make the stack trace readable with the mapping file and state which method the error is in.
- Recognise and document a string encryption pattern: In an APK whose strings pass through one decode method, show the pattern and say how it limits static analysis.
- List the .so files and architectures in an APK: List the libraries in the lib folder by ABI.
- Tabulate the compiler protections of three libraries: Use readelf to extract PIE, RELRO, stack protector and FORTIFY status.
- Rebuild an unprotected library and verify: Fix the build flags, rebuild the library and prove with output that the protections are on.
- Find the methods declared native: List the native methods and the loaded library name in jadx output.
- Match JNI functions from the symbol table: Match the library's exported symbols to the native methods on the Java side.
- Extract the methods registered in JNI_OnLoad: Find the dynamically registered method table in Ghidra pseudocode and document which Java method each binds to.
- Find the embedded key in a native library with strings: Find the string that looks like an API key in the .so file.
- Count the uses of risky C functions: Find functions such as strcpy and sprintf among the imports and list where they are called.
- Write the native code review note for a payment SDK: Gather protections, embedded key, hand-rolled crypto and risky function findings in one review note.
About this course
Where jadx gives up you read smali, get to know the dex format, follow the JNI bridge and statically audit native libraries for compiler protections, embedded secrets and risky functions.
What you will learn
- Dex and smali
- Obfuscated code
- JNI and native libraries
- Reading native code
- Capstone
Prerequisites
You should be comfortable with the level 101 and 201 topics of the same path.
Lab environment
Lessons run in your own Kali Linux terminal that opens in the browser. Nothing to install; the lab starts clean in every lesson.
Frequently asked questions
- Is this course right for my level?
- The course is at level 301; it assumes you know the topics of the lower-level courses.
- Is there anything to install?
- No. Every lesson runs in your own lab environment that opens in the browser.
- How do lessons work?
- Each lesson has 8 to 10 steps and a short quiz. Early steps show the command to type, later steps give less help; if two attempts fail, the solution opens.
- Can I try it for free?
- Yes. The first three lessons of every course are free.