Ejemplo n.º 1
0
 def __init__(self, raw, file):
     (self.index, self.offset, self.size, self.crc) = struct.unpack("<LLLL", raw)
     #Resources are loaded sequentially, so...
     self.raw_data = file.read(self.size)
     self.png = BMPResource(self.raw_data)
     log.debug("%08X | %08X" % (self.crc, crc32(self.raw_data)))
     log.debug(repr(self))
     assert(self.crc == crc32(self.raw_data))
Ejemplo n.º 2
0
 def __init__(self, raw, file):
     (self.index, self.offset, self.size,
      self.crc) = struct.unpack("<LLLL", raw)
     #Resources are loaded sequentially, so...
     self.raw_data = file.read(self.size)
     self.png = BMPResource(self.raw_data)
     log.debug("%08X | %08X" % (self.crc, crc32(self.raw_data)))
     log.debug(repr(self))
     assert (self.crc == crc32(self.raw_data))
def extract_content(pbz, content, output_dir):
    print('Extracting %s...' % content['name'])
    pbz.extract(content['name'], output_dir)
    data = io.FileIO(output_dir + content['name']).readall()
    crc = crc32(data)
    if crc == content['crc']:
        print('\t[  OK] Checking CRC...')
    else:
        print('\t[Fail] Checking CRC...')
        print("\tIt's %d, but should be %d" % (content['crc'], crc))
def extract_content(pbz, content, output_dir):
    print 'Extracting %s...' % content['name']
    pbz.extract(content['name'], output_dir)
    data = io.FileIO(output_dir + content['name']).readall()
    crc = crc32(data)
    if crc == content['crc']:
        print '\t[  OK] Checking CRC...'
    else:
        print '\t[Fail] Checking CRC...'
        print "\tIt's %d, but should be %d" % (content['crc'], crc)
Ejemplo n.º 5
0
def table(
    table_file,
    pack_file_list,
):
    cur_file_id = 1
    next_free_byte = 0

    for filename in pack_file_list:
        with open(filename, 'rb') as data_file:
            content = data_file.read()
            length = len(content)
            table_file.write(
                struct.pack('<IIII', cur_file_id, next_free_byte, length,
                            stm32_crc.crc32(content)))
            cur_file_id += 1
            next_free_byte += length

    # pad the rest of the file
    for i in range(len(pack_file_list), MAX_NUM_FILES):
        table_file.write(struct.pack('<IIII', 0, 0, 0, 0))
Ejemplo n.º 6
0
def manifest(manifest_file, data_file, num_files, timestamp):
    data_file.seek(0)  # first rewind it..
    crc = stm32_crc.crc32(data_file.read())
    manifest_file.write(struct.pack('<III', int(num_files), crc, int(timestamp)))
Ejemplo n.º 7
0
def table(table_file, pack_file_list, ):
    cur_file_id = 1
    next_free_byte = 0

    for filename in pack_file_list:
        with open(filename, 'rb') as data_file:
            content = data_file.read()
            length = len(content)
            table_file.write(struct.pack('<IIII', cur_file_id, next_free_byte, length, stm32_crc.crc32(content)))
            cur_file_id += 1
            next_free_byte += length

    # pad the rest of the file
    for i in range(len(pack_file_list), MAX_NUM_FILES):
        table_file.write(struct.pack('<IIII', 0, 0, 0, 0))
        print " # Copying tintin_fw.bin..."
        shutil.copy(args.tintin_fw, workdir+'tintin_fw.bin')
        print " # Updating CRC value in tintin_fw.bin from 0x%08X to 0x%08X:" % (args.orig_crc or 0, newCrc)
        with open(workdir+'tintin_fw.bin', 'r+b') as tintin:
            updateCrc(tintin, newCrc, args.orig_crc, args.offset, args.replace_all)

        print " # Reading manifest..."
        with open(args.manifest, 'r') as f:
            manifest = json.load(f)

        print " # Updating manifest..."
        rp_size = os.path.getsize(args.respack)
        print "   res pack size = %d" % rp_size
        with open(args.respack) as f:
            rp_crc = crc32(f.read())
        print "   res pack crc = %d" % rp_crc
        tintin_size = os.path.getsize(workdir+"tintin_fw.bin")
        print "   tintin size = %d" % tintin_size
        with open(workdir+"tintin_fw.bin") as f:
            tintin_crc = crc32(f.read())
        print "   tintin crc = %d" % tintin_crc

        print " # Changing values:"
        print "  resources.size: %d => %d" % (manifest['resources']['size'], rp_size)
        manifest['resources']['size'] = rp_size
        print "  resources.crc: %d => %d" % (manifest['resources']['crc'], rp_crc)
        manifest['resources']['crc'] = rp_crc
        print "  firmware.size: %d => %d" % (manifest['firmware']['size'], tintin_size)
        manifest['firmware']['size'] = tintin_size
        print "  firmware.crc: %d => %d" % (manifest['firmware']['crc'], tintin_crc)
Ejemplo n.º 9
0
if __name__ == "__main__":
    name = sys.argv[1]
    company = sys.argv[2]
    
    raw = open('pebble-app.bin', 'rb').read()
    
    with open('pebble-app.bin', 'rb') as f:
        header = f.read(8+8+8+32+32+20)
        (magic, version, sdk_version, app_version, size, entry_point, crc, old_name, old_company, unknown3, jump_table, flags, reloc_list, num_relocs) = struct.unpack("<8sHHHHII32s32sIIIII", header)
        crc = long(crc)
        print (magic, version, sdk_version, app_version, size, entry_point, hex(crc), old_name, old_company, unknown3, jump_table, flags, reloc_list, num_relocs)
        binary = f.read()
        
        print "EXP: 0x%08X (%d)" % (crc,crc)
        rc = crc32(raw)
        print "RAW: 0x%08X (%d)" % (rc,rc)
        rc = crc32(binary)
        print "BIN: 0x%08X (%d)" % (rc,rc)
        
        
        
        with open("log.crc.txt", 'w') as f:
            for i in xrange(len(raw)+1):
                for j in xrange(i,len(raw)+1):
                    nc = crc32(raw[i:j])
                    if crc == nc:
                        print "(%d,%d) - %08X" % (i,j,crc)
                        f.write("(%d,%d) - %08X" % (i,j,crc))
                print "Pass %d of %d complete" % (i, len(raw))
                f.write("Pass %d of %d complete" % (i, len(raw)))
#!/usr/bin/env python

import sys
from libpebble.stm32_crc import crc32

if len(sys.argv) <= 1 or sys.argv[1] == '-h':
	print 'calculateCrc.py calculates STM32 CRC sum for a given file or stdin'
	print 'Usage: calculateCrc.py filename'
	print 'Use `-\' as filename to read from stdin.'
	exit()

filename = sys.argv[1]
f = sys.stdin if filename == '-' else open(filename, 'rb')
c = crc32(f.read())
print 'Checksum for %s:' % (filename if filename!='-' else '<stdin>')
print 'Hex: 0x%08X\nDec: %d' % (c, c)
Ejemplo n.º 11
0
     #WARNING: THE BELOW WORK ISN'T COMPLETE AND WILL ONLY WORK FOR BIG-TIME-12 and BIG-TIME-24
     raw = header + binary
     coda = binary[-(4*num_relocs):]
     rheader = binary[-132:-(4*num_relocs)]
     
     binary = binary[:-132]
     
     (resource_crc, resource_timestamp, resource_name) = struct.unpack("<LL16s", rheader[:24])
     
     
     pbp = validate_pbpack.PBPack(open("app_resources.pbpack", 'rb'))
     res_header = struct.pack("<LL16s", pbp.crc, pbp.timestamp, pbp.name)
     
     crheader = rheader[24:]
     
     crcs = [x.crc for x in pbp.resources]
     out_crc = ""
     for c in crcs:
         out_crc += struct.pack("<I", c)
     
     rheader = res_header + out_crc + rheader[24+len(out_crc):]
     
     print "EXP: 0x%08X (%d)" % (app_crc,app_crc)
     rc = crc32(binary+rheader)
     print "CRC: 0x%08X (%d)" % (rc,rc)
     header = struct.pack("<8sHHHHII32s32sIIIII", magic, version, sdk_version, app_version, size, entry_point, rc, old_name, old_company, unknown3, jump_table, flags, reloc_list, num_relocs)
     
     
 
 with open('pebble-app.bin', 'wb') as f:
     f.write(header + binary + rheader + coda)
Ejemplo n.º 12
0
    #log.info(p)
    
    manifest = None
    with open("manifest.json", "r") as mf:
        manifest = json.load(mf)
    
    if manifest is None:
        sys.exit(1)
    
    with open("app_resources.pbpack", "wb") as pbf:
        pbf.write("\0"*28)
        index = 1
        offset = 0
        raws = []
        for resource in manifest['debug']['resourceMap']['media']:
            fn = "%s.%s" % (resource['defName'],resource['type'])
            size = os.stat(fn).st_size
            raw = open(fn, 'rb').read()
            crc = crc32(raw)
            raws.append(raw)
            pbf.write(struct.pack("<LLLL", index, offset, size, crc))
            print "<Resource %2d @ %04x:%04x CRC:%08x>" % (index, offset, offset+size, crc)
            index += 1
            offset += size
        pbf.write("\0" * (4096+28-pbf.tell()))
        for raw in raws:
            pbf.write(raw)
        
        pbf.seek(0)
        pbf.write(struct.pack("<LLL16s", index-1, crc32(''.join(raws)), manifest['resources']['timestamp'], str(manifest['resources']['friendlyVersion'])))
Ejemplo n.º 13
0
def manifest(manifest_file, data_file, num_files, timestamp):
    data_file.seek(0)  # first rewind it..
    crc = stm32_crc.crc32(data_file.read())
    manifest_file.write(
        struct.pack('<III', int(num_files), crc, int(timestamp)))
Ejemplo n.º 14
0
import sys, struct
from libpebble.stm32_crc import crc32

if __name__ == "__main__":
    
    raw = open('pebble-app.bin', 'rb').read()
    
    with open('pebble-app.bin', 'rb') as f:
        header = f.read(8+8+8+32+32+20)
        (magic, version, sdk_version, app_version, size, entry_point, crc, old_name, old_company, unknown3, jump_table, flags, reloc_list, num_relocs) = struct.unpack("<8sHHHHII32s32sIIIII", header)
        crc = long(crc)
        print (magic, version, sdk_version, app_version, size, hex(entry_point), hex(crc), old_name, old_company, unknown3, hex(jump_table), flags, hex(reloc_list), num_relocs)
        binary = f.read()
        
        print "EXP: 0x%08X (%d)" % (crc,crc)
        rc = crc32(raw[108:len(raw)-(4*num_relocs)])
        print "MIN: 0x%08X (%d)" % (rc,rc)
        rc = crc32(binary)
        print "BIN: 0x%08X (%d)" % (rc,rc)
        
        (end1,end2) = struct.unpack("<II", binary[-8:])
        print "END1: 0x%08X (%d)" % (end1, end1)
        print "END2: 0x%08X (%d)" % (end2, end2)
        print "SIZE: 0x%08X (%d)" % (size, size)
        print "DIFF: 0x%08X (%d)" % (size-end1, size-end1)
        (en1,) = struct.unpack("<I", binary[end1-108:end1+4-108])
        (en2,) = struct.unpack("<I", binary[end2-108:end2+4-108])
        print "*EN1: 0x%08X (%d)" % (en1, en1)
        print "*EN2: 0x%08X (%d)" % (en2, en2)
        (n1,) = struct.unpack("<I", binary[en1-108:en1+4-108])
        (n2,) = struct.unpack("<I", binary[en2-108:en2+4-108])
Ejemplo n.º 15
0
#!/usr/bin/env python

import sys
from libpebble.stm32_crc import crc32

if len(sys.argv) <= 1 or sys.argv[1] == '-h':
    print 'calculateCrc.py calculates STM32 CRC sum for a given file or stdin'
    print 'Usage: calculateCrc.py filename'
    print 'Use `-\' as filename to read from stdin.'
    exit()

filename = sys.argv[1]
f = sys.stdin if filename == '-' else open(filename, 'rb')
c = crc32(f.read())
print 'Checksum for %s:' % (filename if filename != '-' else '<stdin>')
print 'Hex: 0x%08X\nDec: %d' % (c, c)
Ejemplo n.º 16
0
		print " # Copying tintin_fw.bin..."
		shutil.copy(args.tintin_fw, workdir+'tintin_fw.bin')
		print " # Updating CRC value in tintin_fw.bin from 0x%08X to 0x%08X:" % (args.orig_crc or 0, newCrc)
		with open(workdir+'tintin_fw.bin', 'r+b') as tintin:
			updateCrc(tintin, newCrc, args.orig_crc, args.offset)

		print " # Reading manifest..."
		with open(args.manifest, 'r') as f:
			manifest = json.load(f)

		print " # Updating manifest..."
		rp_size = os.path.getsize(args.respack)
		print "   res pack size = %d" % rp_size
		with open(args.respack) as f:
			rp_crc = crc32(f.read())
		print "   res pack crc = %d" % rp_crc
		with open(workdir+"tintin_fw.bin") as f:
			tintin_crc = crc32(f.read())
		print "   tintin crc = %d" % tintin_crc

		print " # Changing values:"
		print "  resources.size: %d => %d" % (manifest['resources']['size'], rp_size)
		manifest['resources']['size'] = rp_size
		print "  resources.crc: %d => %d" % (manifest['resources']['crc'], rp_crc)
		manifest['resources']['crc'] = rp_crc
		print "  firmware.crc: %d => %d" % (manifest['firmware']['crc'], tintin_crc)
		manifest['firmware']['crc'] = tintin_crc

		print " # Storing manifest..."
		with open(workdir+"manifest.json", "wb") as f:
Ejemplo n.º 17
0
def manifest(manifest_file_path, data_chunk_file, num_files, timestamp):
    with open(manifest_file_path, 'wb') as manifest_file:
        with open(data_chunk_file, 'rb') as data_file:
            crc = stm32_crc.crc32(data_file.read())
            manifest_file.write(struct.pack('<III', int(num_files), crc, int(timestamp)))
def extract_resources(pbpack, resourceMap, output_dir):
    numbers = unpack('B', pbpack.read(1))[0]
    print 'Resource pack has %d resources.' % numbers

    pbpack.seek(4)
    crc_from_json = unpack('I', pbpack.read(4))[0]
    print 'Resource pack claims to have crc 0x%X.' % crc_from_json

    offset = None  # this will be set depending on firmware version

    print 'Checking CRC with offset 0x100C (2.x)...'
    pbpack.seek(0x100C)
    crc_resource = crc32(pbpack.read())
    if crc_resource == crc_from_json:
        print '\t[  OK] This seems to be a 2.x firmware.'
        offset = 0x0C
    else:
        print '\t[Info] It is not 2.x firmware, or is corrupted, CRC=0x%08X' % crc_resource
        print 'Checking CRC with offset 0x101C (1.x)...'
        pbpack.seek(0x101C)
        crc_resource2 = crc32(pbpack.read())
        if crc_resource2 == crc_from_json:
            print '\t[  OK] This seems to be a 1.x firmware.'
            offset = 0x1C
        else:
            print '\t[Fail] CRC check failed!'
            print "\tShould be 0x%X, but if 0x%X for 100c and 0x%x for 101c." % (
                crc_from_json, crc_resource, crc_resource2)
            print 'Resource pack is either malformed or has unknown format.'
            return

    print 'Reading resurce headers...'
    resources = {}
    for i in range(numbers):
        pbpack.seek(offset + i * 16)
        index = unpack('i', pbpack.read(4))[0] - 1
        resources[index] = {
            'offset': unpack('i', pbpack.read(4))[0],
            'size': unpack('i', pbpack.read(4))[0],
            'crc': unpack('I', pbpack.read(4))[0]
        }

    for i in range(len(resources)):
        entry = resources[i]
        hasRM = resourceMap and i < len(resourceMap)
        path = resourceMap[i]['file'] if hasRM else 'res/%02d_%08X' % (
            i, entry['crc'])
        dirname = os.path.dirname(path)
        filepath = "/".join(
            (dirname, resourceMap[i]['defName'])) if hasRM else path

        print 'Extracting %s...' % filepath
        mkdir(output_dir + dirname)

        pbpack.seek(0x1000 + offset + entry['offset'])
        file = open(output_dir + filepath, 'wb')
        file.write(pbpack.read(entry['size']))
        file.close()

        data = io.FileIO(output_dir + filepath).readall()
        crc = crc32(data)
        if crc == entry['crc']:
            print '\t[  OK] Checking CRC...'
        else:
            print '\t[Fail] Checking CRC...'
            print "\tIt's 0x%x, but should be 0x%x" % (crc, entry['crc'])
    print 'All resources unpacked.'
def extract_resources(pbpack, resourceMap, output_dir):
    numbers = unpack('I', pbpack.read(4))[0]
    print('Resource pack has %d resources.' % numbers)

    pbpack.seek(4)
    crc_from_json = unpack('I', pbpack.read(4))[0]
    print('Resource pack claims to have crc 0x%X.' % crc_from_json)

    tbl_start = None  # this will be set depending on firmware version
    res_start = None

    offsets = [
        (0x200C, '3.x', 0x0C),
        (0x100C, '2.x', 0x0C),
        (0x101C, '1.x', 0x0C),
    ]
    for ofs, ver, tab in offsets:
        print('Checking CRC with offset {} ({})...'.format(hex(ofs), ver))
        pbpack.seek(ofs)
        crc_resource = crc32(pbpack.read())
        if crc_resource == crc_from_json:
            print('\t[  OK] This looks like {} firmware'.format(ver))
            tbl_start = tab
            res_start = ofs
            break
        else:
            print('\t[????] CRC mismatch: found 0x%X' % crc_resource)
    else:
        print('\t[Fail] CRC check failed!')
        print('\tShould be 0x%X' % crc_from_json)
        print('Resource pack is either malformed or has unknown format.')
        return

    print('Reading resurce headers...')
    resources = {}
    for i in range(numbers):
        pbpack.seek(tbl_start + i * 16)
        index = unpack('i', pbpack.read(4))[0] - 1
        resources[index] = {
            'offset': unpack('i', pbpack.read(4))[0],
            'size': unpack('i', pbpack.read(4))[0],
            'crc': unpack('I', pbpack.read(4))[0]
        }

    for i in range(len(resources)):
        entry = resources[i]
        hasRM = resourceMap and i < len(resourceMap)
        path = resourceMap[i]['file'] if hasRM else 'res/%03d_%08X' % (
            i+1, entry['crc'])
        dirname = os.path.dirname(path)
        filepath = ("/".join((dirname, resourceMap[i]['defName']))
                    if hasRM else path)

        print('Extracting %s...' % filepath)
        mkdir(output_dir + dirname)

        pbpack.seek(res_start + entry['offset'])
        file = open(output_dir + filepath, 'wb')
        file.write(pbpack.read(entry['size']))
        file.close()

        data = io.FileIO(output_dir + filepath).readall()
        crc = crc32(data)
        if crc == entry['crc']:
            print('\t[  OK] Checking CRC...')
        else:
            print('\t[Fail] Checking CRC...')
            print("\tIt's 0x%x, but should be 0x%x" % (crc, entry['crc']))
    print('All resources unpacked.')
Ejemplo n.º 20
0
    raw = open('pebble-app.bin', 'rb').read()

    with open('pebble-app.bin', 'rb') as f:
        header = f.read(8 + 8 + 8 + 32 + 32 + 20)
        (magic, version, sdk_version, app_version, size, entry_point, crc,
         old_name, old_company, unknown3, jump_table, flags, reloc_list,
         num_relocs) = struct.unpack("<8sHHHHII32s32sIIIII", header)
        crc = long(crc)
        print(magic, version, sdk_version, app_version, size, entry_point,
              hex(crc), old_name, old_company, unknown3, jump_table, flags,
              reloc_list, num_relocs)
        binary = f.read()

        print "EXP: 0x%08X (%d)" % (crc, crc)
        rc = crc32(raw)
        print "RAW: 0x%08X (%d)" % (rc, rc)
        rc = crc32(binary)
        print "BIN: 0x%08X (%d)" % (rc, rc)

        with open("log.crc.txt", 'w') as f:
            for i in xrange(len(raw) + 1):
                for j in xrange(i, len(raw) + 1):
                    nc = crc32(raw[i:j])
                    if crc == nc:
                        print "(%d,%d) - %08X" % (i, j, crc)
                        f.write("(%d,%d) - %08X" % (i, j, crc))
                print "Pass %d of %d complete" % (i, len(raw))
                f.write("Pass %d of %d complete" % (i, len(raw)))

    #struct.pack("<8sHHHHII32s32sIIIII"
Ejemplo n.º 21
0
    with open("manifest.json", "r") as mf:
        manifest = json.load(mf)

    if manifest is None:
        sys.exit(1)

    with open("app_resources.pbpack", "wb") as pbf:
        pbf.write("\0" * 28)
        index = 1
        offset = 0
        raws = []
        for resource in manifest['debug']['resourceMap']['media']:
            fn = "%s.%s" % (resource['defName'], resource['type'])
            size = os.stat(fn).st_size
            raw = open(fn, 'rb').read()
            crc = crc32(raw)
            raws.append(raw)
            pbf.write(struct.pack("<LLLL", index, offset, size, crc))
            print "<Resource %2d @ %04x:%04x CRC:%08x>" % (index, offset,
                                                           offset + size, crc)
            index += 1
            offset += size
        pbf.write("\0" * (4096 + 28 - pbf.tell()))
        for raw in raws:
            pbf.write(raw)

        pbf.seek(0)
        pbf.write(
            struct.pack("<LLL16s", index - 1, crc32(''.join(raws)),
                        manifest['resources']['timestamp'],
                        str(manifest['resources']['friendlyVersion'])))
Ejemplo n.º 22
0
from libpebble.stm32_crc import crc32
import json, os, os.path
from zipfile import ZipFile

if __name__ == "__main__":
    manifest = json.load(open("manifest.json"))
    
    manifest["resources"]["crc"] = crc32(open("app_resources.pbpack", 'rb').read())
    s = os.stat("app_resources.pbpack")
    manifest["resources"]["size"] = s.st_size
    manifest["resources"]["timestamp"] = int(s.st_ctime)
    
    manifest["application"]["crc"] = crc32(open("pebble-app.bin", 'rb').read())
    s = os.stat("pebble-app.bin")
    manifest["application"]["size"] = s.st_size
    manifest["application"]["timestamp"] = int(s.st_ctime)
    
    with open("manifest.json", "wb") as f:
        json.dump(manifest, f)
    
    with ZipFile("%s.pbw" % os.path.basename(os.getcwd()), 'w') as app:
        app.write("manifest.json")
        app.write("app_resources.pbpack")
        app.write("pebble-app.bin")
def extract_resources(pbpack, resourceMap, output_dir):
	numbers = unpack('B', pbpack.read(1))[0]
	print 'Resource pack has %d resources.' % numbers

	pbpack.seek(4)
	crc_from_json = unpack('I', pbpack.read(4))[0]
	print 'Resource pack claims to have crc 0x%X.' % crc_from_json

	offset=None # this will be set depending on firmware version

	print 'Checking CRC with offset 0x100C (2.x)...'
	pbpack.seek(0x100C)
	crc_resource = crc32(pbpack.read())
	if crc_resource == crc_from_json:
		print '\t[  OK] This seems to be a 2.x firmware.'
		offset = 0x0C
	else:
		print '\t[Info] It is not 2.x firmware, or is corrupted, CRC=0x%08X' % crc_resource
		print 'Checking CRC with offset 0x101C (1.x)...'
		pbpack.seek(0x101C)
		crc_resource2 = crc32(pbpack.read())
		if crc_resource2 == crc_from_json:
			print '\t[  OK] This seems to be a 1.x firmware.'
			offset = 0x1C
		else:
			print '\t[Fail] CRC check failed!'
			print "\tShould be 0x%X, but if 0x%X for 100c and 0x%x for 101c." % (
					crc_from_json, crc_resource, crc_resource2)
			print 'Resource pack is either malformed or has unknown format.'
			return

	print 'Reading resurce headers...'
	resources = {}
	for i in range(numbers):
		pbpack.seek(offset + i * 16)
		index = unpack('i', pbpack.read(4))[0] - 1
		resources[index] = {
			'offset': unpack('i', pbpack.read(4))[0],
			'size': unpack('i', pbpack.read(4))[0],
			'crc': unpack('I', pbpack.read(4))[0]
		}

	for i in range(len(resources)):
		entry = resources[i]
		hasRM = resourceMap and i < len(resourceMap)
		path = resourceMap[i]['file'] if hasRM else 'res/%02d_%08X' % (i, entry['crc'])
		dirname = os.path.dirname(path)
		filepath = "/".join((dirname, resourceMap[i]['defName'])) if hasRM else path

		print 'Extracting %s...' % filepath
		mkdir(output_dir + dirname)

		pbpack.seek(0x1000 + offset + entry['offset'])
		file = open(output_dir + filepath, 'wb')
		file.write(pbpack.read(entry['size']))
		file.close()

		data = io.FileIO(output_dir + filepath).readall()
		crc = crc32(data)
		if crc == entry['crc']:
			print '\t[  OK] Checking CRC...'
		else:
			print '\t[Fail] Checking CRC...'
			print "\tIt's 0x%x, but should be 0x%x" % (crc, entry['crc'])
	print 'All resources unpacked.'
Ejemplo n.º 24
0
def extract_resources(pbpack, resourceMap, output_dir):
    numbers = unpack('I', pbpack.read(4))[0]
    print('Resource pack has %d resources.' % numbers)

    pbpack.seek(4)
    crc_from_json = unpack('I', pbpack.read(4))[0]
    print('Resource pack claims to have crc 0x%X.' % crc_from_json)

    tbl_start = None  # this will be set depending on firmware version
    res_start = None

    offsets = [
        (0x200C, '3.x', 0x0C),
        (0x100C, '2.x', 0x0C),
        (0x101C, '1.x', 0x0C),
    ]
    for ofs, ver, tab in offsets:
        print('Checking CRC with offset {} ({})...'.format(hex(ofs), ver))
        pbpack.seek(ofs)
        crc_resource = crc32(pbpack.read())
        if crc_resource == crc_from_json:
            print('\t[  OK] This looks like {} firmware'.format(ver))
            tbl_start = tab
            res_start = ofs
            break
        else:
            print('\t[????] CRC mismatch: found 0x%X' % crc_resource)
    else:
        print('\t[Fail] CRC check failed!')
        print('\tShould be 0x%X' % crc_from_json)
        print('Resource pack is either malformed or has unknown format.')
        return

    print('Reading resurce headers...')
    resources = {}
    for i in range(numbers):
        pbpack.seek(tbl_start + i * 16)
        index = unpack('i', pbpack.read(4))[0] - 1
        resources[index] = {
            'offset': unpack('i', pbpack.read(4))[0],
            'size': unpack('i', pbpack.read(4))[0],
            'crc': unpack('I', pbpack.read(4))[0]
        }

    for i in range(len(resources)):
        entry = resources[i]
        hasRM = resourceMap and i < len(resourceMap)
        path = resourceMap[i]['file'] if hasRM else 'res/%03d_%08X' % (
            i + 1, entry['crc'])
        dirname = os.path.dirname(path)
        filepath = ("/".join(
            (dirname, resourceMap[i]['defName'])) if hasRM else path)

        print('Extracting %s...' % filepath)
        mkdir(output_dir + dirname)

        pbpack.seek(res_start + entry['offset'])
        file = open(output_dir + filepath, 'wb')
        file.write(pbpack.read(entry['size']))
        file.close()

        data = io.FileIO(output_dir + filepath).readall()
        crc = crc32(data)
        if crc == entry['crc']:
            print('\t[  OK] Checking CRC...')
        else:
            print('\t[Fail] Checking CRC...')
            print("\tIt's 0x%x, but should be 0x%x" % (crc, entry['crc']))
    print('All resources unpacked.')