跪拜 Guibai
← All articles
Artificial Intelligence · Android · Computer Vision

Obfuscation Is for Size, Not Security — How One Keep Rule Sabotaged It for Two Years

By 疯华整猫 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Treating R8 obfuscation as a security feature leads to over-broad keep rules that silently cancel its size and performance benefits; the four-metric audit approach gives any Android team a concrete way to avoid a two-year silent regression.

Summary

Android obfuscation's original purpose is reducing dex size, not preventing reverse engineering. A developer found their project's `-keep class com.example.** { *; }` rule had been keeping the entire business package intact, leaving seeds.txt larger than mapping.txt and rename coverage under 10%. Removing it caused production ClassNotFoundExceptions from reflection, JNI, and serialization paths, forcing a systematic cleanup.

The article walks through the history of obfuscation from ProGuard to R8, showing how full mode changed rule semantics in four ways, and details a 12-round workflow with the AI assistant Trae. Each round uses explicit goals, constraints, and validation to measure four metrics: rename coverage, seeds count, usage count, and dex size. The final state: coverage 79.6%, dex down from 21.4 MB to 17.9 MB, and a CI gate that fails on any broad keep or disabled optimization.

Takeaways
— Obfuscation originated to save dex space, not to hinder reverse engineering.
— ProGuard's first release in 2002 had only shrinking and name obfuscation.
— R8's Minifier uses shortest-available identifiers in dictionary order.
— Full mode in AGP 8.0 changes attribute retention, default constructors, visibility, and reachability for reflection-only references.
— The project's rename coverage went from 8.7% to 79.6% after removing a broad keep rule.
— Dex size dropped from 21.4 MB to 17.9 MB after cleanup.
— seeds.txt should be smaller than mapping.txt in a healthy build.
— -dontwarn is the most expensive line of configuration because it suppresses real problems.
— Custom non-ASCII obfuscation dictionaries increase dex size and are auto-rewritten by decompilers.
— mapping.txt must be archived per build with version and commit; if it leaks, obfuscation is undone.
— The CI check fails on any -keep class ...** or framework-level keep.
— Cold start improved by 60 ms after cleanup.
Conclusions

The article's core claim that obfuscation is a volume optimization is backed by R8's official docs and the historical record, but it implies that many teams misdirect effort toward perceived security, as shown by the developer's own two-year blind spot.

The 12-round prompt engineering demonstrates that AI coding assistants can be held to measurable deliverables when given explicit constraints and validation criteria, yet the initial staging crash shows that even with a correct regression checklist, human discipline is required to execute it.

The negative result on custom dictionaries contradicts a common belief that more exotic obfuscation is better; the measured dex bloat and decompiler resilience make the default shortest-name strategy the rational choice.

The mapping.txt leak warnings and the deliberately-wrong-mapping retrace drill highlight that operational hygiene is more important than the obfuscation algorithm itself.

Concepts & terms
Minifier
The component in R8 that renames classes, methods, and fields to short identifiers, using a simple dictionary-order strategy that picks the shortest available name.
Full mode (R8)
The default optimization mode since AGP 8.0, which changes rule semantics in four major ways: attribute retention, default constructors, visibility modification, and reachability for reflection-only references.
mapping.txt
A file generated by R8 that records the bidirectional mapping between original and obfuscated names; it is essential for restoring crash stacks and must be archived per build and kept private.
seeds.txt
An output file listing all classes and members kept from obfuscation; a healthy build should have far fewer seeds than mapping entries, and each seed should have a documented rationale.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗