我有十六进制十六进制数据流,打印如
0x3a45 0x1234 0x0352(实际上更长)
我知道它是结构中的内容。在gdb中有一种方法可以在结构上映射它吗? Gdb似乎只接受单个值来执行此操作。
像:
(gdb)print(myStruct)0x3a45 0x1234 0x0352
$ 1 = {a = 3a,b = 45,f = 0x1234,c = 03,e = 52}
在这种情况下,它非常简单但有复杂的结构,十六进制字符串要大得多。
答案 0 :(得分:1)
我认为在gdb中有几种可行的方法可以做到这一点。
最简单的方法是以某种方式将数据写入下级内存。它可能看起来像:
(gdb) set $mem = malloc(50) # number of bytes
(gdb) set $mem[0] = 0x72
(gdb) set $mem[1] = 0xff
# etc - you can find faster ways to do this
(gdb) print *(struct whatever *) $mem
填充内存很痛苦,但这可以编写脚本。例如,您可以编写一个小shell脚本,将原始字节转换为set
命令序列,然后转换为source
。或者你可以在Python中编写一个新的gdb命令来自动完成所有这些命令。
gdb还有一个扩展,让我们在命令行上创建一个数组,并做一种"重新解释转换"在上面。我发现这个方法不那么方便,因为我只能使数组功能创建int
的数组,而不是char
。但无论如何,请考虑这个小程序:
struct x {
int a;
long b;
};
int main() {
struct x x = { 23, 97 };
return 0;
}
我启动gdb并停在return
上,然后检查内存:
(gdb) p sizeof(int)
$1 = 4
(gdb) p sizeof(x)
$2 = 16
(gdb) x/4xw &x
0x7fffffffe240: 0x00000017 0x00007fff 0x00000061 0x00000000
(第二个词是垃圾,因为它在struct padding中......)
现在我们可以手动从原始数据中重新创建x
:
(gdb) print {struct x}{0x17, 0x7fff, 0x61, 0}
$3 = {
a = 23,
b = 97
}
此表达式使用gdb提供的两个C表达式扩展。首先,{0x17, 0x7fff...}
是一种编写数组的方法。其次,{struct x}
是一种"重新解释演员" - 它将值的原始字节重新解释为命名类型。