Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does gdb 'x' command do?

Tags:

c

assembly

gdb

I am reading a book about hacking and it has a chapter about assembly.

Following is my tiny program written in C.

#include <stdio.h>

int main(int argc, char const *argv[])
{
    int i;

    for (i = 0; i < 10; i++) {
        puts("Hello World!");
    }

    return 0;
}

And the following is gdb test:

(gdb) break main
Breakpoint 1 at 0x40050f: file main.c, line 7.
(gdb) run
Breakpoint 1, main (argc=1, argv=0x7fffffffe708) at main.c:7
7       for (i = 0; i < 10; i++) {
(gdb) disassemble main
Dump of assembler code for function main:
   0x0000000000400500 <+0>: push   rbp
   0x0000000000400501 <+1>: mov    rbp,rsp
   0x0000000000400504 <+4>: sub    rsp,0x20
   0x0000000000400508 <+8>: mov    DWORD PTR [rbp-0x14],edi
   0x000000000040050b <+11>:    mov    QWORD PTR [rbp-0x20],rsi
=> 0x000000000040050f <+15>:    mov    DWORD PTR [rbp-0x4],0x0
   0x0000000000400516 <+22>:    jmp    0x400526 <main+38>
   0x0000000000400518 <+24>:    mov    edi,0x4005c4
   0x000000000040051d <+29>:    call   0x4003e0 <puts@plt>
   0x0000000000400522 <+34>:    add    DWORD PTR [rbp-0x4],0x1
   0x0000000000400526 <+38>:    cmp    DWORD PTR [rbp-0x4],0x9
   0x000000000040052a <+42>:    jle    0x400518 <main+24>
   0x000000000040052c <+44>:    mov    eax,0x0
---Type <return> to continue, or q <return> to quit---
   0x0000000000400531 <+49>:    leave  
   0x0000000000400532 <+50>:    ret    
End of assembler dump.

The following part is the things that I don't understand. Please note that $rip is the "instruction pointer" and points to 0x000000000040050f <+15>

(gdb) x/x $rip
0x40050f <main+15>: 0x00fc45c7
(gdb) x/12x $rip
0x40050f <main+15>: 0x00fc45c7  0xeb000000  0x05c4bf0e  0xbee80040
0x40051f <main+31>: 0x83fffffe  0x8301fc45  0x7e09fc7d  0x0000b8ec
0x40052f <main+47>: 0xc3c90000  0x1f0f2e66  0x00000084  0x1f0f0000
(gdb) x/8xb $rip
0x40050f <main+15>: 0xc7    0x45    0xfc    0x00    0x00    0x00    0x00    0xeb
(gdb) x/8xh $rip
0x40050f <main+15>: 0x45c7  0x00fc  0x0000  0xeb00  0xbf0e  0x05c4  0x0040  0xbee8
(gdb) x/8xw $rip
0x40050f <main+15>: 0x00fc45c7  0xeb000000  0x05c4bf0e  0xbee80040
0x40051f <main+31>: 0x83fffffe  0x8301fc45  0x7e09fc7d  0x0000b8ec

First command x/x $rip outputs 0x40050f <main+15>: 0x00fc45c7.

Is it the instruction at 0x40050f? Is 0x00fc45c7 same as mov DWORD PTR [rbp-0x4],0x0 (assembled instruction at 0x40050f)?

Secondly, if it is the instruction, what are those hex numbers from the output of commands x/12x $rip, x/8xw $rip, x/8xh $rip?

like image 960
khajvah Avatar asked Dec 13 '13 16:12

khajvah


1 Answers

As to (1), you got that correct.

As to (2), the x command has up to 3 specifiers: how many objects to print; in which format; and what object size. In all your examples you choose to print as hex (x). As to the first specifier, you ask to print 12, 8, 8 objects.

As to the last specifier in your cases:
x/12x has none, so gdb defaults to assuming you want 4-byte chunks (which GDB calls "words", x86 calls "double words"). Generally, I'd always specify what exactly you want as opposed to falling back on default settings.

x/8xw does the same, for 8 objects, as you explicitly requested dwords now.

(The x command defaults to the last size you used, but the initial default for that on startup is w words)


x/8xh requests half-word sized chunks of 2 bytes, so objects printed in 2 byte chunks. (Half-word relative to GDB's standard 32-bit word size; x86 calls this a "word").

In case you wonder why the concatenation of two neighboring values does not equal what was reported when you printed in dwords, this is because the x86 is a little-endian architecture. What that means is detailed quite well in Erickson's book again - if you look a few pages ahead, he does some calculations you might find helpful. In a nutshell, if you recombine them (2,1) (4,3), ..., you'll see they match.

like image 97
gnometorule Avatar answered Oct 08 '22 00:10

gnometorule