Compiling busybox for an ARM processor (Android)
Currently, I am looking at Android exploits to gain root access. Most of the instructions out there, are about downloading some closed source binaries. Since this is a very sensitive topic, I like to see the source code and at least be able to build the programs myself.
To learn how to do this, I start with building a hello world programm
for my phone on a Ubuntu system. First step is to download a suitable
compiler and toolchain, which is found in the packages
apt-get install gcc-arm-linux-gnueabi libc-dev-armel-cross
Building hello world is as easily done by just
arm-linux-gnueabi-gcc -static hello.c -o hello
-static is necessary, because an Android system doesn’t
include the GNU libraries, but has its own bionic libc. To test the
resulting binary, you must copy it to the phone with
adb push hello /data/local/tmp
and call it with
adb shell /data/local/tmp/hello Hello, world!
Instead of the Ubuntu cross compiler packages, you can also use the
Android NDK. After
installing, you can start building. You must pick a toolchain,
$NDK/toolchains/arm-linux-androideabi-4.8 and choose a platform
to build for, e.g.
Now building is done by
$TOOLCHAIN/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc --sysroot=$PLATFORM hello.c -o hello
--sysroot is needed, so the compiler and linker can find the
necessary header files and libraries. By using the Android NDK instead
gcc-arm-linux-gnueabi, you can avoid static linking and, as a
consequence of this, the executables are much smaller.
Now, on to something more useful, busybox for Android. Busybox’s source is available at www.busybox.net. Just in case, you don’t care about building it yourself, you can also download a prebuilt Busybox executable at /download/binaries.
make help shows a list of make targets available. Among others,
menuconfig, which uses the Linux kernel configuration
To have a simple default configuration, start
make menuconfig and
Busybox Settings ->
Build Options. Activate
BusyBox as a static binary and set
Cross Compiler prefix to
arm-linux-gnueabi-. That’s it, exit and save configuration.
starts building a statically linked busybox executable. Testing busybox is the same as testing our hello world program. Put it on the phone or tablet
adb push busybox /data/local/tmp
and call it with
adb shell /data/local/tmp/busybox
If everything went properly, you will see a copyright, license and usage notice
BusyBox v1.22.1 (2015-01-20 17:55:34 CET) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2012. Licensed under GPLv2. See source distribution for detailed copyright notices.
Usage: busybox [function [arguments]…]
or: busybox –list[-full]
or: busybox –install [-s] [DIR]
or: function [arguments]…
BusyBox is a multi-call binary that combines many common Unix utilities into a single executable. Most people will create a link to busybox for each function they wish to use and BusyBox will act like whatever it was invoked as.
Currently defined functions:
[, [[, acpid, add-shell, addgroup, adduser, adjtimex, arp, arping, ash, awk, base64, basename, beep, blkid, blockdev, bootchartd, brctl, bunzip2, bzcat, bzip2, cal, cat, catv, chat, chattr, chgrp, chmod, chown, chpasswd, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm,
unexpand, uniq, unix2dos, unlzma, unlzop, unxz, unzip, uptime, users, usleep, uudecode, uuencode, vconfig, vi, vlock, volname, wall, watch, watchdog, wc, wget, which, who, whoami, whois, xargs, xz, xzcat, yes, zcat, zcip
Building Busybox with Android NDK is more complicated, because the NDK
doesn’t support everything needed by Busybox. You can start with
android_ndk_defconfig, which provides some basic settings. After
Cross Compiler prefix and
Path to sysroot, you can start
But you will still run into compile errors and need to investigate and adjust the configuration. The first one I encountered was
coreutils/touch.c: In function ‘touch_main’:
coreutils/touch.c:171:21: error: ‘lutimes’ undeclared (first use in this function)
(opts & OPT_h) ? lutimes :
coreutils/touch.c:171:21: note: each undeclared identifier is reported only once for each function it appears in
make: ** [coreutils/touch.o] Error 1
make: ** [coreutils] Error 2
This one can be fixed by disabling
support for -h. But this is not the last one. I guess, by disabling
various applets or adding appropriate definitions, you will finally be
able to build Busybox with the NDK. If size matters for your
environment or you want a dynamically linked Busybox, you might be
willing to go this extra mile(s).
For me this isn’t important right now, so I will be content with Busybox built by the GNU toolchain.