import os.path import io import struct from binascii import b2a_hex from hexdump import hexdump, asasc, tohex, unhex from koddecoder import kodecode from readers import ByteReader """ python3 crodump.py crodump chechnya_proverki_ul_2012 python3 crodump.py kodump -s 6 -o 0x4cc9 -e 0x5d95 chechnya_proverki_ul_2012/CroStru.dat """ def toout(args, data): """ return either ascdump or hexdump """ if args.ascdump: return asasc(data) else: return tohex(data) def enumunreferenced(ranges, filesize): """ from a list of used ranges and the filesize, enumerate the list of unused ranges """ o = 0 for start, end, desc in sorted(ranges): if start > o: yield o, start-o o = end if o>24 ln &= 0xFFFFFFF dat = self.readdata(ofs, ln) if not dat: # empty record encdat = dat elif self.need_decode and not flags: extofs, extlen = struct.unpack(">24 ln &= 0xFFFFFFF dat = self.readdata(ofs, ln) ranges.append((ofs, ofs+ln, "item #%d" % i)) decflag = ' ' infostr = "" tail = b'' if not dat: # empty record encdat = dat elif self.need_decode and not flags: extofs, extlen = struct.unpack(" read from stdin. import sys data = sys.stdin.buffer.read() if args.unhex: data = unhex(data) decode_kod(args, data) def cro_dump(args): """ handle 'crodump' subcommand """ db = Database(args.dbdir) db.dump(args) def destruct(args): """ decode the index#1 structure information record Takes hex input from stdin. """ import sys data = sys.stdin.buffer.read() data = unhex(data) d = dict() rd = ByteReader(data) o = 0 startbyte = rd.readbyte() while not rd.eof(): keylen = rd.readbyte() keyname = rd.readbytes(keylen).decode('ascii') if keyname in d: print("duplicate key: %s" % keyname) index_or_length = rd.readdword() if index_or_length >> 31: d[keyname] = rd.readbytes(index_or_length & 0x7FFFFFFF) print("%-20s - %s" % (keyname, toout(args, d[keyname]))) else: d[keyname] = index_or_length print("%-20s -> %s" % (keyname, d[keyname])) def main(): import argparse parser = argparse.ArgumentParser(description='CRO hexdumper') subparsers = parser.add_subparsers() parser.set_defaults(handler=None) ko = subparsers.add_parser('kodump', help='KOD/hex dumper') ko.add_argument('--offset', '-o', type=str, default="0") ko.add_argument('--length', '-l', type=str) ko.add_argument('--endofs', '-e', type=str) ko.add_argument('--unhex', '-x', action='store_true', help="assume the input contains hex data") ko.add_argument('--shift', '-s', type=str, help="KOD decode with the specified shift") ko.add_argument('--increment', '-i', action='store_true', help="assume data is already KOD decoded, but with wrong shift -> dump alternatives.") ko.add_argument('--ascdump', '-a', action='store_true', help="CP1251 asc dump of the data") ko.add_argument('--nokod', '-n', action='store_true', help="don't KOD decode") ko.add_argument('filename', type=str, nargs='?', help="dump either stdin, or the specified file") ko.set_defaults(handler=kod_hexdump) cro = subparsers.add_parser('crodump', help='CROdumper') cro.add_argument('--verbose', '-v', action='store_true') cro.add_argument('--kodecode', '-k', action='store_true') cro.add_argument('--ascdump', '-a', action='store_true') cro.add_argument('--nokod', '-n', action='store_true') cro.add_argument('--struonly', action='store_true') cro.add_argument('dbdir', type=str) cro.set_defaults(handler=cro_dump) des = subparsers.add_parser('destruct', help='Stru dumper') des.add_argument('--ascdump', '-a', action='store_true') des.set_defaults(handler=destruct) args = parser.parse_args() if args.handler: args.handler(args) if __name__=='__main__': main()