tl; dr - 在尝试对专有数据库文件进行逆向工程时,我发现Wordpad能够将一些数据自动解码为清晰易读的格式。我正在尝试在python中实现该解码。现在,即使是Wordpad伏都教也不可重复。
准备好脑筋急转弯?
我正试图解决一些奇怪的问题。我有一个数据文件,它是科学仪器(Mettler DSC / STARe软件)程序的数据库,我正试图从实验中获取样本信息。从我在文件中挖掘,它似乎包括有关实验运行的明文,未加密信息以及数据。它是一个.t00文件,大小超过40 mb(它基本上存储了运行的所有数据),而且我对编码知之甚少(除了它看起来是任意的。它并不意味着是一个文本文件)。我可以在Wordpad中打开这个文件,可以看到我正在寻找的信息(样本名称,时间戳,实验参数),被实验运行数据包围(正如预期的那样,这看起来像很多gobbledygook,例如¶+ú@“< Ø@ DSSO @¨...)。看起来我基本上很幸运能够对内容有所了解,而我正试图复制它。
我可以使用基本文件处理程序将文件读入python,并使用正则表达式获取我想要的一些信息。 'r'vs'rb'似乎没有帮助。
def textOpenLines(filename,mode='rb'):
with open(filename, mode) as content_file:
return [line for line in content_file]
我可以获取该列表并搜索相关字符串并从中获取样本名称。但是,通过查看Wordpad中的文件,我发现样本名称被列出两次,第二次它有跟随它的日期戳(例如'Dibenzoylperoxid 120 C 03.05.1994 14:24:30')。在python中,我找不到这个字符串。我连自己都找不到时间戳。当我查看它应该发生的行时,我得到一堆随机字节。在记事本中打开看起来像python输出。
我怀疑这是一个编码问题。我已经尝试用Unicode读取文件,我已经尝试过读取行的片段并阅读它们,但我无法破解它。我很难过。
有关如何阅读此内容的任何想法,以便它解码正确吗?写字板是正确的(虽然现在随后尝试打开它,它看起来像记事本输出)。
谢谢!
编辑:
前32个字节(f.read(32))读取
'\ x10 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ x00 \ X00 \ X00 \ X00 \ X00 \ X04 \ X10 \ X00 \ X00'
我对BOM没有太多了解,但是从阅读Wiki页面看,它看起来不像任何有效的UTF标记。
首次在Wordpad中自动解码时,文件的开头如下所示: 121 22二苯甲酰过氧化物120 C 03.05.1994 14:24:30 1 0 4096 ESTimeAI- @£®@nôÂ@49Õ@kÉå@FÞò@`sþ@N5A2A®“A”A-¥A¿A'AA“ÓAÿãAÅÅAäHA,œAÑÌAŸäA¤ ÆAE-AFNATöAÐ|AõAº^ A(ÄAèAýqA¹AÖûAº8A¬uAK«AgÜAüAÞAo4A将N AFAB
在记事本,Python和现在的Wordpad中打开文件的开头如下所示: (空字节x00 ......)](x00 ...)eß(x00 ...)NvN(x00)......等
答案 0 :(得分:4)
您的文件不是由ascii字符组成,而是由打开它的应用程序解释。如果你在wordpad中打开一个.jpg图像会发生同样的事情 - 你会得到一堆二进制和一些ascii字符,这些字符是人类可以打印和识别的。
这就是为什么你不能对你的时间戳进行纯文本搜索的原因。例如。
以下是代码中用于演示此问题的示例。在二进制文件中,您有以下字节:
\x44\x69\x62\x65\x6e\x7a\x6f\x79\x6c\x70\x65\x72\x6f\x78\x69\x64\x20\x31\
x32\x30\x20\x43\x20\x30\x33\x2e\x30\x35\x2e\x31\x39\x39\x34\x20\x31\x34\x3a\x32\
x34\x3a\x33\x30
如果要在像textpad这样的文本编辑器中打开它,它将呈现以下内容:
Dibenzoylperoxid 120 C 03.05.1994 14:24:30
以下是Python中的代码段:
>>> c='\x44\x69\x62\x65\x6e\x7a\x6f\x79\x6c\x70\x65\x72\x6f\x78\x69\x64\x20\x31\
x32\x30\x20\x43\x20\x30\x33\x2e\x30\x35\x2e\x31\x39\x39\x34\x20\x31\x34\x3a\x32\
x34\x3a\x33\x30'
>>> print c
Dibenzoylperoxid 120 C 03.05.1994 14:24:30
这些字节是十六进制格式,这就是为什么你不能用明文搜索它。
原因是因为二进制文件遵循一个非常特殊的结构(协议,规范),因此读取它的程序可以正确地解析它。如果你以jpeg图像为例,你会发现图像的第一个字节和最后一个字节总是相同的(取决于使用的格式) - FF D8
将是jpeg的前两个字节, FF D9
将是jpeg的最后两个字节,用于识别它。现在,图像编辑程序将知道如何开始将这个二进制数据解析为jpeg,并且它将会#34; walk&#34;文件内部的结构来渲染图像。 Here是指向资源的链接,可帮助您根据&#34;签名&#34;或&#34;标题&#34; - 文件10 00
的前两个字节未显示在该数据库中,因此您可能正在处理专有格式,因此您无法轻松地在线查找规范。这就是逆向工程派上用场的地方。
我建议您在hexeditor中打开文件 - 它将为您提供十六进制输出以及ascii输出,以便您可以开始分析文件格式。我个人使用Hackman Hexeditor here(它是免费的,有很多功能)。
但是现在 - 给你一些有用的东西来搜索你感兴趣的数据文件是一种快速的方法,可以在开始搜索之前将搜索查询转换为二进制文件。
import struct
#binary_data = open("your_binary_file.bin","rb").read()
#your binary data would show up as a big string like this one when you .read()
binary_data = '\x44\x69\x62\x65\x6e\x7a\x6f\x79\x6c\x70\x65\x72\x6f\x78\x69\x64\x20\x31\
x32\x30\x20\x43\x20\x30\x33\x2e\x30\x35\x2e\x31\x39\x39\x34\x20\x31\x34\x3a\x32\
x34\x3a\x33\x30'
def search(text):
#convert the text to binary first
s = ""
for c in text:
s+=struct.pack("b", ord(c))
results = binary_data.find(s)
if results == -1:
print "no results found"
else:
print "the string [%s] is found at position %s in the binary data"%(text, results)
search("Dibenzoylperoxid")
search("03.05.1994")
上述脚本的结果是:
the string [Dibenzoylperoxid] is found at position 0 in the binary data
the string [03.05.1994] is found at position 25 in the binary data
这应该让你开始。
答案 1 :(得分:0)
是FutureMe。
您可能对写字板很幸运。我不确定,因为数据已经消失了,但是我猜想写字板做出了英勇的尝试,试图将文件解码为UTF-8(或者可能是UTF-16或CP1252)。该看来起作用的原因是,在大多数二进制协议中,字符串可能被编码为UTF-8,因此对于ASCII字符集,它们在转储中看起来相同。但是,其他所有内容都将进行二进制编码。
您对open(fn, 'rb')
有一个正确的想法,但您应该只读了整个blob,而不是readlines
,后者试图分裂成\n
。由于db文件不是用\n
分隔的,因此将无法正常工作。
本来更好的方法是对字节使用直方图,并尝试推断字段/行分隔符是什么(如果存在的话)。寻找TLV (type-length-value) encoded fields。由于您知道样本名称的列表,因此可以获取一个起始字符串的列表,使用它来查找斑点中的切点,并确定字段大小的规则性。
另外,购买比特币。