Talking to GDB

June 2, 2017

How goes GSoC? Well.. the gdbserver is at the point where it can have a basic conversation with the r2 client. Not really much debugging going on, just reading register and memory values. Which is enough to let r2 work its disassemly magic. Something like this -

Starting r2’s gdbserver on one terminal …

$ r2 -

[0x00000000]> =g 8000 /bin/ls
= attach 6 6
Process with PID 28220 started...
File dbg:///usr/bin/ls reopened in read-write mode
= attach 28220 28220
gdbserver started on port: 8000, file: /bin/ls

… and then connecting to it from another terminal.

$ r2 -d gdb://localhost:8000

= attach 6 6
[0x7f728445fd80]> pd 5
            ;-- rip:
            0x7f728445fd80      4889e7          mov rdi, rsp
            0x7f728445fd83      e8e83d0000      call 0x7f7284463b70
            0x7f728445fd88      4989c4          mov r12, rax
            0x7f728445fd8b      8b05c71e2200    mov eax, dword [0x7f7284681c58]
            0x7f728445fd91      5a              pop rdx
[0x7f728445fd80]>

Off the bat, a few really obvious problems exist. Analysis commands like aa are really slow. And an obvious solution to this problem exists too - caching I/O to prevent redundant memory reads. This problem becomes apparent when you look at a PCAP of an r2 remote debugging session.. multiple reads of the same area of the target’s memory. The key observation here is that values in memory are not going to change when the target is not running, or has stopped at a breakpoint. So once memory is read from a particular location, it can be cached in a buffer inside the client. This buffer can then be invalidated once the target runs. Or there could be finer caching mechanisms put into place… There was an attempt at this some time in the past, and the remnants of that attempt can be seen in the GDB io plugin. Anyway, this is one of the things I’ll be working on during GSoC. Not right away though. Because I have more pressing challenges to overcome.

We can’t yet talk to GDB. Not yet. Of course, we don’t yet handle all the packets defined by the GDB remote protocol. And increasing the number that we do handle is what I’m working on right now. Though I’m being slowed down by the fact that the official GDB remote protocol documentation is not really complete, and nor are there many resources online discussing this. Or maybe I’m not looking in the right places. Well, no worries. I’m currently spending time going through PCAPs of debugging sessions of GDB with gdbserver, r2, Qemu, and Bochs, to figure out how the different packets work. The GDB source code helps a bit too, especially when you find things that even they have as partially implemented, TODO ideas. Plus archives of conversations like this one about how GDB usually ignores error codes, which I found after quite some time spent hunting down the significance of said error codes. Progress is slow, but this is only for the initial few days, since I’ve already figured out stuff about packets whose documentation I haven’t been able to find.

And you might not believe this, given the tone of the last paragraph, but I’m having quite a lot of fun.