This is a quick note on how to run x86 (32- or 64-bits) binaries on an Android phone (with an ARM64 CPU).
I’m using Termux as my terminal. It has packages for QEMU user (
qemu-user-i386
and
qemu-user-x86-64
among others), which will run x86 binaries on an emulated x86 CPU. This alone is not enough though:
❯ lscpu | head -n2
Architecture: aarch64
CPU op-mode(s): 32-bit, 64-bit
❯ readelf -h ./test | grep '\(Class\|Machine\):'
Class: ELF32
Machine: Intel 80386
❯ qemu-i386 ./test
qemu-i386: Could not open '/lib/ld-linux.so.2': No such file or directory
QEMU needs an x86 loader (as specified in the
.interp section), which understandably isn’t available on Android:
❯ objdump -j .interp -s ./test
./test: file format elf32-little
Contents of section .interp:
8048154 2f6c6962 2f6c642d 6c696e75 782e736f /lib/ld-linux.so
8048164 2e3200 .2.
Termux doesn’t package random loaders for foreign architectures, but it has
PRoot, a chroot-like trick (based on
LD_PRELOAD
) that lets us install a basic Debian “container”:
❯ pkg install proot proot-distro
❯ proot-distro install debian
❯ cp ./test ~/../usr/var/lib/proot-distro/installed-rootfs/debian/home/
❯ proot-distro login debian
$ dpkg --add-architecture i386
$ apt update
$ apt install libc6:i386
$ qemu-i386 /home/test
Hello, World!
It works now!
We can even debug the x86 program with GDB multiarch:
$ qemu-i386 -g 1234 /home/test
Now in a separate Termux session:
❯ proot-distro login debian
$ apt install gdb-multiarch
$ gdb-multiarch /home/test
(gdb)$ target remote localhost:1234
(gdb)$ # debug shit
It’s not much but not gonna lie, it feels great. :D