为什么GDB'x / w'和'x / g'显示不同的值?

问题描述 投票:0回答:1

在我的程序中,有一点将变量(存储在rbp-0x84处)与0x1进行比较。但是,当我查看那里的内容时,会得到矛盾的结果。

gef➤  x/w $rbp-0x84
0x7fffffffdf5c: 0x00000000
gef➤  x/g $rbp-0x84
0x7fffffffdf5c: 0x0000000500000000

前8位如何从0x0变为0x5?

哪个会导致我下一个问题...当我尝试时:

gef➤  set $rbp-0x84 = 0x1
gef➤  x $rbp-0x84
0xffffffffffffff7d: Cannot access memory at address 0xffffffffffffff7d

地址如何从0x7fffffffdf5c变为0xffffffffffffff7d?

debugging assembly memory gdb x86-64
1个回答
0
投票

0x0000000500000000的低32位全为零。 x86是Little-endian。 gdb-giant(x86 qword)中高gdb-work(x86 dword)的前8位是5。

转储为单个字节以查看此内容,例如x /8xb

由于$rbp - 0x840xff...,因此set $rbp-0x84 = 0x1似乎将RBP(寄存器本身)修改为较小的数字,因此x $rbp-0x84自动换行。

不会修改内存,因为您没有像*(long*)($rbp-0x84) = 1那样取消引用它作为指针值。 x包含一个隐式取消引用(它使用指针arg并显示内存)。 setprint不在。

不过,我很惊讶它在赋值左侧的表达式完全起作用。这在C语言中是不允许的,但是显然GDB允许它。实际上,我已经测试过了,它在GDB 9.1中产生了$rbp = 1

在更改为RBP之后,$rbp - 0x84是一个比0稍低的数字,即0xff...。请注意,它不再是0x7f...,并且更宽了[[1。 [此页面未映射。(有趣的是,Linux永远不会让您映射虚拟页面,即使在内核中也是如此,因为该范围内的值被视为错误代码,而不是有效的指针。)

脚注1:用户空间虚拟地址最多为47位宽(直到具有如此大RAM的PML5 CPU,操作系统选择使用额外级别的页表)。 Linux将堆栈放在顶部。
© www.soinside.com 2019 - 2024. All rights reserved.