gdb'x'命令有什么作用?

时间:2013-12-13 16:05:03

标签: c assembly gdb

我正在阅读关于黑客攻击的book,它有一章关于装配。

以下是我用C编写的小程序。

#include <stdio.h>

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

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

    return 0;
}

以下是gdb测试:

(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.

以下部分是我不理解的事情。 请注意$ rip是“指令指针”并指向 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

第一个命令x/x $rip输出0x40050f <main+15>: 0x00fc45c7

是0x40050f的指令吗? 0x00fc45c7mov DWORD PTR [rbp-0x4],0x0(0x40050f处的汇编指令)相同吗?

其次,如果是指令,那么命令x/12x $ripx/8xw $ripx/8xh $rip的输出中的那些十六进制数是什么?

2 个答案:

答案 0 :(得分:8)

至于(1),你说得对。

对于(2),x命令最多有3个说明符:要打印的对象数量;以哪种格式;什么对象大小。在所有示例中,您选择以十六进制(x)打印。对于第一个说明符,您要求打印12,8,8个对象。

关于你案件中的最后一个说明者:
x / 12x没有,所以gdb默认假设你想要双字,也就是4字节块。请注意,您发现双字有时定义不同,但在intel x86汇编/ gdb中,它是4个字节。一般来说,我总是指定你想要什么,而不是回到默认设置。

对于8个对象,x / 8xw也是如此,就像你现在明确请求dwords一样。

x / 8xh请求半字大小的字节块,因此以2字节块的形式打印对象。如果你想知道为什么两个相邻值的串联不等于用dwords打印时报告的内容,这是因为x86是一个小端架构。这意味着在erickson的书中再次详细说明 - 如果你看几页,他会做一些你可能会觉得有用的计算。简而言之,如果你重新组合它们(2,1)(4,3),......,你会发现它们匹配。

答案 1 :(得分:7)

(gdb) help x
Examine memory: x/FMT ADDRESS.
ADDRESS is an expression for the memory address to examine.
FMT is a repeat count followed by a format letter and a size letter.
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
  t(binary), f(float), a(address), i(instruction), c(char) and s(string),
  T(OSType), A(floating point values in hex).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
The specified number of objects of the specified size are printed
according to the format.

Defaults for format and size letters are those previously used.
Default count is 1.  Default address is following last thing printed
with this command or "print".