获取hex文件并提取数据

时间:2014-04-06 23:26:10

标签: python parsing hex

我基本上有一个文件,我希望搜索特定的十六进制值(标题),一旦找到,从该十六进制值位置(标题)读取所有内容,直到找到特定的十六进制值(页脚)

我有一些起始代码:

import binascii

holdhd = ""
holdft = ""
header = "03AABBCC"
footer = "FF00FFAA"

with open ('hexfile', 'rb') as file:    
    bytes = file.read()
    a = binascii.hexlify(bytes)     
    while header in a:      
        holdhd = header     
        print holdhd

这将打印出我希望成功找到的标题(文件中有多个标题),但我不确定如何继续从这一点读取文件并打印出所有内容,直到footer找到了。

提前致谢

2 个答案:

答案 0 :(得分:2)

考虑到文件大小,您可能希望将所有内容加载到内存中(将数据保存为字节),然后使用正则表达式提取页眉和页脚之间的部分,例如:

import binascii
import re

header = binascii.unhexlify('000100a0')
footer = binascii.unhexlify('00000000000')

with open('hexfile', 'rb') as fin:
    raw_data = fin.read()

data = re.search('{}(.*?){}'.format(re.escape(header), re.escape(footer)), raw_data).group(1)

答案 1 :(得分:1)

如果文件足够小以便您可以将它们加载到内存中,则可以将它们视为常规字符串,并使用find方法(请参阅here)进行导航。

让我们进入最糟糕的情况:你不能保证你的标题将成为文件中的第一个标题,并且你可能拥有多个标识符(多个{{1}我创建了一个名为<header><body><footer>的文件,其中包含以下内容:

bindata.txt

好的,有两个实体,第一个是ABCD000100a0AAAAAA000000000000ABCDABCD000100a0BBBBBB000000000000ABCD ,第二个AAAAAA和一些垃圾在开头,中间和结尾(BBBBBB在第一个标题之前,{{1在第二个页眉之前和第二个页脚之后的ABCD

使用ABCDABCD对象的ABCD方法和索引,这是我想出的:

find

输出:

str

如果您的文件太大而无法保留在内存中,我认为最好是逐字节读取文件并创建几个函数来查找标题结束的位置并且页脚开始使用文件&#39; s {{ 3}}和seek方法。

编辑:

根据OP的请求,方法无需使用原始二进制文件(使用原始二进制文件)并使用搜索和告诉:

header = "000100a0"
footer = "00000000000"

with open('bindata.txt', 'r') as f:
    data = f.read()
    print "Data: %s" % data
    header_index = data.find(header, 0)
    footer_index = data.find(footer, 0)
    if header_index >= 0 and footer_index >= header_index:
        print "Found header at %s and footer at %s" \
              % (header_index, footer_index)
        body = data[header_index + len(header): footer_index]
        while body is not None:
            print "body: %s" % body
            header_index = data.find(header,\
                                     footer_index + len(footer))
            footer_index = data.find(footer,\
                                     footer_index + len(footer) + len(header) )
            if header_index >= 0 and footer_index >= header_index:
                print "Found header at %s and footer at %s" \
                       % (header_index, footer_index)
                body = data[header_index + len(header): footer_index]
            else:
                body = None

此方法产生以下输出:

Data: ABCD000100a0AAAAAA000000000000ABCDABCD000100a0BBBBBB000000000000ABCD
Found header at 4 and footer at 18
body: AAAAAA
Found header at 38 and footer at 52
body: BBBBBB

请注意,我使用Python的mmap模块来帮助浏览文件。请查看其tell。此外,此示例的第一部分包含一些数据,用于在import os import binascii import mmap header = binascii.unhexlify("000100a0") footer = binascii.unhexlify("0000000000") sample = binascii.unhexlify("ABCD" "000100a0AAAAAA000000000000" "ABCDABCD" "000100a0BBBBBB000000000000" "ABCD") # Create the sample file: with open("sample.data", "wb") as f: f.write(sample) # sample done. Now we have a REAL binary data in sample.data with open('sample.data', 'rb') as f: print "Data: %s" % binascii.hexlify(f.read()) mm = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ) current_offset = 0 header_index = mm.find(header, current_offset) footer_index = mm.find(footer, current_offset + len(header)) if header_index >= 0 and footer_index > header_index: print "Found header at %s and footer at %s"\ % (header_index, footer_index) mm.seek(header_index + len(header)) body = mm.read(footer_index - mm.tell()) while body is not None: print "body: %s" % binascii.hexlify(body) current_offset = mm.tell() header_index = mm.find(header, current_offset + len(footer)) footer_index = mm.find(footer, current_offset + len(footer) + len(header)) if header_index >= 0 and footer_index > header_index: print "Found header at %s and footer at %s"\ % (header_index, footer_index) mm.seek(header_index + len(header)) body = mm.read(footer_index - mm.tell()) else: body = None 中创建实际的二进制文件。块的执行:

Data: abcd000100a0aaaaaa000000000000abcdabcd000100a0bbbbbb000000000000abcd
Found header at 2 and footer at 9
body: aaaaaa
Found header at 19 and footer at 26
body: bbbbbb

生成以下(真正易读的)文件:

sample.data