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 __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)
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))
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)))
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)
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)
#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)
#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'])))
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)))
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])
#!/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)
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:
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.')
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"
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'])))
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.'
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.')