Beyond Java: Obfuscating Android Apps with Purely Native Code
Dalvik Executable (DEX) files form the core of an Android application, encompassing the managed source and entrypoints of the code. These files are the standard starting point for reverse engineers beginning their application analysis. Imagine, however, decompiling an Android application only to discover no entrypoint definition within the DEX file!
This presentation dives into fully native code obfuscation, which eliminates managed (Java / Kotlin) code from Android applications. I will demonstrate techniques for bypassing Java class dependencies and explore methods of obfuscating Android API calls. The absence of the standard app structure hinders reverse engineering and thwarts popular decompilation tools such as APKTool and JADX which offer limited native support. Additionally, I will explore how translating application Dalvik bytecode to native code greatly reduces AV detections. This effectively allows previously known malware families and techniques to execute entirely undetected. Pure native code, however, has a few limitations. This code has a restricted view of the underlying system and applications must still rely on Android APIs for device-specific functions. To address this, the app developer can employ two techniques: use the Java Native Interface (JNI) or access the Binder driver for remote method invocation. Fully native code is an effective obfuscation method that allows previously detected malware samples to bypass detection and combat reverse engineering.
This talk will equip you with the skills needed to implement fully native code obfuscation to protect your Android code. You will also learn the intricacies of the Java Native Interface and explore the functionality of the Binder driver in the Android kernel source. Together, we will create a purely native binary that effectively combats reverse engineering and detections.
This talk will provide a detailed analysis of the intricacies of fully native code obfuscation. During the presentation, I will provide demonstrations of all the techniques that I discuss to fully prepare the audience to implement these obfuscation methods. Participants will also receive a deep dive into the Android Binder kernel source code. Below is a high-level outline that will also include examples:
- Standard APK structure – AndroidManifest definition and Java declaration
- Implementing a fully native application using NativeActivity as the C++/Java glue
- Exporting C++ methods as Android callbacks
- Limitations of purely native code for affecting the Android device
- Calling Android APIs via the Java Native Interface (JNI)
- Drawbacks of using the JNI in native code
- Obfuscating API calls
- Bypassing the JNI by using the Android Binder driver for remote method invocation
- Android kernel Binder function and structure
- Constructing a Parcel object for a target method
- Effectiveness of native code obfuscation
- Thwart decompilation and hide functions in native binaries
- Avoiding antivirus detections – example of taking a detected sample and rewriting it in native code