Skip to content

Instantly share code, notes, and snippets.

@Graph-X
Created Nov 3, 2016
Embed
What would you like to do?
#!/usr/bin/env python
import binascii
from struct import *
import os, sys
#import ctypes
import zlib
import struct
import array
import argparse
#################################################################
#
# unpacker parses out the binary and
# returns a list of the parts. The
# binary format is as follows:
# HEADER = 24 bytes
# start end #bytes field
# 0x0000 - 0x0003 (4 bytes) Magic number
# 0x0004 - 0x0005 (2 bytes) Major version
# 0x0006 - 0x0007 (2 bytes) Minor version
# 0x0008 - 0x000B (4 bytes) Compressed legth as litle endian
# 0x000c - 0x000f (4 bytes) CRC value of compressed data
# 0x0010 - 0x0013 (4 bytes) Uncompressed length
# /HEADER
# 0x0014 - EOF Zlib config data
################################################################
def config_unpacker(confile, config):
fobject = open(confile, 'rb')
mn = ''.join(struct.unpack('4s', fobject.read(4)))
major = ''.join(struct.unpack('2s', fobject.read(2)))
minor = ''.join(struct.unpack('2s', fobject.read(2)))
clen = (struct.unpack('<i', fobject.read(4)))[0]
crc = (struct.unpack('<i', fobject.read(4)))[0]
ulen = (struct.unpack('<i', fobject.read(4)))[0]
#rest of the file should be the config
confD = (struct.unpack('@%ds' % clen, fobject.read(clen)))[0]
#ZOMG IT'S DATA VALIDATION!!!!!!!!
if len(confD) == clen:
if zlib.crc32(confD) == crc:
unconfD = zlib.decompress(confD)
if len(unconfD) == ulen:
######################################################################################
# FUCK YEA!!! IT ALL CHECKS OUT!
# I'm way too excited over the fact you've made it this far
# You should be too, I never thought this script would work in a million years
######################################################################################
parts = [unconfD, 0]
with open(config, 'w') as f:
f.write(parts)
return parts
else:
print('[!] header ulen does not match uncompressed data length. ulen = %d and size = %d You done fucked up now boy!'% (ulen, len(unconfD)))
else:
print('[!] CRC check failed! Upgrayedd will now find you! Fix your old and busted shit and come back to me. Values were header CRC: %d and latest CRC: %d'% (crc, zlib.crc32(unconfD)))
else:
print('[!] Compressed values from header and data do not match. You really screwed the pooch on this one, diddn\'t ya.\nvalues are: header compressed size %d and %d for calculated length'% (clen, len(confD)))
confD = fobject.read()
fobject.close()
parts = [mn,maj,min,ulen,crc,clen]
return parts
################################################
# packer function take the config, builds the
# header and converts the reassembled file
# back to a binary config.
# Format:
# HEADER
# start end #bytes field
# 0x0000 - 0x0003 (4 bytes) Magic number
# 0x0004 - 0x0005 (2 bytes) Major version
# 0x0006 - 0x0007 (2 bytes) Minor version
# 0x0008 - 0x000B (4 bytes) Compressed legth as litle endian
# 0x000c - 0x000f (4 bytes) CRC value of compressed data
# 0x0010 - 0x0013 (4 bytes) Uncompressed length
# /HEADER
# 0x0014 - EOF Zlib config data
###################################################
def config_packer(outfile, config, magic_number, major, minor):
ulen = len(config)
print("[*] ulen is %d"% ulen)
compressed_config = zlib.compress(config)
clen = len(compressed_config)
print("[*] compressed length is %d"% clen)
crc = zlib.crc32(compressed_config)
print("[*] CRC is %d"% crc)
buf = struct.pack('!4s2i', ''.join(magic_number), major, minor)
buf += struct.pack('<3i', clen, crc, ulen)
if len(compressed_config) == clen:
buf += struct.pack('%ds' % (clen), compressed_config)
try:
with open(outfile, 'wb') as output:
output.write(buf)
output.close()
print("[+] buffer has been written to the file successfully")
return True
except Exception as e:
print("[!] couldn't write the config file. Got the following error: %s" % (str(e)))
return False
else:
print("[!] Compresed length does not match length of compressed data clen = %d len(compressed_data) = %d" % (clen, len(compressed_config)))
return False
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--pack', dest='pact', action='store_true', help="pack up a config")
parser.add_argument('-u', '--unpack',dest='unpact', action='store_true', help="unpack a config")
parser.add_argument('-b', '--binfile', dest='binfile', help="binary config file" )
parser.add_argument('-x', '--xmlfile', dest='config', required=True, help="plain text xml config file")
args = parser.parse_args()
if len(sys.argv) == 1:
parser.print_help()
sys.exit(2)
else:
return args
def main():
magic_number = ('L', 'M', 'M', 'N')
major = 0x0003
minor = 0x0000
args = get_args()
p = args.pact
u = args.unpact
config = args.config #plain text xml config
binfile = args.binfile #binary config
if p and u:
print("[-] You can't pack and unpack at the same time ya dolt. Go fix your shit and come back when your head's out of your ass")
sys.exit(2)
if not args.config or not args.binfile:
print("[-] Alright there snowflake, you need to specify an xml file and a binary file for me to work with here. Go to the end of the line and try again")
sys.exit(2)
if p:
with open(config, 'r') as con:
context = con.read()
result = config_packer(binfile, context, magic_number, major, minor)
con.close()
if result:
print("[+] New config file is packed and ready for upload: %s" % binfile)
sys.exit(0)
else:
print("[-] I'm pretty sure you fucked up, but the guy who wrote me didn't add in a lot of error checking. You might want to try this again.")
sys.exit(2)
if u:
result = config_unpacker(binfile,config)
if result:
print("[+] New config xml file is unpacked and read to hack: %s" % config)
sys.exit(0)
else:
print("[-] I'm not sure this worked out how we intended. You might want to double check that bin file")
sys.exit(2)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment