Added gcddump to dump parsed GCD to files which can later be reassembled

into a GCD.
This commit is contained in:
2018-10-21 01:03:19 +02:00
parent c0a1d833ba
commit 27a90e8b38
3 changed files with 154 additions and 2 deletions
+50
View File
@@ -8,6 +8,7 @@ GCD_SIG = b"G\x41RM\x49Nd\00"
DEFAULT_COPYRIGHT = b"Copyright 1996-2017 by G\x61rm\x69n Ltd. or its subsidiaries."
DEFAULT_FIRST_PADDING = 21
DEFAULT_ALIGN = 0x1000 # second padding block pads until 0x1000
MAX_BLOCK_LENGTH = 0xff00 # binary blocks max len
# Typical structure:
# first 0x1000 Bytes: GCD_SIG > 0x0001 > 0x0002 > 0x0003 > 0x0005 > 0x0001 > 0x0002
@@ -27,6 +28,7 @@ class Gcd:
if self.filename is None:
return False
last_tlv6 = None
last_tlv7 = None
with open(self.filename, "rb") as f:
sig = f.read(8)
if sig != GCD_SIG:
@@ -46,6 +48,9 @@ class Gcd:
last_tlv6 = tlv
elif tlv.type_id == 0x0007:
tlv.set_tlv6(last_tlv6)
last_tlv7 = tlv
elif tlv.is_binary:
tlv.set_tlv7(last_tlv7)
f.close()
def add_tlv(self, new_tlv: TLV):
@@ -98,3 +103,48 @@ class Gcd:
else:
print("☒ ONE OR MORE CHECKSUMS INVALID!")
return all_ok
def write_dump_block(self, f, name):
f.write("\n[BLOCK_{}]\n".format(name))
def write_dump_param(self, f, key, value, comment=None):
if comment is not None:
f.write("# {}\n".format(comment))
f.write("{} = {}\n".format(key, value))
def dump(self, output_basename: str):
output_file = "{}.rcp".format(output_basename)
ctr = 0
last_filename = None
with open(output_file, "wt") as f:
f.write("[GCD_DUMP]\n")
f.write("dump_by = grmn-gcd\n")
f.write("dump_ver = 1\n")
f.write("original_filename = {}\n\n".format(self.filename))
f.write("# [BLOCK_nn] headers are just for parsing/grouping purposes.\n")
f.write("# Lengths are informational only, they will be calculated upon reassembly.\n")
for tlv in self.struct:
if tlv.is_binary:
outfile = "{}_{:04x}.bin".format(output_basename, tlv.type_id)
if outfile != last_filename:
self.write_dump_block(f, str(ctr))
self.write_dump_param(f, "from_file", outfile)
for item in tlv.dump():
self.write_dump_param(f, item[0], item[1], item[2])
last_filename = outfile
with open(outfile, "wb") as of:
of.write(tlv.value)
else:
with open(outfile, "ab") as of:
of.write(tlv.value)
elif tlv.type_id == 0xffff:
# EOF marker
pass
else:
tlvinfo = tlv.dump()
if len(tlvinfo) > 0:
self.write_dump_block(f, str(ctr))
for item in tlvinfo:
self.write_dump_param(f, item[0], item[1], item[2])
ctr += 1
f.close()