PDA

View Full Version : Debugging ARM code snippets in IDA Pro 5.6 using QEMU emulator


Hex Blog
January 8th, 2010, 14:17
Introduction

IDA Pro 5.6 has a new feature: automatic running of the QEMU emulator. It can be used to debug small code snippets directly from the database.In this tutorial we will show how to dynamically run code that can be difficult to analyze statically.

Target

As an example we will use shellcode from the article "Alphanumeric RISC ARM Shellcode" ("http://www.phrack.com/issues.html?issue=66&id=12") in Phrack 66.It is self-modifying and because of alphanumeric limitation can be quite hard to undestand. So we will use the debugging feature to decode it.

The sample code is at the bottom of the article but here it is repeated:

Code:
80AR80AR80AR80AR80AR80AR80AR80AR80AR80AR80AR80AR80AR80AR80AR80AR80AR80AR
80AR80AR80AR80AR80AR80AR80AR80AR80AR00OB00OR00SU00SE9PSB9PSR0pMB80SBcACP
daDPqAGYyPDReaOPeaFPeaFPeaFPeaFPeaFPeaFPd0FU803R9pCRPP7R0P5BcPFE6PCBePFE
BP3BlP5RYPFUVP3RAP5RWPFUXpFUx0GRcaFPaP7RAP5BIPFE8p4B0PMRGA5X9pWRAAAO8P4B
gaOP000QxFd0i8QCa129ATQC61BTQC0119OBQCA169OCQCa02800271execme22727
Copy this text to a new text file, remove all line breaks (i.e. make it a single long line) and save. Then load it into IDA.

Loading binary files into IDA

IDA displays the following dialog when it doesn't recognize the file format (as in this case):

http://www.hexblog.com/ida_pro/pix/qemu_load.gif
Since we know that the code is for ARM processor, choose ARM in the "Processor type" dropdown and click Set. Then click OK. The following dialog appears:

http://www.hexblog.com/ida_pro/pix/qemu_ram.gif
When you analyze a real firmware dumped from address 0, these settings are good.However, since our shellcode is not address-dependent, we can choose any address. For example, enter 0x10000 in "ROM start address" and "Loading address" fields.

http://www.hexblog.com/ida_pro/pix/qemu_disass1.gif
IDA doesn't know anything about this file so it didn't create any code. Press C to start disassembly.

http://www.hexblog.com/ida_pro/pix/qemu_disass2.gif
Configuring QEMU

Before starting debug session, we need to set up automatic running of QEMU.


Download a recent version of QEMU with ARM support (e.g. from http://homepage3.nifty.com/takeda-toshiya/qemu/index.html). If qemu-system-arm.exe is in a subdirectory, move it next to qemu.exe and all DLLs.
Note: if you're running Windows 7 or Vista, it's recommended to use QEMU 0.11 or 0.10.50 ("Snapshot" on Takeda Toshiya's page), as the older versions listen for GDB connections only over IPv6 and IDA can't connect to it.
Edit cfg/gdb_arch.cfg and change "set QEMUPATH" line to point to the directory where you unpacked QEMU. Change "set QEMUFLAGS" if you're using an older version.
http://www.hexblog.com/ida_pro/pix/qemu_cfg.gif

In IDA, go to Debug-Debugger options..., Set specific options.
Enable "Run a program before starting debugging".
Click "Choose a configuration". Choose Versatile or Integrator board. The command line and Initial SP fields will be filled in.
http://www.hexblog.com/ida_pro/pix/qemu_options.gif

Memory map will be filled from the config file too. You can edit it by clicking the "Memory map" button, or from the Debugger-Manual memory regions menu item.
Now on every start of debugging session QEMU will be started automatically.

Executing the code

By default, initial execution point is the entry point of the database. If you want to execute some other part of it, there are two ways:


Select the code range that you want to execute, or
Rename starting point ENTRY and ending point EXIT (convention similar to Bochs debugger)
In our case we do want to start at the entry point so we don't need to do anything. If you press F9 now, IDA will write the database contents to an ELF file (database.elfimg) and start QEMU, passing the ELF file name as the "kernel" parameter. QEMU will load it, and stop at the initial point.

http://www.hexblog.com/ida_pro/pix/qemu_start.gif
Now you can step through the code and inspect what it does. Most of the instructions "just work", however, there is a syscall at 0x0010118:
ROM:00010118 SVCMI 0x414141
Since the QEMU configuration we use is "bare metal", without any operating system, this syscall won't be handled. So we need to skip it.

Navigate to 010118 and press F4 (Run to cursor). Notice that the code was changed (patched by preceding instructions):
http://www.hexblog.com/ida_pro/pix/qemu_syscall.gif
(Incidentally, 0x9F0002 is sys_cacheflush for ARM Linux.)
Right-click next line (0001011C) and choose Set IP.
Press F7 three times. Once you're on BXPL R6 line, IDA will detect the mode switch and add a change point to Thumb code:
http://www.hexblog.com/ida_pro/pix/qemu_bx.gif
However, the following, previously existing code will (incorrectly) stay in ARM mode. We need to fix that.
Go to 01012C and press U (Undefine).
Press Alt-G (Change Segment Register Value) and set value of T to 1. The erroneous CODE32 will disappear.
Go back to 00010128 and press C (Make code). Nice Thumb code will appear:
http://www.hexblog.com/ida_pro/pix/qemu_thumb.gif

In Thumb code, there is another syscall at 00010152. If you trace or run until it, you can see that R7 becomes 0xB (sys_execve) and R0 points to 00010156.If you undefine code at 00010156 and make it a string ('A' key), it will look like following:
http://www.hexblog.com/ida_pro/pix/qemu_thumb2.gif
Thus we can conclude that the shellcode tries to execute a file at the path "/execme".

Hint: if the code you're investigating has many syscalls and you don't want to handle them one by one, put a breakpoint at the address 0000000C (ARM's vector for syscalls). Return address will be in LR.</b>Saving results to database


If you want to keep the modified code or data for later analysis, you'll need to copy it to the database. For that:


Edit segment attributes (Alt-S) and make sure that segments with the data you need have the "Loader segment" attribute set.
http://www.hexblog.com/ida_pro/pix/qemu_segm.gif

Choose Debugger-Take memory snapshot and answer "Loader segments".Note: if you answer "All segments", IDA will try to read the whole RAM segment (usually 128M) which can take a VERY long time.
Now you can stop the debugging and inspect the new data.
Note: this will update your database with the new data and discard the old. Repeated execution probably will not be correct.
This concludes our short tutorial. You can get an offline PDF version with a slightly more complex example and more background info here ("http://www.hex-rays.com/idapro/debugger/qemu_debugger_primer.pdf").

Happy debugging!
Please send any comments or questions to support@hex-rays.com ("support@hex-rays.com")



http://hexblog.com/2010/01/debugging_arm_code_snippets_in_1.html