Compiling busybox for an ARM processor (Android)

Submitted by olaf on 2015-01-19

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.

Hello world

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 gcc-arm-linux-gnueabi and libc-dev-armel-cross

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

The option -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, e.g. $NDK/toolchains/arm-linux-androideabi-4.8 and choose a platform to build for, e.g. $NDK/platforms/android-3/arch-arm.

Now building is done by

$TOOLCHAIN/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc --sysroot=$PLATFORM hello.c -o hello

Option --sysroot is needed, so the compiler and linker can find the necessary header files and libraries. By using the Android NDK instead of gcc-arm-linux-gnueabi, you can avoid static linking and, as a consequence of this, the executables are much smaller.

Busybox

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, there is menuconfig, which uses the Linux kernel configuration system.

To have a simple default configuration, start make menuconfig and navigate to Busybox Settings -> Build Options. Activate Build BusyBox as a static binary and set Cross Compiler prefix to arm-linux-gnueabi-. That’s it, exit and save configuration.

make busybox

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

Android NDK

Building Busybox with Android NDK is more complicated, because the NDK doesn’t support everything needed by Busybox. You can start with make android_ndk_defconfig, which provides some basic settings. After adjusting Cross Compiler prefix and Path to sysroot, you can start compiling Busybox.

But you will still run into compile errors and need to investigate and adjust the configuration. The first one I encountered was

CC coreutils/touch.o
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[1]: ** [coreutils/touch.o] Error 1
make: **
[coreutils] Error 2

This one can be fixed by disabling Coreutils -> touch -> Add 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.

1 Comment

Langra Tyagi on 2015-08-23 09:28:00 +0200
+1 for introducing static compilation before mentioning Android NDK. Very helpful overall too.

Post a comment

All comments are held for moderation; Markdown and basic HTML formatting accepted. If you want to stay anonymous, leave name, e-mail and website empty.