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
.smali
file with a custom lexer and parser - Builds internal IR (intermediate representation)
- Supports common instruction formats:
10x
,21c
,35c
- Emits valid
.dex
files 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 build
mkdir -p examples/HelloWorld/apk/
zig-out/bin/craftdex dex examples/HelloWorld/HelloActivity.smali -o examples/HelloWorld/apk/classes.dex
Install 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.xml
Install 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
marco
andbasia
are 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
DexEmitter
structure 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
marco
with a native Zig binary XML writer - Replace
basia
with a native Zig APK builder and signer - Add support for
resources.arsc
and 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
.dex
directly - 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.