summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crodump.py81
1 files changed, 50 insertions, 31 deletions
diff --git a/crodump.py b/crodump.py
index 1ba7e5e..7a9d9f3 100644
--- a/crodump.py
+++ b/crodump.py
@@ -9,7 +9,15 @@ python3 crodump.py crodump chechnya_proverki_ul_2012
9python3 crodump.py kodump -s 6 -o 0x4cc9 -e 0x5d95 chechnya_proverki_ul_2012/CroStru.dat 9python3 crodump.py kodump -s 6 -o 0x4cc9 -e 0x5d95 chechnya_proverki_ul_2012/CroStru.dat
10""" 10"""
11 11
12def toout(args, data):
13 """ return either ascdump or hexdump """
14 if args.ascdump:
15 return asasc(data)
16 else:
17 return tohex(data)
18
12def enumunreferenced(ranges, filesize): 19def enumunreferenced(ranges, filesize):
20 """ from a list of used ranges and the filesize, enumerate the list of unused ranges """
13 o = 0 21 o = 0
14 for start, end, desc in sorted(ranges): 22 for start, end, desc in sorted(ranges):
15 if start > o: 23 if start > o:
@@ -19,6 +27,7 @@ def enumunreferenced(ranges, filesize):
19 yield o, filesize-o 27 yield o, filesize-o
20 28
21class Datafile: 29class Datafile:
30 """ Represent a single .dat with it's .tad index file """
22 def __init__(self, dat, tad): 31 def __init__(self, dat, tad):
23 self.dat = dat 32 self.dat = dat
24 self.tad = tad 33 self.tad = tad
@@ -39,7 +48,7 @@ class Datafile:
39 self.dat.seek(ofs) 48 self.dat.seek(ofs)
40 return self.dat.read(size) 49 return self.dat.read(size)
41 50
42 def dump(self, args, dokodecode=False, plainbytes=0): 51 def dump(self, args, nodecode=False):
43 print("tadhdr: %08x %08x" % tuple(self.tadhdr)) 52 print("tadhdr: %08x %08x" % tuple(self.tadhdr))
44 ranges = [] 53 ranges = []
45 for i, (ofs, ln, chk) in enumerate(self.tadidx): 54 for i, (ofs, ln, chk) in enumerate(self.tadidx):
@@ -50,30 +59,45 @@ class Datafile:
50 59
51 ln &= 0xFFFFFFF 60 ln &= 0xFFFFFFF
52 dat = self.readdata(ofs, ln) 61 dat = self.readdata(ofs, ln)
62 ranges.append((ofs, ofs+ln, "item #%d" % i))
53 plain = b'' 63 plain = b''
54 decrypted = ' ' 64 decflag = ' '
55 if dokodecode and not args.nokod: 65 infostr = ""
56 pb = plainbytes if flags else 8 66 tail = b''
57 plain = dat[:pb] 67 if not nodecode and not flags:
58 dat = kodecode(i+1, dat[pb:]) 68 extofs, extlen = struct.unpack("<LL", dat[:8])
59 decrypted = '*' if flags else '+' 69 infostr = "%08x;%08x" % (extofs, extlen)
60 if args.ascdump: 70 encdat = dat[8:]
61 print("%5d: %08x-%08x: (%02x:%08x) %s %s%s" % (i, ofs, ofs+ln, flags, chk, tohex(plain), decrypted, asasc(dat))) 71 while len(encdat)<extlen:
72 dat = self.readdata(extofs, 0x200)
73 ranges.append((extofs, extofs+0x200, "item #%d ext" % i))
74 extofs, = struct.unpack("<L", dat[:4])
75 infostr += ";%08x" % (extofs)
76 encdat += dat[4:]
77 tail = encdat[extlen:]
78 encdat = encdat[:extlen]
79 decflag = '+'
62 else: 80 else:
63 print("%5d: %08x-%08x: (%02x:%08x) %s %s%s" % (i, ofs, ofs+ln, flags, chk, tohex(plain), decrypted, tohex(dat))) 81 encdat = dat
64 ranges.append((ofs, ofs+ln, "item #%d" % i)) 82 decflag = '*'
83
84 if nodecode:
85 decdat = encdat
86 decflag = ' '
87 else:
88 decdat = kodecode(i+1, encdat)
89
90 print("%5d: %08x-%08x: (%02x:%08x) %s %s%s %s" % (i, ofs, ofs+ln, flags, chk, infostr, decflag, toout(args, decdat), tohex(tail)))
65 91
66 if args.verbose: 92 if args.verbose:
67 # output parts not referenced in the .tad file. 93 # output parts not referenced in the .tad file.
68 for o, l in enumunreferenced(ranges, self.datsize): 94 for o, l in enumunreferenced(ranges, self.datsize):
69 dat = self.readdata(o, l) 95 dat = self.readdata(o, l)
70 if args.ascdump: 96 print("%08x-%08x: %s" % (o, o+l, toout(args, dat)))
71 print("%08x-%08x: %s" % (o, o+l, asasc(dat)))
72 else:
73 print("%08x-%08x: %s" % (o, o+l, tohex(dat)))
74 97
75 98
76class Database: 99class Database:
100 """ represent the entire database, consisting of stru, index and bank files """
77 def __init__(self, dbdir): 101 def __init__(self, dbdir):
78 self.dbdir = dbdir 102 self.dbdir = dbdir
79 103
@@ -114,22 +138,12 @@ def decode_kod(args, data):
114 # explicitly specified shift. 138 # explicitly specified shift.
115 for s in range(256): 139 for s in range(256):
116 enc = incdata(data, s) 140 enc = incdata(data, s)
117 if args.ascdump: 141 print("%02x: %s" % (s, toout(args, enc)))
118 print("%02x: %s" % (s, asasc(enc)))
119 else:
120 print("%02x: %s" % (s, tohex(enc)))
121
122
123
124 else: 142 else:
125 # output with all possible 'shift' values. 143 # output with all possible 'shift' values.
126 for s in range(256): 144 for s in range(256):
127 enc = kodecode(s, data) 145 enc = kodecode(s, data)
128 if args.ascdump: 146 print("%02x: %s" % (s, toout(args, enc)))
129 print("%02x: %s" % (s, asasc(enc)))
130 else:
131 print("%02x: %s" % (s, tohex(enc)))
132
133 147
134 148
135def kod_hexdump(args): 149def kod_hexdump(args):
@@ -145,6 +159,10 @@ def kod_hexdump(args):
145 159
146 if args.filename: 160 if args.filename:
147 with open(args.filename, "rb") as fh: 161 with open(args.filename, "rb") as fh:
162 if args.length is None:
163 fh.seek(0, io.SEEK_END)
164 filesize = fh.tell()
165 args.length = filesize-args.offset
148 fh.seek(args.offset) 166 fh.seek(args.offset)
149 data = fh.read(args.length) 167 data = fh.read(args.length)
150 decode_kod(args, data) 168 decode_kod(args, data)
@@ -158,22 +176,23 @@ def kod_hexdump(args):
158 176
159 177
160def cro_dump(args): 178def cro_dump(args):
179 """ handle 'crodump' subcommand """
161 db = Database(args.dbdir) 180 db = Database(args.dbdir)
162 181
163 if db.stru: 182 if db.stru:
164 print("stru") 183 print("stru")
165 db.stru.dump(args, dokodecode=True) 184 db.stru.dump(args)
166 if args.struonly: 185 if args.struonly:
167 return 186 return
168 if db.index: 187 if db.index:
169 print("index") 188 print("index")
170 db.index.dump(args) 189 db.index.dump(args, nodecode=True)
171 if db.bank: 190 if db.bank:
172 print("bank") 191 print("bank")
173 db.bank.dump(args) 192 db.bank.dump(args, nodecode=True)
174 if db.sys: 193 if db.sys:
175 print("sys") 194 print("sys")
176 db.sys.dump(args, dokodecode=True, plainbytes=8) 195 db.sys.dump(args)
177 196
178 197
179def main(): 198def main():