I'm working on unpacking Hauwei E586 MiFi firmware. I downloaded firmware update pack which is available as Windows EXE, then used Hauwei Modem Flasher to unpack real firmware from installer.
I've got 4 files:
01.bin: data
02.bin: ELF 32-bit LSB executable, ARM, version 1, statically linked, not stripped
03.bin: data
04.bin: ELF 32-bit LSB executable, ARM, version 1, statically linked, not stripped
As we can see 02
and 04
are executable files. 01
is probably some kind of bootloader (I assume it from string analysis). 03
is some kind of pseudo FS.
I started from analyzing 03
(I posted it here):
There is header part
02 00 EE EE 50 BA 6E 00 20 00 00 00 D0 A2 02 00
7B 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00
7B 02
as 16 bits gives 635 which is number of files in binary (verified using strings
). Then there are 635 parts describing each file (call it directory) and at the end there is content of files.
There is directory entry for first GIF file which I found. I choosed GIF because it's easy to identify (there is header GIF8X and footer 0x3B).
77 77 77 5C 75 6D 5C 70 75 62 6C 69 63 5F 73 79
73 2D 72 65 73 6F 75 72 63 65 73 5C 42 75 74 74
75 6E 5F 43 75 72 72 65 6E 74 2E 67 69 66 00 00
lot of zeros
18 22 11 00 10 02 00 00 00 00 00 00 00 00 FF EE
We can see its name: www\um\public_sys-resources\Buttun_Current.gif
and in last line there is offset of file in binary and file size, but I'm not really sure how to interpret this values.
I found first GIF after directory and extracted it manually (from header to footer) which gives me file of size 528 bytes, so reading 10 02
as 16 bit unsigned gives me that number. I tried to treat 18 22
as 16 bit unsigned to get offset, but it was different from offset that I manually read from file. Bu there was constant difference between offset and real offset of file of 1286864
. So I created script for unpacking this binary (I'm getting offset and adding to it 1286864
).
Script worked only partially. It recreated directory structure, but was able only to extract files in one particular directory (directory with GIF which I was using as reference). After check on different part of file it seems that offset of offset in different subdirectories is another that in this GIF directory. So, my guess is that I'm interpreting offset wrong (but treating it as 32 bits gives nothing useful).
There is unpack script:
import sys, struct, os
def main(args):
outdir = args[1]
f = open(args[0], 'rb')
f2 = open(args[0], 'rb')
header = f.read(32)
print(len(header[16:]))
number_of_files = struct.unpack("h", header[16:18])[0]
print(number_of_files)
for i in range(number_of_files):
body = f.read(272)
file_, rest = body.split(b'\x00', 1)
offset = struct.unpack("H", body[256:258])[0] + 1286864
size = struct.unpack("H", body[260:262])[0]
file_ = file_.decode(encoding='UTF-8').replace('\\', '/')
dirname = os.path.join(outdir, os.path.dirname(file_))
filename = os.path.basename(file_)
print(filename, size, offset, dirname)
try:
os.makedirs(dirname)
except OSError:
pass
outfile = open(os.path.join(dirname, filename), "wb")
f2.seek(offset)
outfile.write(f2.read(size))
outfile.close()
if __name__=='__main__':
sys.exit(main(sys.argv[1:]))
Usage: ./script.py 03.bin output_directory
So my question is: what I'm doing wrong? Maybe I should read some another data type as offset/size? Which one?