gpt4 book ai didi

Python 构造 - 解析可变数量的可变长度记录

转载 作者:行者123 更新时间:2023-12-01 02:29:28 28 4
gpt4 key购买 nike

我正在使用construct 2.8 对一些失传已久的 Pascal 程序创建的一些文件的 header 进行逆向工程。

header 由许多不同的记录组成,其中一些是可选的,我不确定顺序是否固定。

例如,其中两条记录如下所示:

header_record_filetype = cs.Struct(
'record_type' / cs.Int8ub,
'file_type' / cs.PascalString(cs.Int16ub),
'unknown' / cs.Int8ub
)

header_record_user = cs.Struct(
'record_type' / cs.Int8ub,
'user' / cs.PascalString(cs.Int16ub)
)

我还发现了另外六个。

如何让解析器根据未知数量的记录的 record_type 成员选择正确的记录类型,直到遇到类型为 0 的记录(或到达文件)?

最佳答案

我是这样解决的:

header = cs.Struct(
'record_type' / cs.Int8ub,
'record' / cs.Switch(cs.this.record_type, {header_record_type_0x01: header_record_0x01,
header_record_type_filename: header_record_filename,
header_record_type_filetype: header_record_filetype,
header_record_type_user: header_record_user,
header_record_type_end: header_record_end,
header_record_type_image_metadata: header_record_image_metadata},
default=header_record_end
),
'offset' / cs.Tell
)

with open(sys.argv[1], 'rb') as f:
h = f.read(2048)
index = 0
record_type = h[index]

while record_type != 0:
record = header.parse(h[index:])
print(record)
index += record.offset
record_type = record.record_type

但我不知道这是否是最好的*方法。

*对于某些“最佳”值。

<小时/>

编辑

我发现 RepeatUntil() 构造隐藏在帮助页面的底部。所以现在我有这个:

header = cs.Struct(
'type' / cs.Enum(cs.Int8ub,
file_metadata=0x01,
filename=0x02,
file_type=0x03,
user=0x0A,
image_metadata=0x10,
end=0xFF),

'record' / cs.Switch(cs.this.type, {'file_metadata': header_record_file_metadata,
'filename': header_record_filename,
'file_type': header_record_filetype,
'user': header_record_user,
'end': header_record_end,
'image_metadata': header_record_image_metadata}),
'size' / cs.Tell
)

with open(sys.argv[1], 'rb') as f:
h = f.read(2048)
records = cs.RepeatUntil(lambda obj, lst, ctx: obj.type == 'end', header).parse(h)
print(records)

这感觉更干净,更符合构造的声明性本质。

关于Python 构造 - 解析可变数量的可变长度记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47003827/

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