
nmmp converts classes.dex bytecode into randomized C structures executed by a native dex-vm, raising reverse-engineering difficulty for developers protecting their own authorized Android releases.
| Tool | maoabc/nmmp — a dex-vm based protector that converts dalvik bytecode in classes.dex into native C structures with randomized opcodes to resist decompilation |
| Category | Android application hardening / bytecode virtualization |
| Primary Use | Protecting your own apk, aab, or aar releases by converting selected classes.dex methods into dex2c native code executed by an embedded vmInterpret engine |
| Safe Use | Use only on Android applications you own or are contractually authorized to harden; also valuable for defensive analysts studying virtualization-based obfuscation techniques in lab environments |
| Telemetry Note | Protected apps gain native .so libraries and a dex-vm interpreter loop, a recognizable structural signature for analysts; conversion leaves a build/dex2c CMake project on the build machine, and obfuscated code complicates static review — defenders should factor this into malware triage |
nmmp from maoabc/nmmp is an Android application hardening tool built around a simple but powerful idea: instead of merely obfuscating classes.dex, it virtualizes it. The project, written largely in C with a Java-based converter component, runs dalvik bytecode inside a custom dex-vm implemented at the native layer, dramatically increasing the effort required to decompile an application with tools like jadx or apktool. With over 1,200 stars and topics tagging android and ndk, it occupies a niche that commercial packers dominate but that open source rarely addresses well.
The repository is split into two cooperating components. nmm-protect is a pure Java project responsible for transformation: it parses the input dex, converts the dex data into C structures, randomizes the opcode mapping, generates a complete ndk project, and compiles everything into a hardened apk. nmmvm is the Android project containing the actual dex-vm interpreter implementation plus tests exercising the various dalvik instructions. This separation of build-time converter and runtime VM mirrors the architecture of native protectors on desktop platforms, and it means only the Apache-licensed VM portion ships inside the final application — the GPL-licensed nmm-protect converter stays on the build machine, so licensing does not contaminate the output.
The heart of the runtime is a single entry point, vmInterpret, which takes a JNIEnv pointer, a vmCode structure, and a vmResolver structure. The README shows the design clearly: vmCode carries the instruction stream (insns), its size (insnsSize), the register file (regs), register type flags (reg_flags — notably marking which registers hold object references, which matters for GC correctness), and the exception handler table (triesHandlers). vmResolver is a vtable-like collection of function pointers that supply runtime symbols: dvmResolveField, dvmResolveMethod, dvmResolveTypeUtf, dvmResolveClass, dvmFindClass, and dvmConstantString. This resolver indirection is the key extensibility point — different protection strategies can plug in different resolvers, and the repository includes a simple libdex-based resolver in test.cpp used during development.
Opcode randomization is the detail that elevates nmmp above naive dex-to-native translation. Because nmm-protect rewrites instructions into a private, per-build opcode encoding before emitting them as C structures, the interpreter loop in the shipped .so library does not correspond to any standard dalvik instruction semantics an analyst can pattern-match against. Every protected build effectively speaks its own dialect. Combined with the disappearance of the original Java-level method bodies from the dex, this defeats the usual decompiler workflow of loading an apk and reading recovered Java source.
Operationally, the tool is a command-line jar. After setting ANDROID_SDK_HOME, ANDROID_NDK_HOME, and optionally CMAKE_PATH, you run something like java -jar vm-protect-xxx.jar apk input.apk convertRules.txt mapping.txt. The build produces a build/ directory containing the final input-protect.apk, the complete dex2c CMake-based C project, and intermediate .dex artifacts — the emitted C project is itself useful reading for anyone studying how bytecode-to-structure conversion works. A first run also creates a tools/ directory next to the jar with a config.json for SDK and NDK path configuration. Beyond apk, the same jar handles aab bundles and aar module hardening with analogous invocations, and newer versions use zipflinger internally so a separate zipalign pass is no longer required; signing with apksigner or jarsigner remains the developer's responsibility.
Selection of what gets converted is controlled by a rule file, and the README is candid about its simplicity. Without a rules file, every class's methods are converted except constructors and static initializers. The supported syntax treats * as a regex .* and handles basic inheritance matching, such as class * extends android.app.Activity or class my.package.* { *; }. One documented subtlety worth internalizing: inheritance matching is single-level, so class * extends A matches a direct subclass B but not the grandchild C — a detail that can silently leave classes unprotected if your rule set assumes transitive matching. Method-level filters like if*; inside a class block allow finer-grained inclusion.
The README also points to community infrastructure around the core project: a third-party GUI front-end at TimScriptov/nmmp for operators who prefer not to work from the shell, and a prebuilt demo apk in the project's releases illustrating the end-to-end output. Building from source follows the standard gradlew workflow — ./gradlew arsc:build then ./gradlew build inside nmm-protect yields an executable fatjar in build/libs. The dual-licensing arrangement (GPL for the converter, Apache for the VM) is explicitly documented, with the author noting that only the VM is packaged into the apk, so the license mix does not affect distributed binaries.
For an authorized audience, nmmp is interesting from two directions. Developers shipping proprietary Android software can use it to protect intellectual property in their own releases, applying it as part of a release pipeline alongside zipalign and apksigner. Security researchers and malware analysts, on the other hand, should study it as a representative of the virtualization techniques increasingly seen in Android malware and commercial packers: recognizing the structural signature — a thin dex shell plus a native library containing an interpreter loop dispatching over randomized opcodes — is a core triage skill. Building and protecting a test app of your own in a lab is the most direct way to understand what such code looks like under static analysis.
The trade-offs are the usual ones for virtualization: runtime performance overhead from interpreted execution, potential instability on less-tested instruction paths, and a harder debugging story for your own crashes. The README acknowledges practical rough edges by inviting issue reports on aar module protection, and the included dalvik instruction test suite in nmmvm signals that instruction coverage is treated as a correctness concern rather than an afterthought. For teams evaluating it, testing against the full range of instructions your codebase actually emits, including exception handling paths covered by triesHandlers, should precede any production use.
What nmmp ultimately demonstrates is that serious Android application protection does not require a commercial black box. A clean two-part architecture — a build-time Java transformer emitting randomized C structures, and a compact native vmInterpret engine with resolver-based symbol indirection — delivers the same class of anti-decompilation resistance that desktop software protectors have offered for years, under permissive licensing for the shipping component, with full source available for audit.
maoabc/nmmp.Educational analysis for authorized security professionals. Use only in controlled, authorized environments.
Related coverage
0 comentários:
Post a Comment
Note: Only a member of this blog may post a comment.