The 5-Layer Hardening Pipeline
Deep dive into VALLUM's 5-stage pipeline: resource shrinking, control-flow obfuscation, function extraction, RASP, and signing.
The VALLUM pipeline is orchestrated by a PowerShell script that runs each engine in sequence. Step 0 checks the environment, Step 1 confirms the APK was already minified by R8 at build time, and Steps 2 through 6 drive the five hardening engines. Every step reports progress over Server-Sent Events, so the UI can show AndResGuard at 25%, control-flow at 45%, dpt-shell at 70%, RASP at 90%, and signing at 95%.
Layer one is AndResGuard at the resource level. Running under JDK 8, it renames res/ paths and entries to short opaque names and recompresses the archive with 7za, while a whitelist keeps launcher icons such as ic_launcher intact to avoid install failures. It defends against resource theft and asset-name reconnaissance, and the cost is minimal - it often shrinks the APK - with the best compatibility of any layer.
Layer two is BlackObfuscator for control flow. By design it flattens the DEX control flow, breaking linear logic into a dispatched state machine to frustrate manual reading. In practice, on an R8-minified APK its dex2jar-to-jar2dex round trip emits invalid bytecode; dx tolerates it but the resulting DEX string pool balloons roughly sevenfold and triggers a runtime NullPointerException. For that reason it is temporarily disabled across the Standard, Enhanced, and Maximum profiles.
Layer three is dpt-shell for function extraction, run with the bundled JDK 11 dpt.jar. It carves method bodies out of the DEX and restores them at runtime through a shell ClassLoader plus JNI, so jadx only sees nop method stubs. Safe mode passes --disable-anti-debug and --disable-frida-detect and deliberately omits -vs and -S. The cost is a larger package, a first-load restoration overhead, and sensitivity to native ABIs.
Layer four is Abdal-DroidGuard, the RASP stage, injected with --all --verbose. It detects debuggers, Frida, emulators, and root at runtime and aborts on tampering. Because it depends on the shell structure that dpt-shell produces, skipping dpt forces the script to skip Abdal as well - the two are coupled. The cost here is occasional false positives and a small runtime overhead.
Layer five is signing. Since dpt-shell and Abdal each re-sign with their own debug certificates, the final stage runs zip_clean.py to strip old signatures, zipalign to align, then apksigner to re-sign with V1+V2+V3 and verify. Three modes are supported: platform (test only), user (your own keystore), and none (produce an unsigned build). Get the signature wrong and the APK cannot be installed or published.