-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzf660configurator.py
148 lines (124 loc) · 5.97 KB
/
zf660configurator.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import sys
import binascii
import struct
import zlib
import os
# also can use header
def validate_header(file_header):
if(file_header[0x0:0x4] != b'\x04\x03\x02\x01'):
print('Invalid magic at begining')
sys.exit()
if(file_header[0x10:0x14] != b'\x01\x02\x03\x04'):
print('Invalid magic')
sys.exit()
hcrc_calc = binascii.crc32(file_header[0x10:0x28]) & 0xffffffff
hcrc_stored = struct.unpack('!L', file_header[0x28:0x2c])[
0] # unpack as long integer
print(
f'hcrc_calculated = {hex(hcrc_calc)} , stored_val = {hex(hcrc_stored)}')
if(hcrc_calc != hcrc_stored):
print('header CRC invalid')
sys.exit()
def disassemble():
file_header = file.read(0x4c)
validate_header(file_header)
# calculating crc on header
block_buffer_size = struct.unpack('!L', file_header[0x20:0x24])[0]
cumulate_crc_stored = struct.unpack('!L', file_header[0x24:0x28])[0]
# relpos_final_block_stored = struct.unpack('!L', file_header[0x1c:0x20])[0]
print(f'block buffer size = {hex(block_buffer_size)}')
fout = open(
f"{filepath}{(filename.split('.'))[0]}_outs/{(filename.split('.'))[0]}_disassembled.xml", 'wb')
cumulate_crc = 0
while(True):
block_header = file.read(0x0c)
if(len(block_header) == 0):
break
block_size = struct.unpack('!L', block_header[0x04:0x08])[0]
print(f'block size = {hex(block_size)}')
block = file.read(block_size)
cumulate_crc = binascii.crc32(block, cumulate_crc) & 0xffffffff
block_decomp = zlib.decompress(block)
fout.write(block_decomp)
print(
f'cumulate_crc_stored = {cumulate_crc_stored}, calculated = {cumulate_crc}')
if(cumulate_crc_stored != cumulate_crc):
print("invalid cumulate_crc")
sys.exit()
fout.close()
def assemble():
# ---------------------------------- compressing and storing xml as zlib ----------------------------------------------
file_data = file.read()
data_block = zlib.compress(file_data, 9)
with open(f"{filepath}{(filename.split('.'))[0]}_outs/{((filename.split('.'))[0])}_compressed.zlib", 'wb') as zfile:
zfile.write(data_block)
zfile.close()
print(
f"zlib file saved {filepath}{(filename.split('.'))[0]}_outs/{((filename.split('.'))[0])}_compressed.zlib\n")
# ----------------------------------block size and xml config file size
xml_size = struct.pack('!L', (os.path.getsize(f'{filepath}{filename}')))
block_size = struct.pack('!L', (os.path.getsize(
f"{filepath}{(filename.split('.'))[0]}_outs/{((filename.split('.'))[0])}_compressed.zlib")))
# --------------------------------- block assembling header----------------------------------------
# calculating block crc --> hex
block_crc = struct.pack('!L', (binascii.crc32(data_block) & 0xffffffff))
# relative position to final block from 0x1c; We are wirtting just one file
block_relpos = b'\x00\x00\x00\x3c'
block_buffer = b'\x00\x01\x00\x00' # temp memory buffer
next_block_relpos = b'\x00' * 4
block_info = b'\x00' * 4 + xml_size + block_relpos + block_buffer + block_crc
block_info_crc = struct.pack('!L', (binascii.crc32(
b'\x01\x02\x03\x04' + block_info) & 0xffffffff)) # crc val of 0x10:0x28
block_header = xml_size + block_size + next_block_relpos
# -----------------printing part-------------------------------------------------------------------
print(f"xml size = {hex((struct.unpack('!L',xml_size))[0])}\nblock size = {hex((struct.unpack('!L',block_size))[0])}\nblock crc = {hex((struct.unpack('!L',block_crc))[0])}\nblock relpos from 0x1c = {hex((struct.unpack('!L',block_relpos))[0])}\nmemory buffer = {hex((struct.unpack('!L',block_buffer))[0])}\nblock info crc = {hex((struct.unpack('!L',block_info_crc))[0])}\n")
# --------------------------------------writting output----------------------------------------------------------
build_file = open(
f"{filepath}{(filename.split('.'))[0]}_outs/{((filename.split('.'))[0])}_assembled.bin", 'wb')
build_file.write(header + block_info + block_info_crc)
build_file.write(b'\x00' * 32)
build_file.write(block_header)
build_file.write(data_block)
build_file.close()
print(
f"bin file saved {filepath}{(filename.split('.'))[0]}_outs/{((filename.split('.'))[0])}_assembled.bin")
if __name__ == "__main__":
if(len(sys.argv) < 3):
print("Usage : createF660config.py <-c | -d> <inputfile (xml or bin)> \nexample:createF660config.py -c /config_out/config.xml")
sys.exit()
fileInarray = list(sys.argv[2])
fileInput = ""
for i in range(len(fileInarray)):
if(os.name == 'nt'):
if(fileInarray[i] == "/"):
fileInarray[i] = "\\"
else:
if(fileInarray[i] == "\\"):
fileInarray[i] = "/"
fileInput = ''.join(fileInarray)
if(os.name == 'nt'):
args = fileInput.split('\\')
else:
args = fileInput.split('/')
filename = args[-1]
filepath = ""
if(len(args) > 1):
for i in (args[:len(args) - 1]):
if(os.name == 'nt'):
filepath += i + "\\"
else:
filepath += i + "/"
file = open(filepath + filename, 'rb')
print("Creating a project folder")
command = "mkdir " + str(filepath) + \
str((filename.split('.'))[0]) + "_outs"
os.system(command)
# Complete F660 Header (End-Of-Transmission F660)
header = b'\x04\x03\x02\x01\x00\x00\x00\x00\x00\x00\x00\x04\x46\x36\x36\x30\x01\x02\x03\x04'
if(sys.argv[1] == "-c"):
assemble()
elif(sys.argv[1] == "-d"):
disassemble()
else:
print("invalid arguments \nUsage : createF660config.py <-c | -d> <inputfile (xml or bin)>\nexample:createF660config.py -c /config_out/config.xml")
file.close()