我正在使用 GDB,并且我在其中一个寄存器中有一个指向 C 风格字符串的指针。我想显示该字符串。然而,当我尝试取消引用寄存器中的指针时,甚至手动取消引用时,它给了我错误的地址。这是为什么?我实际上该怎么做?这里 RDX 可能指向环境变量。我使用的是unix系统(Ubuntu 22.04)。 GDB 版本是
GNU gdb (Ubuntu 12.0.90-0ubuntu1) 12.0.90
我用 --nx
加载它只是为了确保它不是我的插件之一。
(gdb) info registers
[..snip..]
rdx 0x7fffffffd8e8 140737488345320
[..snip..]
(gdb) x/1s *$rdx
0xffffffffffffdd6a: <error: Cannot access memory at address 0xffffffffffffdd6a>
(gdb) x/1xg $rdx
0x7fffffffd8e8: 0x00007fffffffdd6a
(gdb) x/1s 0x00007fffffffdd6a
0x7fffffffdd6a: "QT_SCALE_FACTOR=1"
(gdb) x/1s *0x7fffffffd8e8
0xffffffffffffdd6a: <error: Cannot access memory at address 0xffffffffffffdd6a>
编辑:
我编写了一个测试程序,并且解除引用工作得很好。
#include <cstdint>
#include <print>
int main()
{
char cstr[] = "Testing.";
char* ptr1 = reinterpret_cast<char*>(cstr);
char** ptr2 = &ptr1;
std::print("String: {0}, ptr1: {1:x}, ptr2: {2:x}", cstr, (uint64_t)ptr1, (uint64_t)ptr2);
return 0;
}
pwndbg> print ptr2
$3 = (char **) 0x7fffffffd7e8
pwndbg> print ptr1
$4 = 0x7fffffffd7f0 "Testing."
pwndbg> x/1s ptr2
0x7fffffffd7e8: "\360\327\377\377\377\177"
pwndbg> x/1s *ptr2
0x7fffffffd7f0: "Testing."
似乎只有取消引用 $registers 才会给出错误的值?
另一个程序是
int main()
{
__builtin_trap();
return 0;
}
顺便说一句,用
clang++ -g -O0 trap.cpp -o trap
编译
错误消息提示这里出了什么问题:
(gdb) x/1s *$rdx
0xffffffffffffdd6a: <error: Cannot access memory at address 0xffffffffffffdd6a>
注意地址
0xffffffffffffdd6a
,然后将其与执行此操作时看到的输出进行比较:
(gdb) x/1xg $rdx
0x7fffffffd8e8: 0x00007fffffffdd6a
请注意,GDB 尝试访问不同的地址。我们看到的是,GDB 将
*$rdx
的结果截断为 32 位,然后将其符号扩展为 64 位: 0x00007fffffffdd6a
-> 0xffffdd6a
-> 0xffffffffffffdd6a
。
我不知道为什么会出现这种情况:
(gdb) ptype $rdx
type = int64_t
我希望 GDB 将取消引用视为 64 位。不过,您可以说服 GDB 执行 64 位访问,例如:
(gdb) p/1s *(unsigned long long *)$rdx
我认为应该做你想做的事。