在我的程序中,有一点将变量(存储在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?
0x0000000500000000
的低32位全为零。 x86是Little-endian。 gdb-giant(x86 qword)中高gdb-work(x86 dword)的前8位是5。
转储为单个字节以查看此内容,例如x /8xb
由于$rbp - 0x84
为0xff...
,因此set $rbp-0x84 = 0x1
似乎将RBP(寄存器本身)修改为较小的数字,因此x $rbp-0x84
自动换行。
不会修改内存,因为您没有像*(long*)($rbp-0x84) = 1
那样取消引用它作为指针值。 x
包含一个隐式取消引用(它使用指针arg并显示内存)。 set
和print
不在。
不过,我很惊讶它在赋值左侧的表达式完全起作用。这在C语言中是不允许的,但是显然GDB允许它。实际上,我已经测试过了,它在GDB 9.1中产生了$rbp = 1
。
在更改为RBP之后,$rbp - 0x84
是一个比0
稍低的数字,即0xff...。请注意,它不再是0x7f...
,并且更宽了[[1。 [此页面未映射。(有趣的是,Linux永远不会让您映射虚拟页面,即使在内核中也是如此,因为该范围内的值被视为错误代码,而不是有效的指针。)