1

我正在编写一个小脚本,旨在打开一个二进制文件,找到一个经常变化的二进制 blob,然后将该 blob 复制到一个新文件中。

这是二进制文件的布局:

-JUNK (Unknown Size) (Unknown Contents)
-3-byte HEADER containing encoded size of blob
-PADDING (Unknown Size) (Every byte is FF in hex)
-Start of blob (72 bytes) (Unknown Contents)
-16 bytes that are ALWAYS the same
-End of blob (Size can be determined from subtracting (72+16) from value HEADER) (Unknown Contents)
-JUNK (Unknown Size) (Unknown Contents)

这是我到目前为止编写的代码:

from sys import argv
import binascii
import base64

InputFileName = argv[1]

with open(InputFileName, 'rb') as InputFile:

    Constant16 = base64.b64decode("GIhTSuBask6y60iLI2VwIg==")
    Constant16Offset = InputFile.read().find(Constant16)

    InputFile.seek(Constant16Offset)
    InputFile.seek(-72,1)

    InputFile.seek(-1,1)
    FFTestVar = InputFile.read(1)

    while FFTestVar == b'\xFF':
        InputFile.seek(-2,1)
        FFTestVar = InputFile.read(1)

    InputFile.seek(-3,1)
    BlobSizeBin = InputFile.read(3)
    BlobSizeHex = binascii.b2a_hex(BlobSizeBin)
    BlobSizeDec = int(BlobSizeHex, 16)

    InputFile.seek(Constant16Offset)
    InputFile.seek(-72,1)

    Blob = InputFile.read(BlobSizeDec)

    with open('output.bin', 'wb') as OutputFile:

        OutputFile.write(Blob)

不幸的是,while循环很慢。InputFile 最大可达 24MB,而填充可能是其中的一大块。一次一个字节地浏览它是非常慢的。

我在想可能有更好的方法可以做到这一点,但是谷歌搜索一两个小时并没有帮助。

谢谢!

4

1 回答 1

2

您可以将整个文件读入内存(实际上是这样做的):

data = InputFile.read()

然后你可以把data它当作随便的字符串(但它不是 unicode 字符串,而是一个字节数组,不幸的是str在 python 2.X 下调用)。您需要记住偏移量,以便我们创建offset属性。看起来像的每一行都InputFile.seek(xx)必须翻译offset = xx成.InputFile.seek(xx, 1)offset += xx

magic_number = base64.b64decode("GIhTSuBask6y60iLI2VwIg==")
offset = magic_number_offset = data.find(magic_number)
offset -= 72

然后,而不是 while 循环使用re模块(您需要导入该模块):

pattern = re.compile("[^\xFF]\xFF*$")
offset = pattern.search(data, endpos=offset).start() + 1

其余代码是:

offset -= 3
blob_size_bin = data[offset:offset+3]
blob_size_hex = binascii.b2a_hex(blob_size_bin)
blob_size_dec = int(blob_size_hex, 16)
offset = magic_number_offset - 72
blob = data[offset:offset+blob_size_dec]

如果文件非常大并且python进程消耗大量内存,您可以使用mmap模块而不是将整个文件加载到内存中。

如果此解决方案仍然很慢,您可以反转数据顺序 ( reversed_data = data[::-1]) 并搜索 pattern [^\ff]

于 2012-11-26T09:31:55.647 回答