Partition LwVM table
The iBoot exploit discussed in this writeup is relying on an insecure implementation of the HFS+ file system parser on iBoot versions older than iOS 5.x (included). It does not parse the HFS+ header securely, leading to a heap buffer overflow if some values are set to big numbers. This corrupted file system header might be still readable by a fixed HFS+ parser code, but the one compiled within iOS 5.x iBoot (and older versions) won't be able to and will trigger a heap buffer overflow.
Such kind of iBoot exploits that are triggered from file system have some important considerations when implemented. If the corrupted HFS+ file system is used as System partition for iOS, a vulnerable iBoot version will not be able to mount that file system to search for the kernelcache or upgrade routine images (in case of an OTA update). The corrupted HFS+ file system can only be used to trigger the exploit, not to be mounted.
To get around of this issue, we are going to create a third partition and set it as the boot one. Then, iBoot will try mount the corrupted HFS+ file system of that third partition instead of mounting the one of the System partition by default. We will also be able to use this third partition to dry-run our implementation of the exploit before attacking the main bootchain.
Before you attempt to re-partition the disk of your iOS device, I recommand you read the partition LwVM table guide I wrote for my iOS multiboot writeup here to give you a basic idea of what you will have to do.
It contains most of the information you will need to succeed without ending up with a bootlooped device. However, there are some important differences in this process between an iBoot exploit like that one and an iOS multiboot setup.
We will do re-partitionning in four steps.
- Calculate the size of partitions according to our projected configuration.
- Resize the LwVM container of the data partition.
- Delete all existing GPT partitions (including System), then recreate all of them with the new size you want. This will be a dangerous operation, just saying.
- Resize the LwVM container of the System partition to have it get the new size.
Execute gptfdisk with the disk volume rdisk0s1 as argument.
iPad-k94ap#gptfdisk /dev/rdisk0s1

gptfdisk>p

7815175 * 8192 = 64021913600 bytes
/dev/rdisk0s1 : 64021913600 bytes
Now, let's calculate the System partition size. There's something important to consider, we must calculate that according to the size we plan to set for the partition.
The new size you will give to the System partition depends of your post-exploitation plans. If you think about installing different iOS versions, I suggest you set a size of 3.2 GB. This will allow you to flash most root filesystem .dmg images including iOS 9 ones and having some space for jailbreaking if you plan to.
1 GB = 1024 * 1024 * 1024 = 1073741824 bytes
3.2 GB = 3.2 * 1073741824 = 3435973836,8
Divide it by [block size] value :
3435973836,8 / 8192 = 419430,4 logical sectors
Remove decimal part, to keep an integer logical sectors number :
419430,4 -> 419430
Convert it back to bytes :
419430 * 8192 = 3435970560 bytes
/dev/rdisk0s1s1 (System) : 3435970560 bytes
Calculate the exploitation partition size. A third partition which contains an invalid HFS+ filesystem is used to trigger the exploit once iBoot tries to mount it. There must be some available space for it right after the Data partition. To define the size of that third partition, we must consider the amount of RAM memory our device has, then add 128 MB to that value.
The iPad 2nd has 512 MB of RAM, so the ideal size of this partition would be around 512 MB + 128 MB = 640 MB.
1 MB = 1024 * 1024 = 1048576 bytes
640 MB = 1048576 * 640 = 671088640bytes
/dev/rdisk0s1s3 (Exploit) : 671088640
Finally, calculate the size in bytes of the Data partition. Our Data partition will fit into the remaining space of the whole disk minus System and Exploit partition.
64021913600 (/dev/rdisk0s1) - 3435970560 (/dev/rdisk0s1s1) - 671088640 (/dev/rdisk0s1s3) = 59914854400 bytes (/dev/rdisk0s1s2)
/dev/rdisk0s1s2 (Data) : 59914854400 bytes (55.8 GB)
According to the partition sizes we have calculated previously, resize the data partition LwVM container. The iOS device I'm working on for this writeup is an iPad 2nd (K48AP) 64 GB.
Initial size of data partition for iOS 5.0.1 on this device is 58.1 GB.

We will use hfs_resize to shrink the LwVM container of the data partition. This will free up some space for a tiny additional partition that we will use to trigger the exploit.
iPad-k48ap#hfs_resize [mount point] [capacity in bytes]
The mount point is the folder where your disk device is mounted. For iOS, the data partition is always mounted in /private/var of the root filesystem. We already have calculated the new size of our Data partition, 59914854400 bytes. Our command to reduce the data partition would be like this.iPad-k48ap#hfs_resize /private/var/ 59914854400

We are now ready to adjust the size of partitions within the GPT. To partition an iOS device disk which uses LwVM + GPT, we will use gptfdisk. This tool will allows us to edit the GPT partition table stored on /dev/rdisk0s1, then changes will be written back to the LwVM partition table stored on /dev/rdisk0.
Execute gptfdisk with the disk volume rdisk0s1 as argument.
iPad-k94ap#gptfdisk /dev/rdisk0s1

In order to recreate the partitions with the same properties and attributes they had before deleting them, we can display informations about our current partitions with the following command.
gptfdisk>i [enter]
1 [enter]

gptfdisk>i [enter]
2 [enter]

- Partition Unique GUID
- Attribute flags
Go into gptfdisk expert mode, then show attributes for partition 1.
gptfdisk>x [enter]
a [enter]
1 [enter]
[CTRL+C]

a [enter]
2 [enter]
[CTRL+C]

gptfdisk>m [enter]
Delete the Data partition :
gptfdisk>d [enter]
2 [enter]
gptfdisk>d [enter]
1 [enter]

Re-create the System partition with the new size you want it to be. I will set it to 3.2 GB, as mentioned before in this writeup.
gptfdisk>n [enter]
The first sector should be keep as default.[enter]
The last sector is where the partition must ends on the logical disk. We already know how much logical sectors our resized System partition will use, we calculated it previously. Our number of logical sectors for System partition is 419430.Add the default first sector value (this number is the currently allocated number of blocks) : 419430 + 4 = 419434 and give this value to GPTfdisk.
[enter]
Keep the default Hex code.[enter]

Set System as partition name :
gptfdisk>c [enter]
1 [enter]
System [enter]

Go to gptfdisk expert mode.
gptfdisk>x [enter]
Enter the following commands to restore the partition GUID.
c [enter]
1 [enter]
[GUID] [enter]

gptfdisk>m [enter]
Re-create the data partition with the same size that you set previously using hfs_resize. It was 59914854400 bytes (55.8 GB) for my 64 GB iPad 2nd.gptfdisk>n [enter]
The first sector should be keep as default.[enter]
Take the size you have previously set in hfs_resize, then do the following maths.Divide it by [block size] value :
59914854400 / 8192 = 7313825 blocks
Add the default first sector value (this number is the currently allocated number of blocks) : 419436 + 7313825 = 7733261
Give this value to GPTfdisk.
[enter]
Keep the default Hex code.[enter]

gptfdisk>c [enter] 2 [enter] Data [enter]

gptfdisk>p [enter]

The original Data partition had some attribute flags set to on. In order to make the recreated partition same as it was and avoid disk issues, we will put these flags to on for it.
Be sure you are in gptfdisk expert mode.
a [enter]
2 [enter]
48 [enter][enter]
c [enter]
2 [enter]
[GUID] [enter]

gptfdisk>m [enter]
Verify that the data partition as been properly recreated and that is has the right size :gptfdisk>p [enter]

gptfdisk>w [enter]
y [enter]
iPad-k94ap# sync; iPad-k94ap# sync; iPad-k94ap# sync;

Execute gptfdisk with the disk volume rdisk0s1 as argument.
iPad-k94ap#gptfdisk /dev/rdisk0s1
verify that our current partitions were properly resized.gptfdisk>p

Outside gptfdisk, you will notice that our System partition still has 1.6 GB total capacity but we set it to 3.2 GB using gptfdisk. iPad-k94ap#df -h

We previously set /dev/rdisk0s1s1 (System) to 3435970560 bytes.
iPad-k94ap#hfs_resize / 3435970560


iPad-k94ap#gptfdisk /dev/rdisk0s1
Default partition table can only hold two partitions, we will expand it to allow creating more partitions.
gptfdisk>x [enter]
s [enter]
4 [enter]
gptfdisk>n [enter]
3 [enter]
Keep default first sector [enter]
Divide it by [block size] value to obtain how many logical sectors will be required.
671088640 bytes / 8192 = 81920 sectors needed.
Add those sectors to the minimal sector position we can set for the new partition.
7733264 + 81920 = 7815184
The last sector number we calculated for our partition at the last position might be greater than the maximum last sector value allowed by gptfdisk for our current partition configuration. This is expected, because we did not include the sectors used for storing partition configuration when we calculated sizes at the beginning. This is also very important to keep at least five unused sectors from the maximum last sector value allowed by gptfdisk for the last partition because gptfdisk or LwVM might not apply the changes.
Give this value to gptfdisk[enter]
Keep the default Hex code.[enter]

gptfdisk>c [enter]
3 [enter]
Exploit [enter]
gptfdisk>w [enter]
y [enter]
iPad-k94ap# sync
iPad-k94ap# sync
iPad-k94ap# sync
iPad-k94ap#ls /dev/ | grep rdisk
You should see exactly five disk devices.- /dev/rdisk0 (LwVM device)
- /dev/rdisk0s1 (LwVM provided GPT)
- /dev/rdisk0s1s1 (System)
- /dev/rdisk0s1s2 (Data)
- /dev/rdisk0s1s3 (Exploit)