我正在阅读关于黑客攻击的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的指令吗?
0x00fc45c7
与mov DWORD PTR [rbp-0x4],0x0
(0x40050f处的汇编指令)相同吗?
其次,如果是指令,那么命令x/12x $rip
,x/8xw $rip
,x/8xh $rip
的输出中的那些十六进制数是什么?
答案 0 :(得分:8)
至于(1),你说得对。
对于(2),x命令最多有3个说明符:要打印的对象数量;以哪种格式;什么对象大小。在所有示例中,您选择以十六进制(x)打印。对于第一个说明符,您要求打印12,8,8个对象。
关于你案件中的最后一个说明者:
x / 12x没有,所以gdb默认假设你想要双字,也就是4字节块。请注意,您发现双字有时定义不同,但在intel x86汇编/ gdb中,它是4个字节。一般来说,我总是指定你想要什么,而不是回到默认设置。
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".