binwalk zlib 数据
binwalk 结果之间的差异可能是由于您使用的 binwalk 版本不同造成的。因此,只需运行不带任何参数的 binwalk 即可检查 binwalk 的版本。关于固件,您无法使用 binwalk 解压缩内容。要了解原因,请检查固件的启动。您会发现一个0x20以DLA50字符串开头的字节标头。这个魔法字符串和标题在 offset 处重复0x4020,0x8040依此类推。要查看标头的结构,请检查固件文件中间的以下一项:
我用黄色标记魔法字符串(DLA50),用绿色标记片段的位置,用蓝色标记片段的大小。
以下脚本可以跟随标题并从图像中提取部分:
import struct
import binascii
import sys
if (len(sys.argv) < 2):
print 'firm.py filename'
sys.exit(0)
id = 0
last = 0
idh = None
bf = open(sys.argv[1], 'rb')
while(True):
h = bf.read(0x20)
if (len(h) < 0x20 or h[0:5] != 'DLA50'):
break
dpos = struct.unpack('L', h[0x14:0x18])[0]
dsize = struct.unpack('L', h[0x18:0x1c])[0]
print '%s, pos: %x, size: %x'%(binascii.hexlify(h), dpos, dsize)
d = bf.read(dsize)
if (last != 0x4000):
if (idh != None):
idh.close()
idh = open('%d.bin'%(id), 'wb')
id += 1
idh.write(d)
last = dsize
idh.close()
上述脚本将提取以下部分:
0-0x2865b: 可执行代码,可以用 LZMA、LZO 或类似的东西压缩0x286d7-0x56f60: 文件系统,单个文件也被压缩0x56f60-0x5bdc0: 可能是配置区
第一部分以0x10字节头开始,后跟高熵数据。标题包含一些标志或魔术字节和数据大小,我在下一张图片中用蓝色标记。我可以根据第一部分的大小来识别大小数据项,即0x28555 = header size + 0x28545.
下一部分以以下字节开始:
开始于的区域0x60似乎包含文件名,例如501h1_uk.js等等,以及其他二进制数据。因此,该区域可能包含文件条目。如果为真,则前面的数据 ( 0x00- 0x60) 是目录条目或标题。在这个头部区域,你可以找到一些小端字节序的有趣值。的0x0002e709(标有蓝色)是与文件大小相等。的0x00000060(标记为黄色)可能指向文件条目的开始。的0x00000d48(用红色标出)后的文件入口偏移可以在文件内部彼此偏移。因此,在检查文件中的偏移量后,它看到它正好指向目录条目之后,因此它可能是数据区的起始偏移量。
我们对头的结构有一些猜测,所以让我们检查文件条目。如果我们假设文件名总是在文件条目内的相同位置开始,那么我们可以通过减去两个连续文件名的偏移量来计算一个条目的大小。根据此计算,文件条目大小将为0x16字节。
与前面的步骤类似,经过多一点研究,我们可以得出结论,文件入口区从文件的计数开始,每个文件入口包含文件名、文件标志、文件数据的相对位置和文件大小。
总而言之,以下脚本可以从固件文件的第二部分提取文件:
import struct
import sys
if (len(sys.argv) < 2):
print 'parse_fs.py filename'
sys.exit(0)
fh = open(sys.argv[1],'rb')
h = fh.read(0x60)
fs_size = struct.unpack('L', h[0x08:0x0c])[0]
offset = struct.unpack('L', h[0x20:0x24])[0]
data_start = struct.unpack('L', h[0x24:0x28])[0]
print 'fs size: %x, dir offset: %x, data start: %x'%(fs_size, offset, data_start)
fh.seek(offset)
ds = data_start-offset
d = fh.read(ds)
count = struct.unpack('H', d[0:2])[0]
for i in xrange(count):
o = i*0x16+2
unk1 = struct.unpack('H', d[o+0x00:o+0x02])[0]
fname = d[o+0x02:o+0x0e]+'\x00'
fname = fname[0:fname.find('\x00')]
unk2 = struct.unpack('H', d[o+0x0e:o+0x10])[0]
pos = struct.unpack('L', d[o+0x10:o+0x14])[0]+data_start
size = struct.unpack('H', d[o+0x14:o+0x16])[0]
print ' %s, pos: %x, size: %x, unk1: %x, unk2: %x'%(fname, pos, size, unk1, unk2)
fh.seek(pos)
open('fs_%s'%(fname), 'wb').write(fh.read(size))


