Android

Reinforcement ideas for Android application core code

2025-10-30

Code form

Android projects are usually written in high-level languages such as Java/Kotlin, and after compilation, they first obtain. class, which is then compiled into. dex by dx/d8, and finally distributed with APK. Therefore, all business logic ultimately settles in. dex. And mature decompilation tools on the market (jadx, baksmali, etc.) can instantly restore. dex to approximate source code in seconds, allowing developers to effortlessly write algorithms, protocols, and encryption processes. So, how to protect. dex has become the top priority of security work. The following article summarizes several common reinforcement routes in the industry.


Strengthen the route

1. Dex overall encryption

1.1 Landing Loading

The idea is simple: encrypt the entire. dex file and insert it into the installation package. At startup, use our self-developed ClassLoader to decrypt the ciphertext into plaintext. dex, and then hand it over to PathClassLoader for loading. Static reverse can only see a bunch of meaningless ciphertexts, which indeed blocks many script kids. But the drawbacks are also obvious: the decrypted plaintext. dex must be stored on the disk, which can be easily copied by rooting the device or using Frida, greatly reducing the protection effect.

1.2 Memory loading

In order to eliminate the shortcoming of "disk dropping", InCacheDexClassLoader appeared after Android 8.0, which can directly decrypt ciphertext into ByteBuffer in memory and feed it to the virtual machine in one breath. The entire process does not touch the disk, and it is difficult to obtain files even after rooting. Unfortunately, decrypting. dex will create a continuous image in memory, and attackers only need to dump the memory to reassemble the complete. dex, which is still not the ultimate solution.

1.3 Method Level Strip Extraction

Furthermore, instead of encrypting the entire. dex, each method's CodeItem is individually extracted and encrypted, and the backfill is decrypted only when running to a certain method. Static reverse can only see a large number of empty shell methods; Dynamic dump can only retrieve methods that have already been executed. But the higher the road, the higher the devil. Attackers can use Inline Hooks or ART interpreters to plug in and "stitch" decrypted instructions back while running, ultimately still having a chance to spell out the complete. dex.

2. Java2C(Java → Native)

If you don't want any sensitive code to appear in. dex, you can move the key methods as a whole to the Native layer:

  • First declare the native method in the Java layer;
  • Translate the original Java methods into equivalent C/C++logic using tools;
  • Compile into. so and expose it to Java calls through JNI.


The Java layer only has one shell left, and the reverse engineer can only see Native symbols, which greatly increases the difficulty of static analysis. However, native debugging (IDA, Frida stalker) is still feasible, and JNI call chain, exception handling, and GC interaction all require additional support, resulting in increased development costs and stability risks.

3. Dex VMP (Virtual Chassis)

The current route known as the "ultimate solution" on the market is to translate Dalvik bytecode in. dex into a private instruction set, which is interpreted and executed by the built-in virtual machine during runtime. The attacker only receives custom bytecode, and to restore it, they must first understand the entire VM architecture, instruction format, and scheduling logic, resulting in an exponential increase in workload.

However, VM itself has become a new attack surface - as long as the interpreter is reversed clearly, theoretically it can still be restored, but the threshold is much higher than the previous solutions.


One stop reinforcement tool

Virbox Protector packages the above ideas into a "foolproof" solution:

  • Core function: DEX Function Level Virtualization (VMP), one click to translate specified methods into private instructions;
  • Auxiliary functions: string encryption, overall Dex encryption, anti debugging, anti injection, signature verification, file integrity verification;
  • Environmental detection: anti emulator, anti root, anti multi open, anti screenshot.


Developers only need to check the options and configure the rules to complete the reinforcement during the compilation phase, without the need to manually write JNIs or maintain VMs, truly achieving the goal of "writing business logic and leaving the rest to the tools".

more stories
See more