Timeless debugging - qira

quira is a great tool. There are other timeless debuggers that are very powerful, such as rr from Radare2 or PANDA. But they lack a friendly GUI. qira has a GUI and is very useful for tracing simple programs. And it features IDA integration! But there are very few examples out there on how to use it, so I am adding one here.

Setting qira up can be frustrating, especially with the PIN tool, as some of the build scripts depend on older compilers. At the time of this writing there is a pull request on github to update the QEMU it uses to v3.1.0. So I think it's useful to have instructions for getting it set up on a clean Ubuntu 19.04 installation, using QEMU 3.1.0 and setting up the PIN tool as well.

sudo apt install git curl python python-virtualenv python-dev build-essential pkg-config zlib1g-dev libglib2.0-dev libpixman-1-dev libcapstone-dev debootstrap debian-archive-keyring 
git clone https://github.com/geohot/qira.git
cd qira/tracers
nano qemu_build.sh

and there change two lines

git clone https://github.com/geohot/qemu.git --depth 1 --branch qira

to

git clone https://github.com/geohot/qemu.git --depth 1 --branch v3.1.0-qira

and

./configure --target-list=i386-linux-user,x86_64-linux-user,arm-linux-user,ppc-linux-user,aarch64-linux-user,mips-linux-user,mipsel-linux-user --enable-tcg-interpreter --enable-debug-tcg --cpu=unknown --python=python

to

./configure --target-list=i386-linux-user,x86_64-linux-user,arm-linux-user,ppc-linux-user,aarch64-linux-user,mips-linux-user,mipsel-linux-user --enable-tcg-interpreter --enable-debug-tcg --enable-capstone --python=python

then, the install.sh script should be able to build QEMU and qira.

$ ./install.sh 
[.....snip.....]
tests pass
making systemwide symlink
***************************************
  Thanks for installing QIRA
  Check out README for more info
  Or just dive in with 'qira /bin/ls'
  And point Chrome to localhost:3002
    ~geohot


sometimes this build script does not finish and ends with a curl error.

curl: (7) Failed to connect to localhost port 3002: Connection refused

This can be fixed by running qira manually and then running the install script once more.

$ ./qira /bin/ls
$ ./install.sh

and the PIN tools can be built too. First, lets install the right compiler:

sudo gedit /etc/apt/sources.list

and add

deb http://dk.archive.ubuntu.com/ubuntu/ xenial main
deb http://dk.archive.ubuntu.com/ubuntu/ xenial universe

to the list. Then

sudo apt update

The PIN tracer should now build. However, I made a patch to fix an error I had, which you may want to apply. When executing qira --pin /bin/ls I got the following error:

E: qirapin.cpp:679: Cannot use IARG_MEMORYWRITE_SIZE on non-standard memory access of instruction at 0x7f9d7c8207b8: xsavec ptr [rsp+0x40]

There is already a fix for a similar situation in qirapin.cpp:

  if(INS_Mnemonic(ins) == "XSAVE") {
  // Avoids "Cannot use IARG_MEMORYWRITE_SIZE on non-standard memory access of instruction at 0xfoo: xsave ptr [rsp]"
  // TODO: Bitch at the PIN folks.
  return;
 }

So I just added one more:

  if(INS_Mnemonic(ins) == "XSAVEC") {
  // Avoids "Cannot use IARG_MEMORYWRITE_SIZE on non-standard memory access of instruction at 0xfoo: xsave ptr [rsp]"
  // TODO: Bitch at the PIN folks.
  return;
 }

Now.

cd tracers/
$ ./pin_build.sh 

Now qira can run using either QEMU or PIN.

The PIN tracer can fail with an error message:

A: Source/pin/injector_nonmac/auxvector.cpp: CopyAux: 291: unexpected AUX VEC type 26

This can sometimes be mitigated by changing qira_program.py to add the ifeellucky option:

change

eargs = [self.pinbinary, "-injection", "child", "-t", self.pintool, "--", self.program]+self.args

to

eargs = [self.pinbinary, "-ifeellucky","-injection", "child", "-t", self.pintool, "--", self.program]+self.args

And there seems to be a problem with later versions of Ubuntu in displaying the PIN trace in the GUI. I am sure this will be addressed sooner or later....

Anyway, we can now trace the executable. The executable I am tracing here, needed some patching to run under QEMU, because it's vulnerable to a timing anti-debugging technique as described here:

Anti-Debugging and Anti-VM using timing

After the patch, the executable can be executed by qira:

$ qira ./keygenme

So just a simple serial number check. This executable features a number of techniques of making the reverser's life hard. Aside from the timing attack descibed above, there is also some stack pointer manipulation that IDA cannot figure out and some other stuff that makes IDA think code is data and vice versa. For example,

Here, there is a call to 8048F86+1 but IDA thinks that there is code already at 8048F86. So it is necessary to fix that up by first undefining the code at 8048F86 and then defining code at 8048F87.

Nothing earth shattering here in principle, but already there is another one. And so it's very laborious or even unfeasible to fix all these up before we can then have a look at the serial number generation algorithm. It would be nice to only have to fix the ones involved in the serial number generation routine. Since this program basically only does a serial number generation check, it turns out we still have to fix almost all the code, but for a more complex program having to fix up only the bare minimum will certainly increase productivity. Lets see how qira can help. The build for quira also builds IDA plugins, so make sure they are installed.

The red arrows show a timeline of execution. There is a number 1 at the top indicating instruction number 1 and a corresponding 1917 at the bottom indicating the last instruction. For this example, that is already a very nice result, because even without IDA we could just brutishly trace through the assembly to try and find/examine the serial check routine. But we are here to show off some of the features of qira.

The arrow on the left points to the first instruction in the execution trace. The arrow to the right shows how the instructions are automatically shown in IDA (if IDA has decoded them right - more on that later). The timeline gets progressively more green and then goes back to black. The more green the timeline gets, the deeper into function calls the executable is at that point. Also, the line numbers are indented in the instruction trace window to indicate the same thing.

And as we trace through the instructions one by one (just using the down arrow key) at some point we reach one of these instructions that IDA misidentified. So this is the first one we have to fix up as detailed above. Of course, sometimes IDA does not identify instructions at all:

But now that we have the execution trace we can be pretty confident in defining those instructions. qira also marks all occurrences of the current instuction address in the time line using red bars. The current occurrence is also marked as blue (indicated by arrow).

This is a very useful visualization. In the example executable trace the name had 7 letters, so this may be where it gets processed. In fact, just stepping a little further:

One can see that the first letter gets iterated over twice, the second letter 3 times, etc. This is all very useful information when it comes to reversing the algorithm. Finally, There is the sudden step back in the time line from green to almost black:

One might suspect a return from a deep-recursive serial check algorithm and in the example executable that was actually the case, presenting the examiner with a ready-computed serial number for the test name.