The DEX Header: Spotting a Dalvik Executable Disguised as a PNG
The challenge
A mobile malware sample shipped as icon.png inside an app's assets, but it never renders as an image. Open it in the hex viewer, compare the leading bytes to the reference signatures, and type the real file type.
What you'll learn
- 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
Skills tested
Prerequisites
- Basic familiarity with Android apps shipping as APK archives
- Comfort converting hex bytes to their ASCII characters
How it works
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.
Common mistakes
- 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).
How to defend against it
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.