Decrypting the iOS kernel cache on devices with an A4 or lower CPU is relatively straight forward thanks to the limera1n boot exploit. This allows the extraction of the IV & Keys for each file within the IPSW software bundle which are published on the iPhone Wiki
. Each time new firmware package is released the keys are updated.
I believe it is possible to dump the kernel cache from a device with an A5 and greater chip but so far I haven't played with this. This has to be done from memory rather than extracting from the IPSW which is more complex.
To decrypt your kernel you first need to download a copy of the IPSW package for your device, I'm going to use the iPhone 4 GSM 7.0.4 firmware available here:
Once the firmware has downloaded you can simply unzip the IPSW file and extract the contents, you should have the following:
The file you are interested in is kernelcache.release.xx. In this instance, the file we want is kernelcache.release.n90. n90 is specific device identifier for the iPhone 4, each device will have it's own identifier. If you are using an iPad or iPod then the identifier here will be different.
The kernel is an img3 format file that is encrypted and also compressed using lzss so we need to decrypt it then decompress it.
To decrypt you can use either xpwn or decodeimg3, I opted for decodeimg3 as it was a single perl script! You can download decodeimg3 from here:
I had a couple of issues running the script first off as I didn't have "Crypt::Rijndael" perl module installed (info on installing perl modules here). Once this was installed it worked fine.
To decrypt the kernelcache you will also need the IV and Key from the iPhone wiki for the specific firmware build you are interested in. The iPhone 4 GSM IV & Key can be found here:
Once you are on that page locate the IV & Key for kernelcache.release.n90 as below, you will need them in a minute:
To decrypt your extracted kernel use the following command:
$ ./decodeimg3 <YOUR KERNEL> -v -o <DECRYPTED KERNEL> -k <KEY FROM WIKI> -iv <IV FROM WIKI>
- <YOUR KERNEL> = kernelcache.release.n90 we extracted from IPSW earlier.
- -v = Verbose
- -o = Output file, I use the same file name and append .lzss as it is easy to see it's lzss for decompressing.
- -k = Key from wiki
- -iv = IV from wiki
Below is the output from decrypting the kernel:
Next step is to decompress the kernel using lzssdec, the source code can be found here:
You will need to compile this, I used the following command to compile it on OSX:
$ g++ lzssdec.cpp -o lzssdec
Now you need to know the offset at where the lzss section starts. Opening the decrypted and uncompressed kernel in a hex editor and looking for 0xFEEDFACE should show you the offset. The screen shot below shows this:
The offset we need is 0x0180 to decompress our kernelcache.release.n90.lzss file.
Using the lzssdec tool we compiled earlier, the correct offset and our decrypted kernel, we can now decompress to give us a mach-0 arm binary using the command below:
$ lzssdec -o 0x0180 < kernelcache.release.n90.lzss > kernelcache.release.n90.cleartext
To check you have a decrypted and decompressed mach-o ARM binary use the following:
$ file kernelcache.release.n90.cleartext
The binary should open up in IDAPro
so you can disassemble and reverse the kernel further :)
- Willem Hengeveld for his scripts and tools (decodeimg3 & lzssdec).
- Jonathan Levin for the book OSX & iOS Internals, an excellent reference.
- The iPhoneWiki, best iOS resource on the www!