Skip to main content

Tool-selection matrix

No decompiler is best for every Android package. Select by implementation layer, then build/protection characteristics, then operator preference.

Default conventional-Android stack​

When fingerprinting shows meaningful DEX and normal Android resources:

apktool d sample.apk -o output/apktool
jadx -d output/jadx sample.apk
apkid sample.apk

Use apktool for decoded resources and smali, jadx for navigation and high-level output, and APKiD for signatures. This is a baseline, not a promise that each tool will succeed.

By implementation layer​

EvidenceBehavior likely lives inPrimary toolsVerification
ordinary classes*.dex, resourcesJava/Kotlin DEXjadx + apktoolsmali; CFR/Procyon/JEB on disputed methods
libapp.so, libflutter.so, flutter_assetsAOT Dart + platform bridgesnapshot-aware Flutter tools; inspect embeddingAndroid bridge + native cross-reference
index.android.bundle, HermesJS/Hermes bytecodetext tooling or matching Hermes disassemblerAndroid native modules; source map if owned
assemblies/*.dll, Mono.NET IL/managed assembliesILSpy, dnSpyEx, dotPeekAndroid binding layer
Unity Managed/*.dllmanaged C#ILSpy/dnSpyExUnity assets/runtime behavior
libil2cpp.so + global-metadata.datIL2CPP native codemetadata extractor + Ghidra/IDAmatching build/version; runtime if scoped
application .so + JNI bridgenative ELFGhidra/IDA, binutilsJava declarations, RegisterNatives, disassembly
tiny loader DEX + protected payloadruntime-loaded DEX/nativeloader/static analysis, then authorized runtime dumphash/provenance and dumped DEX cross-check

By era and build toolchain​

Era / traitsGood first choiceWhy / caveat
pre-2013 Java, single DEXjadx or dex2jar + classic Java decompilerlegacy pipeline often works; modern jadx is easier to operate
ProGuard-era Javajadx + apktoolnames may be short but structure often remains readable
Kotlin/coroutinesjadx + smalisource-like output helps, but state machines and synthetic code remain noisy
modern R8/AGPjadx + apktoolinlining and class merging can erase source boundaries
large multidexjadx + apktoolensure every DEX and relevant split is included
vendor/system APKapktool with framework resourcesOEM resource frameworks may be required

APK metadata only gives a rough era. Repackaging, library ages, and target SDK policy can blur it.

By protection level​

ProtectionSignsRoute
none / name minificationreadable constants and flow; short identifiersjadx; use owned mapping when available
R8 optimizationinlining, merged classes, synthesized methodscompare call sites and smali; do not expect original boundaries
string encryptionwrapper around opaque constantsisolate decoder, reimplement or observe narrowly at runtime
reflection obfuscationreconstructed names, reflective callstrace builders and targets; collect runtime names only if needed
control-flow transformationdispatch loops, opaque predicates, decompiler disagreementsmali, second engine, cautious simplification
commercial packer/virtualizerloader stub, runtime DEX/native loaderidentify loader; authorized dynamic extraction may be necessary
anti-debug/instrumentationexits under debugger/root/Fridaestablish trigger; treat bypass as separately scoped work

Tool strengths and limits​

ToolStrengthLimit
apktoolresources, manifest, smali, rebuild workflowsno Java/Kotlin source reconstruction
jadxfast navigation and Java-like output, multidex supportmay fail or silently simplify difficult bytecode
dex2jarbridge DEX into JVM decompiler ecosystemconversion can lose unusual DEX semantics; multidex handling varies
CFR / Procyonindependent Java decompiler interpretationusually consumes converted JAR, adding a conversion layer
Bytecode Viewerside-by-side engines in one UInot a substitute for original smali
JEBstrong commercial analysis and scriptingpaid; output still needs verification
APKiDquick signatures for compilers/protectorssignature coverage and certainty are limited
simplifysymbolic simplification of some obfuscationcan be slow/incomplete; preserve original evidence
Ghidrafree native disassembly/decompilation and scriptingauto-analysis and recovered types require review
IDA + Hex-Raysmature native navigation/decompilationcommercial
Fridatargeted runtime observationsetup, side effects, detection, and authorization complexity

Cross-checking rule​

Cross-check whenever the conclusion depends on exact branch semantics, error handling, cryptographic inputs, permission checks, or a decompiler warning.

  1. Read the same method in original smali/disassembly.
  2. Compare another decompiler when practical.
  3. Trace callers and callees rather than isolating one pseudocode block.
  4. Use runtime evidence only when static representations cannot resolve the question and scope allows it.
  5. Report any remaining ambiguity.

Selection record template​

Target hash:
Container/build clues:
Implementation layer:
Protection clues:
Primary tool + version:
Reason selected:
Verification tool/view:
Known limitation:

This short record makes later findings reproducible and explains why a different target may need a different pipeline.