Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,53 @@ Outputs are the collected return values per invocation; useful for bulk string/c

A recurring Android malware pattern is a **small Java stub + stripped JNI loader + high-entropy asset**. If the APK contains a native library with one abnormally large JNI export, encrypted strings, and an `assets/` blob that doesn't match its file extension, you can usually recover the next stage **without executing the sample**.<sup>[[7]](#references)</sup>

#### Repair hostile APK and DEX metadata before decompiling

Treat an APK as an **adversarial ZIP**, not as a trustworthy filesystem tree. List members before extraction and reject absolute paths, normalized paths that escape the output directory, and file/directory collisions. A sample can remain installable while crafted names make extractors omit entries, crash, or write outside the analysis directory.<sup>[[8]](#references)[[11]](#references)</sup>

A DEX parser error also does **not** prove that the bytecode is encrypted. Compare the header and `map_list` against the actual layout: section sizes must fit inside `file_size`, fixed-width tables must be aligned, indexes must stay within their target tables, and `string_data`, `class_data`, and `code_item` references must decode consistently. A packer can swap map type labels or point table entries at valid-but-wrong data so a disassembler follows the attacker's metadata instead of the real structures.<sup>[[9]](#references)[[11]](#references)</sup>

Useful repairs on a disposable copy are:<sup>[[9]](#references)[[11]](#references)</sup>

- Rebuild incorrect map entries from structurally valid candidate sections instead of trusting the declared type/offset pair.
- Replace a junk `code_item.debug_info_off` with `0` when debugging data is nonessential; `0` explicitly means that no debug information exists.
- Parse only through the DEX header's declared `file_size`, but carve any trailing overlay for separate analysis; triage invalid references in unreachable methods separately from reachable code.
- After patching offsets or instructions, update `file_size`/map values as needed and recompute the DEX SHA-1 signature and Adler-32 checksum before reopening it in strict tools.

#### Recover indexed native string oracles and encrypted assets

When most Java strings are calls such as `nativeGetStr(int)`, enumerate the integer call sites and reverse the single JNI routine as a **string oracle**.<sup>[[8]](#references)[[11]](#references)</sup> In a stripped native library, the fixed AES S-box and Rcon tables identify AES; a nonce/counter block plus an incrementing counter distinguishes CTR-like use from ECB/CBC.<sup>[[11]](#references)</sup> Preserve the exact counter layout and endianness when reimplementing it, then iterate all valid indexes to recover configuration, asset names, permission strings, and payload parameters in bulk.<sup>[[11]](#references)</sup>

Apply recovered cipher parameters to high-entropy, extensionless assets offline and validate the plaintext independently rather than trusting a successful decrypt. For an embedded APK, check ZIP integrity and its signing metadata:<sup>[[8]](#references)[[11]](#references)</sup>

```bash
file stage2.bin
unzip -t stage2.bin
apksigner verify --verbose --print-certs stage2.bin
```

#### Reconstruct DPT-Shell method bodies

DPT-Shell hollows DEX method implementations and reconstructs them at runtime.<sup>[[10]](#references)</sup> Strong fingerprints are a small `ProxyApplication`/`JniBridge` stub, `assets/OoooooOooo`, and a native loader below `assets/vwwwwwvwww/` for each ABI.<sup>[[10]](#references)[[11]](#references)</sup> Repair deceptive DEX table offsets **before** resolving method indexes; otherwise valid code-store records will be mapped to the wrong methods.<sup>[[11]](#references)</sup>

The upstream writer and runtime parser define the code store as little-endian records:<sup>[[10]](#references)</sup>

```text
u16 version
u16 dex_count
u32 dex_section_offset[dex_count]
for each DEX section:
u16 method_count
repeat method_count times:
u32 method_idx
u32 instruction_size_bytes
u8 instructions[instruction_size_bytes]
```

For each DEX section, use `method_idx` as an index into that file's `method_ids`, locate the method's `code_item`, and restore its `insns[]` bytes.<sup>[[10]](#references)[[11]](#references)</sup> Keep DEX instruction units in mind: `code_item.insns_size` counts 16-bit code units whereas the external store records a byte length. Validate every offset/length against the store boundary, then regenerate the DEX signature/checksum after patching.<sup>[[9]](#references)[[10]](#references)</sup>

Also inspect nominal image resources instead of assuming they are decoration. For PNGs, concatenate `IDAT` chunks in file order, decompress the zlib stream, and compare its expected scanline length with the actual output; unexplained trailing data or additional streams can be another code/payload carrier.<sup>[[11]](#references)</sup>

#### OLLVM-style native XOR string recovery

A common native pattern is a one-time init block that decrypts strings **in place** byte-by-byte:
Expand Down Expand Up @@ -195,5 +242,9 @@ After decrypting a staged container:
- [5] [Deobfuscating Android Apps with Androidmeda: A Smarter Way to Read Obfuscated Code](https://www.mobile-hacker.com/2025/07/22/deobfuscating-android-apps-with-androidmeda-a-smarter-way-to-read-obfuscated-code/)
- [6] [Androidmeda source code](https://github.com/In3tinct/Androidmeda)
- [7] [Fake RTO Challan Checker Part 2: Cracking the Payload, Mapping the Operator, and Why This Is Worse Than I Thought](https://medium.com/@singhbkn07/fake-rto-challan-checker-part-2-cracking-the-payload-mapping-the-operator-and-why-this-is-3eb78e512d7f)
- [8] [Fake mParivahan APK — original malware analysis and sample research](https://github.com/0x6773/mparivahan-apk-scam)
- [9] [Android Open Source Project — Dalvik executable format](https://source.android.com/docs/core/runtime/dex-format)
- [10] [dpt-shell — Android DEX protection shell source](https://github.com/luoyesiqiu/dpt-shell)
- [11] [78 Victims, One Lazy Key, and a Firebase Named After India’s Ruling Party](https://medium.com/@singhbkn07/78-victims-one-lazy-key-and-a-firebase-named-after-indias-ruling-party-62cf0ad0380e)

{{#include ../../banners/hacktricks-training.md}}