def main(ipswname, model_id, outdir): ipsw = zipfile.ZipFile(ipswname) manifest = plistlib.readPlistFromString(ipsw.read("BuildManifest.plist")) kernelname = manifest["BuildIdentities"][0]["Manifest"]["KernelCache"][ "Info"]["Path"] kernel = ipsw.read(kernelname) keys = IPSWkeys(manifest, outdir) key, iv = keys.getKeyIV(kernelname) if key == None: print "No keys found for kernel" return #- print "Decrypting %s" % kernelname kernel = decryptImg3(kernel, key.decode("hex"), iv.decode("hex")) assert kernel.startswith( "complzss" ), "Decrypted kernelcache does not start with \"complzss\" => bad key/iv ?" #- print "Unpacking ..." kernel = decompress_lzss(kernel) assert kernel.startswith( "\xCE\xFA\xED\xFE" ), "Decompressed kernelcache does not start with 0xFEEDFACE" for p in patchs_ios5: #- print "Doing %s patch" % p s, r = patchs_ios5[p] c = kernel.count(s) if c != 1: print "=> FAIL, count=%d, do not boot that kernel it wont work" % c else: kernel = kernel.replace(s, r) outkernel = "%s/%s.kernelcache" % (outdir, model_id) open(outkernel, "wb").write(kernel) #- print "Patched kernel written to %s" % outkernel ramdiskname = manifest["BuildIdentities"][0]["Manifest"]["RestoreRamDisk"][ "Info"]["Path"] key, iv = keys.getKeyIV("Ramdisk") build_options = "OK %s %s %s" % (ramdiskname, key, iv) print "%s" % build_options
def main(ipswname, model_id, outdir): ipsw = zipfile.ZipFile(ipswname) manifest = plistlib.readPlistFromString(ipsw.read("BuildManifest.plist")) kernelname = manifest["BuildIdentities"][0]["Manifest"]["KernelCache"]["Info"]["Path"] kernel = ipsw.read(kernelname) keys = IPSWkeys(manifest, outdir) key,iv = keys.getKeyIV(kernelname) if key == None: print "No keys found for kernel" return #- print "Decrypting %s" % kernelname kernel = decryptImg3(kernel, key.decode("hex"), iv.decode("hex")) assert kernel.startswith("complzss"), "Decrypted kernelcache does not start with \"complzss\" => bad key/iv ?" #- print "Unpacking ..." kernel = decompress_lzss(kernel) assert kernel.startswith("\xCE\xFA\xED\xFE"), "Decompressed kernelcache does not start with 0xFEEDFACE" for p in patchs_ios5: #- print "Doing %s patch" % p s, r = patchs_ios5[p] c = kernel.count(s) if c != 1: print "=> FAIL, count=%d, do not boot that kernel it wont work" % c else: kernel = kernel.replace(s,r) outkernel = "%s/%s.kernelcache" % (outdir, model_id) open(outkernel, "wb").write(kernel) #- print "Patched kernel written to %s" % outkernel ramdiskname = manifest["BuildIdentities"][0]["Manifest"]["RestoreRamDisk"]["Info"]["Path"] key,iv = keys.getKeyIV("Ramdisk") build_options = "OK %s %s %s" % (ramdiskname, key, iv) print "%s" % build_options
def main(ipswname, options): ipsw = zipfile.ZipFile(ipswname) manifest = plistlib.readPlistFromString(ipsw.read("BuildManifest.plist")) kernelname = manifest["BuildIdentities"][0]["Manifest"]["KernelCache"]["Info"]["Path"] kernel = ipsw.read(kernelname) keys = IPSWkeys(manifest) key,iv = keys.getKeyIV(kernelname) if key == None: print "No keys found for kernel" return print "Decrypting %s" % kernelname kernel = decryptImg3(kernel, key.decode("hex"), iv.decode("hex")) assert kernel.startswith("complzss"), "Decrypted kernelcache does not start with \"complzss\" => bad key/iv ?" print "Unpacking ..." kernel = decompress_lzss(kernel) assert kernel.startswith("\xCE\xFA\xED\xFE"), "Decompressed kernelcache does not start with 0xFEEDFACE" patchs = patchs_ios5 if manifest["ProductVersion"].startswith("4."): print "Using iOS 4 kernel patches" patchs = patchs_ios4 if options.fixnand: if patchs != patchs_ios4: print "FAIL : use --fixnand with iOS 4.x IPSW" return patchs.update(patchs_ios4_fixnand) kernelname = "fix_nand_" + kernelname print "WARNING : only use this kernel to fix NAND epoch brick" for p in patchs: print "Doing %s patch" % p s, r = patchs[p] c = kernel.count(s) if c != 1: print "=> FAIL, count=%d, do not boot that kernel it wont work" % c else: kernel = kernel.replace(s,r) outkernel = "%s.patched" % kernelname open(outkernel, "wb").write(kernel) print "Patched kernel written to %s" % outkernel ramdiskname = manifest["BuildIdentities"][0]["Manifest"]["RestoreRamDisk"]["Info"]["Path"] key,iv = keys.getKeyIV("Ramdisk") build_cmd = "./build_ramdisk.sh %s %s %s %s" % (ipswname, ramdiskname, key, iv) rs_cmd = "redsn0w -i %s -r myramdisk.dmg -k %s" % (ipswname, outkernel) rdisk_script="""#!/bin/sh for VER in 4.2 4.3 5.0 do if [ -f "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS$VER.sdk/System/Library/Frameworks/IOKit.framework/IOKit" ]; then SDKVER=$VER echo "Found iOS SDK $SDKVER" break fi done if [ "$SDKVER" == "" ]; then echo "iOS SDK not found" exit fi SDKVER=$SDKVER make -C ramdisk_tools %s echo "You can boot the ramdisk using the following command (fix paths)" echo "%s" """ % (build_cmd, rs_cmd) devclass = manifest["BuildIdentities"][0]["Info"]["DeviceClass"] scriptname="make_ramdisk_%s.sh" % devclass f=open(scriptname, "wb") f.write(rdisk_script) f.close() print "Created script %s, you can use it to (re)build the ramdisk"% scriptname
def main(ipswname, options): ipsw = zipfile.ZipFile(ipswname) ipswname = os.path.basename(ipswname) manifest = plistlib.readPlistFromString(ipsw.read("BuildManifest.plist")) kernelname = manifest["BuildIdentities"][0]["Manifest"]["KernelCache"]["Info"]["Path"] devclass = manifest["BuildIdentities"][0]["Info"]["DeviceClass"] kernel = ipsw.read(kernelname) keys = IPSWkeys(manifest) key,iv = keys.getKeyIV(kernelname) if key == None: print "No keys found for kernel" return -1 print "Decrypting %s" % kernelname kernel = decryptImg3(kernel, key.decode("hex"), iv.decode("hex")) assert kernel.startswith("complzss"), "Decrypted kernelcache does not start with \"complzss\" => bad key/iv ?" print "Unpacking ..." kernel = decompress_lzss(kernel) assert kernel.startswith("\xCE\xFA\xED\xFE"), "Decompressed kernelcache does not start with 0xFEEDFACE" patchs = patchs_ios5 if devclass in ["n82ap", "n72ap"]: print "Using ARMv6 kernel patches" patchs = patchs_armv6 elif manifest["ProductVersion"].startswith("4."): print "Using iOS 4 kernel patches" patchs = patchs_ios4 elif manifest["ProductVersion"].startswith("6."): print "Using iOS 6 kernel patches" patchs = patchs_ios6 if options.fixnand: if patchs != patchs_ios4: print "FAIL : use --fixnand with iOS 4.x IPSW" return patchs.update(patchs_ios4_fixnand) kernelname = "fix_nand_" + kernelname print "WARNING : only use this kernel to fix NAND epoch brick" patchfail = False for p in patchs: print "Doing %s patch" % p s, r = patchs[p] c = kernel.count(s) if c != 1: print "=> FAIL, count=%d, do not boot that kernel it wont work" % c patchfail = True else: kernel = kernel.replace(s,r) if patchfail: return -1 if manifest["ProductVersion"] >= "5.0": kernel = patch_IOFlashControllerUserClient_externalMethod(ipswname, kernel) ipswname = ipswname.replace("_Restore.ipsw", "") outkernel = "data/boot/kernel_%s.patched" % ipswname f = open(outkernel, "wb") f.write(kernel) f.close() print "Patched kernel written to %s" % outkernel ramdiskname = manifest["BuildIdentities"][0]["Manifest"]["RestoreRamDisk"]["Info"]["Path"] key,iv = keys.getKeyIV("Ramdisk") ramdisk = ipsw.read(ramdiskname) print "Decrypting %s" % ramdiskname ramdisk = decryptImg3(ramdisk, key.decode("hex"), iv.decode("hex")) assert ramdisk[0x400:0x402] == "H+", "H+ magic not found in decrypted ramdisk => bad key/iv ?" customramdisk = "data/boot/ramdisk_%s.dmg" % ipswname if os.path.exists(customramdisk): print "Ramdisk %s already exists" % customramdisk return f = open(customramdisk, "wb") f.write(ramdisk) f.close() print "Decrypted ramdisk written to %s" % customramdisk
def main(ipswname, options): ipsw = zipfile.ZipFile(ipswname) manifest = plistlib.readPlistFromString(ipsw.read("BuildManifest.plist")) kernelname = manifest["BuildIdentities"][0]["Manifest"]["KernelCache"][ "Info"]["Path"] devclass = manifest["BuildIdentities"][0]["Info"]["DeviceClass"] kernel = ipsw.read(kernelname) keys = IPSWkeys(manifest) key, iv = keys.getKeyIV(kernelname) if key == None: print "No keys found for kernel" return # print "Decrypting %s" % kernelname kernel = decryptImg3(kernel, key.decode("hex"), iv.decode("hex")) assert kernel.startswith( "complzss" ), "Decrypted kernelcache does not start with \"complzss\" => bad key/iv ?" # print "Unpacking ..." kernel = decompress_lzss(kernel) assert kernel.startswith( "\xCE\xFA\xED\xFE" ), "Decompressed kernelcache does not start with 0xFEEDFACE" patchs = patchs_ios5 if devclass in ["n82ap", "n72ap"]: # print "Using ARMv6 kernel patches" patchs = patchs_armv6 elif manifest["ProductVersion"].startswith("4."): # print "Using iOS 4 kernel patches" patchs = patchs_ios4 if options.fixnand: if patchs != patchs_ios4: print "FAIL : use --fixnand with iOS 4.x IPSW" return patchs.update(patchs_ios4_fixnand) kernelname = "fix_nand_" + kernelname # print "WARNING : only use this kernel to fix NAND epoch brick" for p in patchs: # print "Doing %s patch" % p s, r = patchs[p] c = kernel.count(s) if c != 1: print "=> FAIL, count=%d, do not boot that kernel it wont work" % c else: kernel = kernel.replace(s, r) outkernel = "%s.patched" % kernelname open(outkernel, "wb").write(kernel) # print "Patched kernel written to %s" % outkernel ramdiskname = manifest["BuildIdentities"][0]["Manifest"]["RestoreRamDisk"][ "Info"]["Path"] key, iv = keys.getKeyIV("Ramdisk") customramdisk = "myramdisk_%s.dmg" % devclass build_cmd = "./build_ramdisk.sh %s %s %s %s %s" % (ipswname, ramdiskname, key, iv, customramdisk) print ' '.join([ipswname, ramdiskname, key, iv, customramdisk, outkernel]) #print "{} {} {} {} {}".format(ipswname, ramdiskname, key, iv, customramdisk) return rs_cmd = "redsn0w -i %s -r %s -k %s" % (ipswname, customramdisk, outkernel) rdisk_script = """#!/bin/sh for VER in 4.2 4.3 5.0 5.1 6.0 6.1 do if [ -f "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS$VER.sdk/System/Library/Frameworks/IOKit.framework/IOKit" ]; then SDKVER=$VER echo "Found iOS SDK $SDKVER" break fi done if [ "$SDKVER" == "" ]; then echo "iOS SDK not found" exit fi SDKVER=$SDKVER make -C ramdisk_tools %s if [ "$?" == "0" ] then echo "You can boot the ramdisk using the following command (fix paths)" echo "%s" echo "Add -a \\"-v rd=md0 nand-disable=1\\" for nand dump/read only access" fi """ % (build_cmd, rs_cmd) scriptname = "make_ramdisk_%s.sh" % devclass f = open(scriptname, "wb") f.write(rdisk_script) f.close() print "Created script %s, you can use it to (re)build the ramdisk" % scriptname
def main(ipswname, options): ipsw = zipfile.ZipFile(ipswname) ipswname = os.path.basename(ipswname) manifest = plistlib.readPlistFromString(ipsw.read("BuildManifest.plist")) kernelname = manifest["BuildIdentities"][0]["Manifest"]["KernelCache"][ "Info"]["Path"] devclass = manifest["BuildIdentities"][0]["Info"]["DeviceClass"] kernel = ipsw.read(kernelname) keys = IPSWkeys(manifest) key, iv = keys.getKeyIV(kernelname) if key == None: print "No keys found for kernel" return -1 print "Decrypting %s" % kernelname kernel = decryptImg3(kernel, key.decode("hex"), iv.decode("hex")) assert kernel.startswith( "complzss" ), "Decrypted kernelcache does not start with \"complzss\" => bad key/iv ?" print "Unpacking ..." kernel = decompress_lzss(kernel) assert kernel.startswith( "\xCE\xFA\xED\xFE" ), "Decompressed kernelcache does not start with 0xFEEDFACE" patchs = patchs_ios5 if devclass in ["n82ap", "n72ap"]: print "Using ARMv6 kernel patches" patchs = patchs_armv6 elif manifest["ProductVersion"].startswith("4."): print "Using iOS 4 kernel patches" patchs = patchs_ios4 elif manifest["ProductVersion"].startswith("6."): print "Using iOS 6 kernel patches" patchs = patchs_ios6 if options.fixnand: if patchs != patchs_ios4: print "FAIL : use --fixnand with iOS 4.x IPSW" return patchs.update(patchs_ios4_fixnand) kernelname = "fix_nand_" + kernelname print "WARNING : only use this kernel to fix NAND epoch brick" patchfail = False for p in patchs: print "Doing %s patch" % p s, r = patchs[p] c = kernel.count(s) if c != 1: print "=> FAIL, count=%d, do not boot that kernel it wont work" % c patchfail = True else: kernel = kernel.replace(s, r) if patchfail: return -1 if manifest["ProductVersion"] >= "5.0": kernel = patch_IOFlashControllerUserClient_externalMethod( ipswname, kernel) ipswname = ipswname.replace("_Restore.ipsw", "") outkernel = "data/boot/kernel_%s.patched" % ipswname f = open(outkernel, "wb") f.write(kernel) f.close() print "Patched kernel written to %s" % outkernel ramdiskname = manifest["BuildIdentities"][0]["Manifest"]["RestoreRamDisk"][ "Info"]["Path"] key, iv = keys.getKeyIV("Ramdisk") ramdisk = ipsw.read(ramdiskname) print "Decrypting %s" % ramdiskname ramdisk = decryptImg3(ramdisk, key.decode("hex"), iv.decode("hex")) assert ramdisk[ 0x400: 0x402] == "H+", "H+ magic not found in decrypted ramdisk => bad key/iv ?" customramdisk = "data/boot/ramdisk_%s.dmg" % ipswname if os.path.exists(customramdisk): print "Ramdisk %s already exists" % customramdisk return f = open(customramdisk, "wb") f.write(ramdisk) f.close() print "Decrypted ramdisk written to %s" % customramdisk