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.