The DEX Header: Spotting a Dalvik Executable Disguised as a PNG
Le défi
Un échantillon de malware mobile était livré sous le nom icon.png dans les ressources d'une application, mais il ne s'affiche jamais comme une image. Ouvrez-le dans la visionneuse hexadécimale, comparez les premiers octets aux signatures de référence, et indiquez le vrai type de fichier.
Ce que tu vas apprendre
- Recognise the DEX magic bytes 64 65 78 0A ('dex\n') and the version field that follows
- Read leading bytes as ASCII to identify a format by its printable signature
- Explain why Android loads code by its DEX header, not by the file extension
- Distinguish DEX from PNG, ELF, and ZIP using their distinct signatures
- Treat image-named files inside app assets as potential code-hiding spots
Compétences testées
Prérequis
- Basic familiarity with Android apps shipping as APK archives
- Comfort converting hex bytes to their ASCII characters
Comment ça marche
Android apps are distributed as APKs (themselves ZIP archives), and the compiled application code lives inside a .dex file - a Dalvik executable. Every DEX begins with a fixed magic: the bytes 64 65 78 0A spell dex followed by a newline, and the next four bytes (30 33 35 00 here) are the version string 035 terminated by a null. That eight-byte header is how the runtime recognises bytecode it can load.
The file in this challenge is named icon.png, which suggests an image, but a real PNG starts with 89 50 4E 47. The actual bytes are the DEX magic, so the name is a deliberate disguise. Because Android (and any analyst's tooling) identifies executable code by its header rather than its extension, dropping DEX bytes into an icon.png hides the payload in plain sight inside an app's assets while still being loadable.
The reference list deliberately includes look-alike binary formats. 7F 45 4C 46 is ELF (Linux/native binaries), 50 4B 03 04 is the ZIP/APK container, and 89 50 4E 47 is the PNG it pretends to be. Only the 64 65 78 0A signature corresponds to a Dalvik executable.
Erreurs fréquentes
- Believing the .png extension. The name promises an image, but the header is the source of truth and it is not a PNG.
- Confusing DEX with ELF. Both are executable formats, but ELF starts with
7F 45 4C 46('\x7fELF'), not64 65 78 0A. - Reading only the hex and skipping the ASCII. The ASCII gutter spells
dexoutright, which is the fastest tell. - Answering 'APK' or 'ZIP'. The containing app may be an APK/ZIP, but this specific file's header is a bare DEX, not a ZIP (
50 4B 03 04).
Comment s'en protéger
Mobile defenders should classify every asset by its real content and treat code-shaped files in non-code locations as a red flag.
- Scan APK contents with a content-based type detector and flag any DEX magic found outside the expected
classes*.dexentries. - Alert on image-extension files (
.png,.jpg) insideassets/orres/raw/whose magic bytes are executable formats. - Block dynamic code loading from app assets where the platform allows it, and audit any
DexClassLoaderusage. - Maintain a known-good signature baseline so renamed or appended DEX payloads stand out during review.