[英]Why cannot gdb access memory of ret instruction?
asm 中的每次call
都會導致該指令push
es 返回值,因此一旦調用ret
,程序就知道從哪里繼續。 所以我想檢查調用ret
的地址:
有這個:
#include <stdio.h>
int main()
{
printf("a=%d; b=%d; c=%d", 1, 2, 3);
return 0;
}
我使用 gdb:
(gdb) b printf
+b printf
Breakpoint 1 at 0x1030
(gdb) run
+run
Breakpoint 1, __printf (format=0x555555556004 "a=%d; b=%d; c=%d")
at printf.c:28
28 printf.c: No such file or directory.
(gdb) x/10x $rsp
+x/10x $rsp
0x7fffffffdc28: 0x55555159 0x00005555 0x55555160 0x00005555
0x7fffffffdc38: 0xf7e1c09b 0x00007fff 0x00000000 0x00000000
0x7fffffffdc48: 0xffffdd18 0x00007fff
(gdb) x/i 0x55555159
+x/i 0x55555159
0x55555159: Cannot access memory at address 0x55555159
(gdb)
在這里,我試圖從返回地址讀取指令,但不知何故無法訪問該地址。 為什么,什么時候應該是ret
的有效地址?
正如 Eric Postpischil 評論的那樣,您只檢查了返回地址的一半,即x86_64
上的 64 位。
使用您的程序:
(gdb) b printf
Breakpoint 1 at 0x1030
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, __printf (format=0x555555556004 "a=%d; b=%d; c=%d") at printf.c:28
28 printf.c: No such file or directory.
(gdb) bt
#0 __printf (format=0x555555556004 "a=%d; b=%d; c=%d") at printf.c:28
#1 0x0000555555555159 in main () at t.c:4
這表明我們期望在堆棧上找到的返回地址是0x0000555555555159
。 確實,這正是地址 @ $rsp
:
(gdb) x/gx $rsp
0x7fffffffdbd8: 0x0000555555555159
要查看該地址的指令:
(gdb) x/i 0x0000555555555159
0x555555555159 <main+36>: mov $0x0,%eax
你也可以拆開整個main
,看看你在哪里以及你要返回哪里:
(gdb) disas main
Dump of assembler code for function main:
0x0000555555555135 <+0>: push %rbp
0x0000555555555136 <+1>: mov %rsp,%rbp
0x0000555555555139 <+4>: mov $0x3,%ecx
0x000055555555513e <+9>: mov $0x2,%edx
0x0000555555555143 <+14>: mov $0x1,%esi
0x0000555555555148 <+19>: lea 0xeb5(%rip),%rdi # 0x555555556004
0x000055555555514f <+26>: mov $0x0,%eax
0x0000555555555154 <+31>: callq 0x555555555030 <printf@plt>
0x0000555555555159 <+36>: mov $0x0,%eax
0x000055555555515e <+41>: pop %rbp
0x000055555555515f <+42>: retq
End of assembler dump.
如您所見, printf
將返回的指令確實位於地址0x0000555555555159
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.