Work in progress.
craftdex is a tool that turns .smali files into .dex bytecode — written in Zig.
It's a small, low-level project that focuses on understanding and generating the core of Android apps: the classes.dex file.
You don't need Android Studio, JDK, or NDK — just a .smali file and zig.
- Parses a
.smalifile with a custom lexer and parser - Builds internal IR (intermediate representation)
- Supports common instruction formats:
10x,21c,35c - Emits valid
.dexfiles with:- string data
- type/method/proto/class tables
- code sections
- headers, checksums, and signature
It works on real Android devices — the .dex loads and runs.
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out key.pem
openssl pkcs8 -topk8 -inform PEM -outform DER -nocrypt -in key.pem -out key.pk8
openssl req -new -x509 -key key.pem -out key.x509.pem -days 365 -subj "/CN=helloworld"For the next steps you can also use the build_hello.sh script.
zig buildmkdir -p examples/HelloWorld/apk/
zig-out/bin/craftdex dex examples/HelloWorld/HelloActivity.smali -o examples/HelloWorld/apk/classes.dexInstall marco via nimble install and use it to convert XML to some binary XML
nimble install marco
~/.nimble/bin/marco < examples/HelloWorld/AndroidManifest.xml > examples/HelloWorld/apk/AndroidManifest.xmlInstall basia via go install and use it to make an apk archive and sign it
basia -i=examples/HelloWorld/apk/ -o=examples/HelloWorld/hello.apk -c=key.x509.pem -k=key.pk8
marcoandbasiaare planned to be replaced by Zig code.
Plans to evolve craftdex from a single .smali emitter into a full toolchain:
- Refactor internal layout planner and offset assignment
- Make internal IR more expressive and modular
- Clean up
DexEmitterstructure for better testability and reuse
- Extend smali grammar (fields, annotations, register ranges, labels)
- Improve error messages and robustness
- Add support for
.locals,.registers, labels, and branching
- Implement more instruction formats (
22c,3rc,10t, etc.) - Add support for control flow, field access, arrays
- Support exception handling and method attributes
- Replace
marcowith a native Zig binary XML writer - Replace
basiawith a native Zig APK builder and signer - Add support for
resources.arscand proper ZIP layout
- Add support for minimal Android views and layout
- Draw with
SurfaceView - Implement enough bytecode to run a game loop
- Build and launch a Flappy Bird demo
- Support compilation from Zig AIR, like SPIR-V codegen
- Make it possible to write Android apps entirely in Zig and emit
.dexdirectly - Support Android libc (bionic) for cross-compilation
Much more is needed...
- https://formats.kaitai.io/dex/
- https://source.android.com/docs/core/runtime/dalvik-bytecode
- https://source.android.com/docs/core/runtime/constraints
- https://github.com/google/smali
Special thanks to akavel for the inspiration and motivation.
I’ll add more credits as the project evolves. Contributions are welcome — feel free to open issues, send PRs, or just share ideas.
