简体   繁体   English

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

[英]What does gdb 'x' command do?

I am reading a book about hacking and it has a chapter about assembly.我正在读一关于黑客的,其中有一章关于汇编。

Following is my tiny program written in C.以下是我用 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测试:

(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>请注意 $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

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

Is it the instruction at 0x40050f?是 0x40050f 处的指令吗? Is 0x00fc45c7 same as mov DWORD PTR [rbp-0x4],0x0 (assembled instruction at 0x40050f)? 0x00fc45c7是否与mov DWORD PTR [rbp-0x4],0x0 (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 ?其次,如果是指令,那么命令x/12x $rip , x/8xw $rip , x/8xh $rip的输出中的那些十六进制数是多少?

As to (1), you got that correct.至于(1),你猜对了。

As to (2), the x command has up to 3 specifiers: how many objects to print;对于 (2), x 命令最多有 3 个说明符:要打印的对象数量; in which format;以哪种格式; and what object size.和什么对象大小。 In all your examples you choose to print as hex (x).在所有示例中,您选择打印为十六进制 (x)。 As to the first specifier, you ask to print 12, 8, 8 objects.对于第一个说明符,您要求打印 12、8、8 个对象。

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"). x/12x 没有,所以 gdb 默认假设你想要 4 字节的块(GDB 称之为“字”,x86 称之为“双字”)。 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. x/8xw 对 8 个对象执行相同的操作,正如您现在明确请求的 dwords。

(The x command defaults to the last size you used, but the initial default for that on startup is w words) x命令默认为您使用的最后一个大小,但启动时的初始默认值是w字)


x/8xh requests half-word sized chunks of 2 bytes, so objects printed in 2 byte chunks. x/8xh 请求 2 个字节的半字大小的块,因此以 2 个字节的块打印对象。 (Half-word relative to GDB's standard 32-bit word size; x86 calls this a "word"). (半字相对于 GDB 的标准 32 位字长;x86 称之为“字”)。

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.如果您想知道为什么两个相邻值的串联与您在 dwords 中打印时报告的不相等,这是因为 x86 是小端架构。 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.简而言之,如果你重新组合它们 (2,1) (4,3), ...,你会看到它们匹配。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM