使用gdb将十六进制数据解码为struct

时间:2016-09-23 05:55:42

标签: gdb

我有十六进制十六进制数据流,打印如

0x3a45 0x1234 0x0352(实际上更长)

我知道它是结构中的内容。在gdb中有一种方法可以在结构上映射它吗? Gdb似乎只接受单个值来执行此操作。

像:

(gdb)print(myStruct)0x3a45 0x1234 0x0352

$ 1 = {a = 3a,b = 45,f = 0x1234,c = 03,e = 52}

在这种情况下,它非常简单但有复杂的结构,十六进制字符串要大得多。

1 个答案:

答案 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}是一种"重新解释演员" - 它将值的原始字节重新解释为命名类型。