gpt4 book ai didi

python - 内存转储格式为 gdb 中的 xxd

转载 作者:IT老高 更新时间:2023-10-28 21:38:56 27 4
gpt4 key购买 nike

我正在尝试检查一个缓冲区,该缓冲区包含二进制格式的消息,但也包含字符串数据。例如,我正在使用这个 C 代码:

int main (void) {
char buf[100] = "\x01\x02\x03\x04String Data\xAA\xBB\xCC";

return 0;
}

我想获得 buf 中内容的十六进制转储,格式类似于 xxd(我不在乎它是否完全匹配,什么我真正在寻找的是与可打印字符并排的十六进制转储)。

在 GDB 中我可以使用类似的东西:

(gdb) x /100bx buf
0x7fffffffdf00: 0x01 0x02 0x03 0x04 0x53 0x74 0x72 0x69
0x7fffffffdf08: 0x6e 0x67 0x20 0x44 0x61 0x74 0x61 0xaa
0x7fffffffdf10: 0xbb 0xcc 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdf18: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdf20: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdf28: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdf30: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdf38: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdf40: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdf48: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdf50: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x7fffffffdf58: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

这很好,但很难用这种方式挑选字符串......或者我可以使用

(gdb) x /100bs buf
0x7fffffffdf00: "\001\002\003\004String Data\252\273\314"
0x7fffffffdf13: ""
0x7fffffffdf14: ""
0x7fffffffdf15: ""
0x7fffffffdf16: ""
0x7fffffffdf17: ""
...

这使得阅读二进制部分变得很困难......我正在处理的实际消息中也有很多 ascii nul,所以看起来真的是一团糟。

我能想到的最好办法就是这样做:

(gdb) dump binary memory dump.bin buf buf+100

然后

$ xxd dump.bin
0000000: 0102 0304 5374 7269 6e67 2044 6174 61aa ....String Data.
0000010: bbcc 0000 0000 0000 0000 0000 0000 0000 ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000060: 0000 0000 ....

但每次都这样做很痛苦。我发现有人以前想要这个,所以想知道是否有人找到了在 gdb 中实现它的方法。另外,您会以这种方式丢失原始内存中的地址。

我正在使用内置 python 支持的 GDB 7.4,所以我愿意使用 pretty-print 或类似设备,但我不知道如何设置。

最佳答案

(gdb) define xxd
>dump binary memory dump.bin $arg0 $arg0+$arg1
>shell xxd dump.bin
>end
(gdb) xxd &j 10
0000000: 0000 0000 0000 0000 0000 0000 4d8c a7f7 ............M...
0000010: ff7f 0000 0000 0000 0000 0000 c8d7 ffff ................
0000020: ff7f 0000 0000 0000

看起来很简单;-)

您可以编写一个 Python 脚本(现代 GDB 版本已嵌入 Python 解释器)来做同样的事情,而无需“脱壳”。

更新:

这是一个可能的 Python 实现(将其保存到 xxd.py):

class XXD(gdb.Command):
def __init__(self):
super(XXD, self).__init__("xxd", gdb.COMMAND_USER)

def _PrintLine(self, offset, bytes, size):
print('{:08x}: '.format(offset), end='')
todo = size
while todo >= 4:
print(''.join('{:02x}'.format(b) for b in bytes[0:4]), end='')
todo -= 4
bytes = bytes[3:]
if todo:
print(' ', end='')

# Print any remaining bytes
print(''.join('{:02x}'.format(b) for b in bytes[0:todo]), end='')

print()
return size

def invoke(self, arg, from_tty):
args = arg.split()
if len(args) != 2:
print("xxd: <addr> <count>")
return
size = int(args[1])
addr = gdb.parse_and_eval(args[0])
inferior = gdb.inferiors()[0]
bytes = inferior.read_memory(addr, size).tobytes()

offset = int(addr)
while size > 0:
n = self._PrintLine(offset, bytes, min(len(bytes), 16))
size -= n
offset += n
bytes = bytes[n:]

XXD()

像这样使用它:

// Sample program x.c
char foo[] = "abcdefghijklmopqrstuvwxyz";
int main() { return 0; }

gcc -g x.c
gdb -q ./a.out

(gdb) source xxd.py
Temporary breakpoint 1, main () at x.c:3
3 int main() { return 0; }

(gdb) xxd &foo[0] 18
00404030: 61626364 64656667 6768696a 6a6b6c6d
00404040: 7273

关于python - 内存转储格式为 gdb 中的 xxd,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9233095/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com