我正在解包 Hauwei E586 MiFi 固件。我下载了可用作 Windows EXE 的固件更新包,然后使用 Hauwei Modem Flasher 从安装程序中解压真实固件。
我有4个文件:
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
如我们所见02
,04
是可执行文件。01
可能是某种引导加载程序(我从字符串分析中假设它)。03
是某种伪FS。
我从分析开始03
(我把它贴在这里):
有标题部分
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
因为 16 位给出 635,这是二进制文件的数量(使用 验证strings
)。然后有 635 个部分描述每个文件(称为目录),最后是文件的内容。
我找到的第一个 GIF 文件有目录条目。我选择 GIF 是因为它很容易识别(有页眉 GIF8X 和页脚 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
我们可以看到它的名字:www\um\public_sys-resources\Buttun_Current.gif
在最后一行有二进制和文件大小的文件偏移量,但我不确定如何解释这些值。
我在目录之后找到第一个 GIF 并手动提取它(从页眉到页脚),这给了我 528 字节大小的文件,因此读取10 02
为 16 位无符号给了我这个数字。我试图将18 22
16 位无符号视为获取偏移量,但它与我手动从文件中读取的偏移量不同。但是1286864
. 所以我创建了解包这个二进制文件的脚本(我得到了偏移量并添加到它1286864
)。
脚本仅部分起作用。它重新创建了目录结构,但只能提取一个特定目录(我用作参考的带有 GIF 的目录)中的文件。检查文件的不同部分后,不同子目录中的偏移量似乎是这个GIF目录中的另一个。所以,我的猜测是我解释偏移量是错误的(但将其视为 32 位没有任何用处)。
有解压脚本:
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:]))
用法: ./script.py 03.bin output_directory
所以我的问题是:我做错了什么?也许我应该读取另一种数据类型作为偏移量/大小?哪一个?