Run x86_64 Linux binaries transparently on arm64 via Box64's dynamic recompilation + kernel binfmt_misc. No wrapper scripts, no box64 prefix — just run the binary directly.
Tools like Android SDK aapt, zipalign, aidl only ship x86_64 binaries. With binfmt_misc registered, the kernel forwards any x86_64 ELF to Box64 automatically — build systems (Gradle, Make, etc.) work without modification.
- arm64 Linux (Debian 12+, Ubuntu 22.04+, or any distro with binfmt_misc support)
- Root/sudo access
- ~200MB disk for Box64 build
sudo apt-get install -y cmake gcc g++ git python3-dev libgles2-mesa-dev libegl-dev libsdl2-dev
cd /tmp
git clone --depth 1 https://github.com/ptitSeb/box64.git
cd box64 && mkdir build && cd build
cmake .. -DARM64=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
make -j$(nproc)
sudo make installVerify:
box64 --version
# Box64 arm64 v0.x.x ...Box64 prints banner/info to stderr by default. Add a global config to silence it:
sudo bash -c 'sed -i "/^# Note that process name/a\\
# Default: suppress verbose output\\
#\\
[*]\\
BOX64_LOG=0\\
" /etc/box64.box64rc'Verify the config was inserted:
head -15 /etc/box64.box64rcYou should see a [*] section with BOX64_LOG=0 near the top.
Alternative: If you prefer not to modify the shipped
box64.box64rc, set the env var in your shell profile:echo 'export BOX64_LOG=0' >> ~/.bashrcThis only works for direct
box64 ./binaryinvocations, not binfmt_misc (the kernel doesn't inherit shell env).
# Mount binfmt_misc filesystem (idempotent)
sudo mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 2>/dev/null
# Register box64.real as the x86_64 interpreter
echo ':box64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/box64.real:POF' \
| sudo tee /proc/sys/fs/binfmt_misc/registerVerify:
cat /proc/sys/fs/binfmt_misc/box64Expected output:
enabled
interpreter /usr/local/bin/box64.real
flags: POF
offset 0
magic 7f454c4602010100000000000000000002003e00
mask ffffffffffffff00fffffffffffffffffeffffff
Flags explained:
P— Preserve argv[0] (the original binary path)O— Open binary fd and pass to interpreterF— Path is the binary itself, not a wrapper
Important: Point to
box64.real(the compiled binary), not a shell wrapper script. The kernel cannot recursively resolve binfmt_misc for script interpreters — a#!/bin/bashwrapper will fail withExec format error.
sudo bash -c 'cat > /usr/lib/binfmt.d/box64.conf << "EOF"
:box64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/box64.real:POF
EOF'On systemd-based systems, systemd-binfmt.service auto-loads files from /usr/lib/binfmt.d/ at boot. No extra service enable needed.
# Grab any x86_64 ELF binary to test
file /path/to/x86_64_binary
# ELF 64-bit LSB pie executable, x86-64, ...
/path/to/x86_64_binary
# Should run via Box64 transparently, no "box64" prefix neededexport ANDROID_SDK_ROOT=/opt/android-sdk
yes | $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager \
--sdk_root=$ANDROID_SDK_ROOT \
"build-tools;35.0.0" "platforms;android-35"
# x86_64 tools now work natively via binfmt:
$ANDROID_SDK_ROOT/build-tools/35.0.0/aapt version
# Android Asset Packaging Tool, v0.2-11948202
$ANDROID_SDK_ROOT/build-tools/35.0.0/zipalign -v 4 input.apk output.apk| Symptom | Cause | Fix |
|---|---|---|
cannot execute binary file: Exec format error |
binfmt not registered or kernel can't find interpreter | Re-run Step 3; verify box64.real exists at the registered path |
Exec format error after registering with a wrapper script |
Kernel can't recursively handle script interpreters in binfmt | Point to box64.real directly, not a shell wrapper |
| Box64 banner/logs in output | BOX64_LOG not set globally |
Add [*] BOX64_LOG=0 to /etc/box64.box64rc (Step 2) |
| binfmt lost after reboot | No persistent config | Create /usr/lib/binfmt.d/box64.conf (Step 4); on non-systemd systems, add the register command to a startup script |
box64.real: error while loading shared libraries |
Missing x86_64 libs or wrong LD_LIBRARY_PATH |
Ensure Box64 can find your x86_64 libs; check with box64.real --help |
Registration fails with File exists |
Already registered | Deregister first: echo -1 | sudo tee /proc/sys/fs/binfmt_misc/box64 |
User runs: ./aapt (x86_64 ELF)
↓
Kernel sees x86_64 magic in ELF header
↓
binfmt_misc matches, looks up "box64" entry
↓
Kernel invokes: /usr/local/bin/box64.real ./aapt [args]
↓
Box64 translates x86_64 instructions → arm64 at runtime
↓
Output is identical to native execution
# Remove binfmt registration
echo -1 | sudo tee /proc/sys/fs/binfmt_misc/box64
# Remove persistent config
sudo rm /usr/lib/binfmt.d/box64.conf
# Uninstall Box64
sudo rm /usr/local/bin/box64 /usr/local/bin/box64.real /usr/lib/libbox64.so
sudo rm -rf /usr/local/share/box64