Setting up an ARMEL Reverse Engineering / Debug Lab in QEMU

I recently came across a tutorial on ARM Reverse Engineering https://azeria-labs.com/writing-arm-assembly-part-1/.

However, this tutorial seems to recommend using a Raspberry Pi for following along with the tutorial. I decided I wanted to be able to work through the tutorial using a virtual machine, so I built a QEMU VM of the ARMEL architecture. This is the same architecture that the Raspberry Pi is based off of. I went with Debian for ARMEL because its the OS I'm most familiar with. After the operating system is installed, I install tools like GDB and GEF for debugging / reverse engineering.

GEF is a plugin for GDB specifically built for reverse engineering and exploit development. From https://github.com/hugsy/gef.git:

GEF is a kick-ass set of commands for X86, ARM, MIPS, PowerPC and SPARC to make GDB cool again for exploit dev. It is aimed to be used mostly by exploiters and reverse-engineers, to provide additional features to GDB using the Python API to assist during the process of dynamic analysis and exploit development.

Most of the QEMU setup instructions came from this gist, but are provided again here for completeness. I've also streamlined / edited many of the commands.

If you want to actually run Raspian on QEMU, I recommend this guide.

Creating the QEMU VM

Create a disk image:

$ qemu-img create -f qcow2 armdisk.img 12G

Download VMLinuz and Initrd.gz for installation:

$ wget -r --no-parent -nH --cut-dirs=9 -R index.html* http://ftp.
.org/debian/dists/wheezy/main/installer-armel/current/images/versatile/netboot/

Boot into install mode:

$ qemu-system-arm -m 1024M -M versatilepb -kernel vmlinuz-3.2.0-4-versatile -initrd initrd.gz -append "root=/dev/ram" -hda armdisk.img -no-reboot

When installing the operating system, ensure that you DO NOT select LVM when partitioning the disk. Simply use the first partitioning option, which is something along the lines of Use the entire disk.

Extract the kernel and initrd:

$ sudo modprobe nbd max_part=16
$ sudo qemu-nbd -c /dev/nbd0 armdisk.img
$ mkdir ~/qemu-mounted
$ sudo mount /dev/nbd0p1 ~/qemu-mounted
$ mkdir after-copy

$ cp ~/qemu-mounted/boot/* after-copy/

$ sudo umount ~/qemu-mounted
$ sudo qemu-nbd -d /dev/nbd0

source: https://gist.github.com/Liryna/10710751

Fire up the VM with the proper parammeters:

$ qemu-system-arm -M versatilepb -m 1024M  -kernel after-copy/vmlinuz-3.2.0-4-versatile -initrd after-copy/initrd.img-3.2.0-4-versatile -hda armdisk.img -append "root=/dev/sda1" -redir tcp:5555::22 -nographic

Setting up RE Tools

Wait a few minutes for the VM to boot up, then SSH into the VM on localhost port 5555 using the following command:

$ ssh -p 5555 user@localhost

Once inside the VM, change to the root user:

$ su

Then run the following to install a few prerequisite packages:

# apt-get install git build-essential python-dev

A brief rundown on what each of the dependencies is for: git - cloning GEF build-essential - the build tools we'll need to build GDB * python-dev - headers necessary for building GDB with python support.

Next grab a recent version of GDB, build, and install:

# wget http://ftp.gnu.org/gnu/gdb/gdb-7.12.tar.gz
# tar xzf gdb-7.12.tar.gz
# cd gdb-7.12
# ./configure --with-python
# make
# make install
# ln -s /usr/local/bin/gdb /usr/bin/gdb
# exit

Note that the build process will take a long time (2-4 hours) under QEMU. We need to install a recent version of GDB because GEF does not support any version of GDB before 7.x. See this issue for more information.

Next we want to install GDB-GEF:

$ git clone https://github.com/hugsy/gef.git ~/gef
$ echo "source ~/gef/gef.git" >> ~/.gdbinit

If at this point you run gdb, you will get a SEGFAULT.

Lastly, we need to set readline_comapt = true. Add the following to ~/.gef.rc:

[gef]
readline_compat = True

As per this document, this will prevent GEF from segfaulting upon launch of GDB.

At this point you should be able to use GEF with GDB on an ARMEL VM under QEMU.

You might also enjoy reading: