Full workflow
- Triage: [[re-triage]] (capabilities:
triage) —— file/hash/entropy to confirm the input type (both APK and IPA are ZIP containers,filereports ZIP; pure.so/ Framework dylib go directly to step 4); if the [[re-analyze]] entry point was not used, do it first, read theRE_*session variables - Static:
- Android: [[re-apk]] (capabilities:
dex-parser) —— apktool unpacking, AndroidManifest entry points/permissions/components, jadx decompiling Java, smali patch ideas, hardening identification - iOS: [[re-ios]] (capabilities:
macho-parser) —— ipa unpacking and signature checks, class-dump headers, decrypting encrypted binaries
- Android: [[re-apk]] (capabilities:
- Dynamic: [[re-frida]] (capabilities:
frida-instrumentation) —— when runtime behavior is needed (decryption, hooking, bypassing certificates/detection, observing call chains), spawn/attach instrumentation; for iOS breakpoint debugging use [[re-lldb]] (capabilities:debugging) - Native libraries: mobile apps containing native code (Android
lib/*.so, dylib inside iOS Framework) → [[re-binary-core]] (capabilities:decompilation、debugging、memory-dump、elf-parser、pe-parser、macho-parser): [[re-format-elf]] (capabilities:elf-parser; Android) / [[re-format-macho]] (capabilities:macho-parser; iOS) parse the format, [[re-ghidra]] (capabilities:decompilation、debugging) decompiles the underlying JNI/OC logic; for deep Android native work (JNI registration recovery, so logic) use [[re-android-native]] (capabilities:jni-analysis); for iOS jailbreak environments (jailbreak detection / tweak / dynamic debugging) use [[re-ios-jb]] (capabilities:jailbreak-analysis) - Hardening/packing: [[re-apk]] (capabilities:
dex-parser) after identifying hardening, move to the unpacking domain ([[re-anti-analysis]] (capabilities:unpack、deobfuscation、evasion-analysis), Android); for iOS App Store encrypted binaries, unpack according to [[re-ios]] (capabilities:macho-parser) (the backend is chosen according to the target iOS/jailbreak environment). Return the unpacked artifacts to step 2 and re-run - Deliverables: conclusions/report (according to
RE_REPORT), hashes and evidence archived (see [[re-triage]] (capabilities:triage))
Archive the result of each step (evidence path + sha256, see [[re-triage]] (capabilities:triage)), for citation in the report; if a malicious sample/callback is found, switch to [[re-malware]] (capabilities:malware-behavior、document-malware、evasion-analysis、key-extraction、threat-intel)。
When to use which atomic skill (selection tree)
- Input is an APK / target is Android → [[re-apk]] (capabilities:
dex-parser) static → runtime needed → [[re-frida]] (capabilities:frida-instrumentation) - Input is an IPA / target is iOS → [[re-ios]] (capabilities:
macho-parser) static + unpacking → breakpoint debugging [[re-lldb]] (capabilities:debugging) / instrumentation [[re-frida]] (capabilities:frida-instrumentation) - Target contains native libraries (.so / dylib) → [[re-binary-core]] (capabilities:
decompilation、debugging、memory-dump、elf-parser、pe-parser、macho-parser; [[re-format-elf]] (capabilities:elf-parser) / [[re-format-macho]] (capabilities:macho-parser) / [[re-ghidra]] (capabilities:decompilation、debugging)); Android native specialization (JNI/so) → [[re-android-native]] (capabilities:jni-analysis) - Target has jailbreak detection / tweak analysis needed / dynamic debugging on jailbroken devices → [[re-ios-jb]] (capabilities:
jailbreak-analysis) - Need decryption / certificate bypass / function hooking / observing call chains → [[re-frida]] (capabilities:
frida-instrumentation) - Hardening/packing: Android → [[re-anti-analysis]] (capabilities:
unpack、deobfuscation、evasion-analysis; first identify via [[re-apk]] (capabilities:dex-parser)); iOS encryption → [[re-ios]] (capabilities:macho-parser) unpack - Android hardening unpacking specialized (Legus/360/Bangcle/Ijiami) → [[re-mobile-pack]] (capabilities:
unpack; after identification run/static unpacking + DEX repair) - Flutter / React Native hybrid apps → [[re-hybrid-app]] (capabilities:
hybrid-app-analysis; engine identification → blutter / hermes-dec) - Extract DEX/keys from runtime memory → [[re-memdump]] (capabilities:
memory-dump; DEX extraction see that skill)
Cross-domain combination
- Mobile App contains native libraries: [[re-mobile]] → [[re-binary-core]] ([[re-format-elf]] / [[re-ghidra]] decompile JNI/OC low-level logic); Android native specialized [[re-android-native]]; iOS jailbreak environment [[re-ios-jb]] (jailbreak detection / tweak / lldb remote)
- Mobile App hardening/packing: [[re-mobile]] → [[re-anti-analysis]] (Android unpacking); iOS encrypted binary [[re-ios]] unpacking
- Dynamic analysis default sandbox: emulator snapshot / controlled jailbroken device + network isolation ([[re-analyze/platform-tips]] highest principle)
- Mobile malicious samples/callbacks: [[re-mobile]] → [[re-malware]] (for behavior analysis see [[re-sandbox]])
- This gateway is invoked by the "Mobile App Analysis" path in [[re-analyze]]'s triage.md (re-mobile → re-apk / re-ios → re-frida → if contains native libraries re-binary-core)
Common pitfalls and traps
- Getting an APK and directly running jadx to output Java then drawing conclusions → for hardened samples jadx only sees the shell — first use [[re-apk]] to identify hardening, then switch to the unpacking domain ([[re-anti-analysis]]) or dynamically obtain in-memory DEX
- Analyzing an iOS encrypted binary as a normal static target → class-dump/otool only sees the shell or ciphertext — first check according to [[re-ios]]
cryptidand unpack before continuing - Running mobile dynamic analysis directly bare on a real device → device environment uncontrollable, evidence hard to reproduce — prefer emulator snapshot / controlled jailbroken device, network isolation ([[re-analyze/platform-tips]] highest principle)
- Ignoring native libraries → only analyzed the Java/OC layer, core logic (JNI, anti-debugging, sensitive algorithms) is all in .so/dylib — see
lib/and Framework, then switch to [[re-binary-core]] - Skipping steps in the selection tree → using frida before static analysis is done, or still no progress after using all dynamic means — advance in workflow order 1→6, archive evidence at each step before proceeding to the next
Mobile package repackaging and patching
- Repackaging preserves original format parameters: Symptom—the package after repackaging/resource replacement crashes on load or fails to parse on a real device; Cause—the repackaging tool's default output format differs from the original format (compression method/alignment/container flags); Countermeasure—preserve the original package's format parameters (compression flags/alignment), produce output of the same order and format as the original file, verify locally first before going to a real device
- Before replacing embedded resources, first understand the host structure: Symptom—after replacement the target reads misaligned; Cause—the container's embedded length/header fields are unknown (length field not synchronized when replaced content length changes); Countermeasure—first script-parse the host structure (magic number/length field positions), after replacement reverse-extract the content from the final artifact for comparison and verification (in compressed containers strings cannot find it, must decompress to verify)
- Patch injection point selects a module whose content is completely known: Symptom — to modify a module with complex logic, you can only patch the instruction stream at the byte level, which is fragile; Cause — there is no declarative/readable host; Countermeasure — choose a module whose content can be fully restored and wholly rewritten (configuration class/constant class) as the injection host, and append the patch logic to the tail of the host
- A patch must never block the main flow: Symptom — the patch code executes before the host framework is ready, crashing or hanging; Cause — the injection timing is too early (host dependencies not initialized); Countermeasure — poll the host readiness flag (UI framework root/main object available) before executing, protect against all exceptions, silently give up on timeout and fall back to the original behavior
- Troubleshooting order for native crashes on real devices: Symptom — the tombstone/native stack only localizes to the module layer, and the root cause cannot be seen; Cause — runtime protection (pcall/exception catching) cannot save you from a native abort, and the managed exception log is the root cause; Countermeasure — suspect "repackaging format differences" first (compression/alignment/container structure), then suspect the logic; for root-cause evidence, look at the runtime exception log (FATAL EXCEPTION / Unhandled Exception), and do not only look at the native stack
- Channel package ≠ official package: Protocol/behavior conclusions for third-party channel repackaged versions (package name with channel identifier, login via channel SDK) cannot be directly applied to the official package — before analysis, first confirm the package source (package name/signature/channel SDK characteristics)
Experience Library
For the complete collection of practical experience, see [[experience]].