forked from unbe/mmi-ifs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunpackifs.py
115 lines (104 loc) · 3.55 KB
/
unpackifs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import sys
from construct import *
from subprocess import PIPE, Popen
# http://www.qnx.com/developers/docs/660/index.jsp?topic=%2Fcom.qnx.doc.neutrino.building%2Ftopic%2Fload_process_Boot_header.html
boot_header = Struct("boot_header",
Enum(ULInt32("signature"),
CORRECT = 0x00FF7EEB,
_default_ = Pass,
),
ULInt16("version"),
BitStruct("flags1",
Flag("STARTUP_HDR_FLAGS1_VIRTUAL"),
Flag("STARTUP_HDR_FLAGS1_BIGENDIAN"),
Enum(BitField("Compression", 4),
STARTUP_HDR_FLAGS1_COMPRESS_NONE = 0,
STARTUP_HDR_FLAGS1_COMPRESS_ZLIB = 0x01,
STARTUP_HDR_FLAGS1_COMPRESS_LZO = 0x02,
STARTUP_HDR_FLAGS1_COMPRESS_UCL = 0x03,
_default_ = Pass
),
Padding(2),
),
ULInt8("flags2_unused"),
ULInt16("header_size"),
Enum(ULInt16("machine"),
EM_NONE = 0,
EM_M32 = 1, # /* AT&T WE 32100 */
EM_SPARC = 2, # /* Sun SPARC */
EM_386 = 3, # /* Intel 80386 */
EM_68k = 4, # /* Motorola 68000 */
EM_88k = 5, # /* Motorola 88000 */
EM_486 = 6, # /* Intel 80486 */
EM_860 = 7, # /* Intel i860 */
EM_MIPS = 8, # /* MIPS RS3000 Big-Endian */
EM_S370 = 9, # /* IBM system 370 */
EM_MIPS_RS3_LE = 10, # /* MIPS RS3000 Little-Endian */
EM_RS6000 = 11, # /* RS6000 */
EM_UNKNOWN12 = 12,
EM_UNKNOWN13 = 13,
EM_UNKNOWN14 = 14,
EM_PA_RISC = 15, # /* PA_RISC */
EM_nCUBE = 16, # /* nCUBE */
EM_VPP500 = 17, # /* Fujitsu VPP500 */
EM_SPARC32PLUS = 18, # /* Sun Sparc 32+ */
EM_UNKNOWN19 = 19,
EM_PPC = 20, # /* Power PC */
EM_ARM = 40, # /* ARM */
EM_SH = 42, # /* Hitachi SH */
_default_ = Pass
),
ULInt32("startup_vaddr"),
ULInt32("paddr_bias"),
ULInt32("image_paddr"),
ULInt32("ram_paddr"),
ULInt32("ram_size"),
ULInt32("startup_size"),
ULInt32("stored_size"),
ULInt32("imagefs_paddr"),
ULInt32("imagefs_size"),
ULInt16("preboot_size"),
ULInt16("zero0"),
Array(3, ULInt32("zero3"))
)
input = open(sys.argv[1], "rb")
data = input.read()
input.close()
header = boot_header.parse(data)
print header
if header.stored_size == len(data):
print "stored_size OK"
else:
print "stored_size NOK"
stored_imagefs = header.stored_size - header.startup_size
if stored_imagefs == header.imagefs_size:
print "imagefs_size OK, uncompressed"
elif stored_imagefs < header.imagefs_size:
print "imagefs_size OK, compressed %d -> %d" % (header.imagefs_size, stored_imagefs)
else:
print "imagefs_size NOK: imagefs %d, stored %d" % (header.imagefs_size, stored_imagefs)
startup = open(sys.argv[1] + ".startup", "wb")
startup.write(data[:header.startup_size])
print "Wrote " + str(startup)
startup.close()
imagefs = open(sys.argv[1] + ".imagefs", "wb")
imagefs_data = data[header.startup_size:]
imagefs.write(imagefs_data)
print "Wrote " + str(imagefs)
imagefs.close()
imagefs_struct = GreedyRange(PascalString("imagefs", length_field = UBInt16("length")))
imagefs_parsed = imagefs_struct.parse(imagefs_data)
print "Found %d LZO blocks" % len(imagefs_parsed)
imagefs = open(sys.argv[1] + ".imagefs.decompressed", "wb")
for i in range(len(imagefs_parsed)):
sys.stdout.write("\rDecompress: %d/%d " % (i, len(imagefs_parsed)))
if len(imagefs_parsed[i]) == 0:
continue
lzod = Popen("./lzod", stdin=PIPE, stdout=imagefs, stderr=PIPE)
lzod_result = lzod.communicate(imagefs_parsed[i])
if (lzod.returncode != 0):
print "Failed: %d" % lzod.returncode
print lzod_result
raise Exception
print "\nWrote " + str(imagefs)
imagefs.close()