The differences between the binwalk results may be caused by the different version of the binwalk you use. So, check the version of your binwalk by simply running binwalk without any parameter.
Regarding to the firmware, you cannot unpack the content using binwalk. To see why, check the start of the firmware. You will find a
0x20 bytes header starting with the
DLA50 string. This magic string and the header is repeated at offset
0x8040 and so on. To see the structure of the header, check the following one from the middle of the firmware file:
I marked the magic string (DLA50) with yellow, the position of the fragment with green and the size of the fragment with blue.
The following script can follow the headers and extract the parts from the image:
if (len(sys.argv) < 2):
print 'firm.py filename'
id = 0
last = 0
idh = None
bf = open(sys.argv, 'rb')
h = bf.read(0x20)
if (len(h) < 0x20 or h[0:5] != 'DLA50'):
dpos = struct.unpack('L', h[0x14:0x18])
dsize = struct.unpack('L', h[0x18:0x1c])
print '%s, pos: %x, size: %x'%(binascii.hexlify(h), dpos, dsize)
d = bf.read(dsize)
if (last != 0x4000):
if (idh != None):
idh = open('%d.bin'%(id), 'wb')
id += 1
last = dsize
The above script will extract the following parts:
0-0x2865b: Executable code, may be compressed with LZMA, LZO or something similar
0x286d7-0x56f60: File system, the individual files are also compressed
0x56f60-0x5bdc0: Possibly a configuration area
The first part is starting with a
0x10 bytes header followed by a high entropy data. The header contains some flags or magic bytes and a data size, which I marked with blue in the next image. I can identify the size data item based on the size of the first part, which is
0x28555 = header size + 0x28545.
The next part starts with the following bytes:
The area started at
0x60 seems to contain file names, such as
501h1_uk.js and so on, along with other binary data. So, this area may contain file entries. If it is true, the previous data (
0x60) is a directory entry or a header. In this header area, you can found some interesting value in little-endian byte order. The
0x0002e709 (marked with blue) is equal with the file size. The
0x00000060 (marked with yellow) may point to the start of the file entries. The
0x00000d48 (marked with red) after the file entry offset may be another offset inside the file. So, after checking that offset in the file, it see that it points right after the directory entries, so it may by the starting offset of the data area.
We have some guesses about the structure of the header, so let's check the file entries. If we suppose, that file names are started at the same position always inside a file entry, then we can calculate the size of one entry by subtracting the offset of two consecutive file names. Based on this calculation the file entry size will be
Similarly to the previous steps, after a little more research, we can conclude that the file entry area starts with the count of the files and every file entry contains the file name, file flags, relative position of the file data and the file size.
Putting all together, the following script can extract the files from the second part of the firmware file:
if (len(sys.argv) < 2):
print 'parse_fs.py filename'
fh = open(sys.argv,'rb')
h = fh.read(0x60)
fs_size = struct.unpack('L', h[0x08:0x0c])
offset = struct.unpack('L', h[0x20:0x24])
data_start = struct.unpack('L', h[0x24:0x28])
print 'fs size: %x, dir offset: %x, data start: %x'%(fs_size, offset, data_start)
ds = data_start-offset
d = fh.read(ds)
count = struct.unpack('H', d[0:2])
for i in xrange(count):
o = i*0x16+2
unk1 = struct.unpack('H', d[o+0x00:o+0x02])
fname = d[o+0x02:o+0x0e]+'\x00'
fname = fname[0:fname.find('\x00')]
unk2 = struct.unpack('H', d[o+0x0e:o+0x10])
pos = struct.unpack('L', d[o+0x10:o+0x14])+data_start
size = struct.unpack('H', d[o+0x14:o+0x16])
print ' %s, pos: %x, size: %x, unk1: %x, unk2: %x'%(fname, pos, size, unk1, unk2)