|
@@ -0,0 +1,109 @@
|
|
|
+#!/usr/bin/python3
|
|
|
+
|
|
|
+import argparse
|
|
|
+
|
|
|
+parser = argparse.ArgumentParser(description='KALYPSO 2.5/2.6 Data Parser ver. 0.1')
|
|
|
+parser.add_argument('-inv', action="store_true", help='Check for Tail filling in reverse byte order')
|
|
|
+parser.add_argument('-o', metavar="outfile", type=argparse.FileType('wb'), nargs='?', help='File to write decoded data to. If not set, will print human readable Hex Values to stdout instead.')
|
|
|
+parser.add_argument('infile', type=argparse.FileType('rb'), nargs=1, help='File to read from')
|
|
|
+args = parser.parse_args()
|
|
|
+
|
|
|
+writeToFile = True if args.o else False
|
|
|
+
|
|
|
+
|
|
|
+def print32Hex(b, offset, blocks=4, withLineNumber=True):
|
|
|
+
|
|
|
+ if withLineNumber:
|
|
|
+ print('0x{0:08x}'.format(offset), end=": ")
|
|
|
+
|
|
|
+ for i in range(blocks):
|
|
|
+ print('0x{0:02x}'.format(b[(i*4)+0]), end ="")
|
|
|
+ print('{0:02x}'.format(b[(i*4)+1]), end ="")
|
|
|
+ print('{0:02x}'.format(b[(i*4)+2]), end ="")
|
|
|
+ print('{0:02x}'.format(b[(i*4)+3]), end ="")
|
|
|
+ print(" ", end ="")
|
|
|
+
|
|
|
+ print("") #newline after block
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def checkTail(b, inverse=False, words=4):
|
|
|
+ a = [0xfe, 0xdc, 0xba, 0x98] #Filling pattern
|
|
|
+
|
|
|
+ for w in range(words):
|
|
|
+ u = (w+1) * 4 #upper window
|
|
|
+ l = u - 4 #lower window
|
|
|
+
|
|
|
+ for i,e in enumerate(b[l:u]):
|
|
|
+ comp = a[3-i] if inverse else a[i]
|
|
|
+
|
|
|
+ if e is not comp:
|
|
|
+ return False
|
|
|
+ return True
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+def flipBytes(bytes):
|
|
|
+ ret = []
|
|
|
+
|
|
|
+ #Take every second element from bytes, starting with 0 (bytes[0::2])
|
|
|
+ #Take every second element from bytes, starting with 1 (bytes[1::2])
|
|
|
+ #Create a list of pairs from the previous two (zip)
|
|
|
+ #Append first (f) and second (s) element to 'ret' (append)
|
|
|
+ for f,s in zip(bytes[0::2], bytes[1::2]):
|
|
|
+ ret.append(s)
|
|
|
+ ret.append(f)
|
|
|
+
|
|
|
+ return ret
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#---------- MAIN LOOP -------------#
|
|
|
+
|
|
|
+with args.infile[0] as ifile:
|
|
|
+ offset = 0
|
|
|
+
|
|
|
+ #read header
|
|
|
+ byte_s = ifile.read(32)
|
|
|
+ if not byte_s:
|
|
|
+ print("Failed to read header from file. Not enough data to read!")
|
|
|
+ quit()
|
|
|
+
|
|
|
+ #print header
|
|
|
+ if writeToFile:
|
|
|
+ args.o.write(bytes(byte_s))
|
|
|
+ else:
|
|
|
+ print32Hex(byte_s[0:16], 0)
|
|
|
+ print32Hex(byte_s[16:32], 16)
|
|
|
+
|
|
|
+
|
|
|
+ #read rest of the file
|
|
|
+ offset = 32
|
|
|
+ keep_flipping = True
|
|
|
+ while 1:
|
|
|
+ byte_s = ifile.read(16) #read 4 words
|
|
|
+
|
|
|
+ if not byte_s:
|
|
|
+ #quit once no more data is available
|
|
|
+ break
|
|
|
+
|
|
|
+ #Have we found the Tail filling?
|
|
|
+ if checkTail(byte_s, args.inv):
|
|
|
+ keep_flipping = False
|
|
|
+
|
|
|
+ #dO ThE fLiP!
|
|
|
+ byte_s = flipBytes(byte_s) if keep_flipping else byte_s
|
|
|
+
|
|
|
+ if writeToFile:
|
|
|
+ args.o.write(bytes(byte_s))
|
|
|
+ else:
|
|
|
+ print32Hex(byte_s, offset)
|
|
|
+
|
|
|
+ offset = offset + 16 #continue
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|