Dec 4
So the methodology has currently been trying to proceed as quickly as possible, trying to get every device working and aiming for breadth instead of stability. This allows me to do more high-value tasks like reverse engineering, rapidly gaining understanding of the platform instead of just getting bogged down debugging every single thing. Unfortunately, we're paying a bit for it now as I try to get things into gear to put together applications.

First thing is, I don't really trust the current memory structure. For one thing, it's WEIRD. It seems like even if I turn the MMU off, 0x0 is still mapped to 0x18000000. I know the MMU is working, somewhat, because if I allow the heap to run into the place I put my pagetable, bad things happen. =P I understand there's not going to be enough devices or memory to fill out the entire 32-bit address space, though, so maybe there was already some sort of static mapping. I also believe 0x9000000 (the range used by iboot's file transfer facility) is mapped to 0x18100000. That is, 0x0 == 0x80000000 == 0x18000000. The problem is that there are no such mappings in the page table. 0x80000000 to 0x180000000 is set cacheable and bufferable, but is identity mapped. Anyone have enough experience with the hardware to tell me if this makes sense? I mean, maybe it's just that the top 4 bits are just completely ignored by the memory controller.

Second thing is, sometimes I get random freeze-ups and I don't know why. Maybe I'm just hallucinating or screwing up somewhere, or maybe it's just me failing at C (wouldn't be the first time this happened). Anyway, the upshot is, I want to go back through and clean up/refactor the code into its final form. I tried to follow best programming practices as much as possible the first time around, but sometimes it just was too inefficient to do so when dealing with only half-way reverse engineered device drivers.

The third thing is what I'm working on currently. I need openiboot to replace iBoot. I currently have written a pretty simple chainloader. All it does is warm up all the devices as usual, and then load iBoot from NOR and then jumps to it. iBoot is relocateable and should be able to get itself to the right place. Now this works fine from a copy of openiboot that is started from iBoot using "go", but after I flash openiboot onto the "ibot" image in NOR, the device goes straight to DFU. Now either I'm screwing up hardware initialization or there is some additional verification (checksums, probably not signatures) done before LLB wants to load iboot. It may be that the latter is more likely, since I end up in DFU mode rather than a hung device. Not sure if the device is intelligent enough to recognize a failed boot if I don't say, update the powernvram.

After I get this working, the next thing is to see if the gamma table stuff works then (and if not, fix it). After that, the boot menu I talked about can be written. The next thing I want to work on is NAND FTL. That's the last piece before we reach the end of the "openiboot" phase and can move into the Linux phase. Pretty much all the drivers people expect will be ready and the fun can begin.

I know it seems like we're still very far, but I think we've made very concrete and tremendous progress in a fairly reasonable period of time. A lot of things are now clear and the biggest obstacles are not Apple's protections, or a lack of understanding, but merely my own stupid mistakes and typos.

Speaking of horribly stupid mistakes, my next post will be the story of how I almost bricked my phone yesterday night (but not really :P).

Tagi: freeze ups, memory structure, static mapping, programming practices, mmu, sime, single thing, address space, reverse engineering, device drivers, mappings, upshot, file transfer, ups, breadth, heap, methodology, ace

Dec 4
New Ramdisk
Posted by George Hotz in ramdisk, crypt on 12 4th, 2008| icon3
In the KBAG section of the img3 files, you'll find 0x20 bytes after the section header. Decrypt them with the hardware AES engine and get
IV: 29681F625D1F61271EC3116601B8BCDE
KEY: 850AFC271132D15AE6989565567E65BF
(this is the 2.0 ramdisk)

Tagi: ramdisk, crypt

Nov 24
While I was waiting for CPICH to finish the first bits of the NAND FTL reverse engineering work, I've been trying to fill in some of the gaps we had in other places, such as the PMU. As promised, there is also now an easy way to install openiboot onto the iPhone. This is great because it will eventually lead to an even leaner and easier QuickPwn in the future.

One of the annoying parts about iBoot in recovery mode is that the thing refuses to charge the iPhone while sitting in recovery mode. The battery just eventually entirely drains. With the new PMU code, openiboot now recharges the battery, so programmers using it (read: me) can just have it sit on the console screen indefinitely. You can also do neat things like check the current battery voltage and check the power supply type the phone is charging from.

The "installation code" consists of porting over my knowledge of reading and modifying img3 files from working on the jailbreaks. I was too lazy to port over the entire xpwn framework, but I wrote up a "diet" version that is sufficient to read and modify img3 files in a limited fashion. img3 files are sort of the new native format of the main part of the NOR (just a bunch of img3 files concatenated together). The upshot is that you can load openiboot as an img3 through iBoot (just like sending an iBEC image) and then type "install" at the console and openiboot will be a permanent stage in your bootloader chain. =P

You can, of course, keep booting up to the iPhone OS as you always do by selecting the option in the boot menu. Installing openiboot isn't very useful except for hackers wanting to hack openiboot.

I also figured out how to parse and modify the NVRAM banks (storing environment variables like "auto-boot", etc.), which was actually pointless complicated (in my opinion). They have two banks consisting of a bunch of partitions with these headers that Apple uses a pointless one-byte custom checksum on. The entire bank is also checksumed with adler32. When NVRAM is modified, the oldest bank is overwritten with the data and becomes the newest bank (which is tracked by an epoch number on each bank). This is so if one bank becomes corrupted, the other can be used as a backup. However, NVRAM hardly contains anything high value so the value of all this trouble is doubtful. Being able to write to NVRAM, though, makes it possible to set auto-boot on and off within openiboot so that we can easily control whether or not to enter iBoot's recovery mode.

Someone asked me how "safe" it was to do the installation, etc. Well, I've been doing it every time I make an update these days, so it's fairly safe. The worst that can happen in the usual case is that you may be forced into a DFU mode restore. Everything will be undone with a restore. Early on, I did have bugs that really screwed things up so that a DFU mode restore was no longer possible, but even that was recoverable. I'll just go over how briefly:

The important thing is to have a backup of the NOR. As I described in a previous posting, it's possible to really screw things up if you erase the SysCfg section of the NOR. If you do that, the iPhone OS will refuse to boot at all since iBoot cannot properly populate the device tree for the kernel. Since restore ramdisks rely on XNU booting, this is Bad News Bears. In addition, the SysCfg section is device specific, so if you do not have a backup, it will be difficult to ever completely recover from erasing it.

Therefore, before you proceed, MAKE A BACKUP OF YOUR NOR. openiboot can do this for you (and subsequently restore your backup if things go wrong).

Load openiboot via loadibec and select the console. Connect with the oibc client. Type in: nor_read 0x09000000 0x0 0x100000

This will read all of NOR into memory. Then type: ~nordump.bin:0x100000

This will transfer the dump over USB onto your computer and save it as nordump.bin.

Supposing you filled the entire NOR with garbage somehow and are unable to boot. You have to get into openiboot to restore the NOR. The problem is that openiboot is only designed to operate in a post-LLB or post-Recovery Mode context, so it cannot be directly booted from DFU mode. Basically, you've got to load a pwned WTF, then a pwned iBSS, and then a pwned iBEC (all of which is available from a custom IPSW). After that, you can use loadibec to load openiboot. Then, you can restore the NOR thus:

!nordump.bin
nor_write 0x09000000 0x0 0x100000

After that, you can reboot and everything should be normal.

Also, I received a few responses for people volunteering to do the art. I'm not sure what the best thing would be, since I don't want anyone putting in effort for nothing, but we do want the best possible results. So, I'll be getting back to you guys about that.

Tagi: recovery mode, csts, fashi, boot menu, auto boot, battery voltage, promed, pmu, iphe, nand, iboot, phe, upshot, opti, aces, gaps, programmers, hackers, variables, banks

next >