Introduction
In the first part of this blog series, we explored the Protective MBR and its role in safeguarding the compatibility of modern GPT-partitioned disks with legacy systems. We delved into how the Protective MBR serves as a barrier to prevent older systems from misinterpreting GPT disks, thereby ensuring that the entire disk is marked as in use by GPT. This foundational understanding sets the stage for a deeper dive into the heart of the GUID Partition Table (GPT) itself — the GPT Header.
In this second part, we will unpack the GPT Header, a crucial component of the GPT schema that provides vital information about the disk’s structure. We will examine each field within the GPT Header, explaining its significance and how it contributes to the overall functionality and integrity of the disk. By the end of this post, you will have a comprehensive understanding of the GPT Header, enabling you to confidently analyze and manipulate GPT-partitioned disks in forensic investigations or data recovery scenarios.
GPT Header Overview
The GPT (GUID Partition Table) Header is a crucial component of the disk’s partitioning system. It divides the disk into separate sections, each of which can store different types of data, such as your operating system, personal files, application data, or games. These sections can be different drives (like the C: drive, D: drive, E: drive, etc.).
The GPT Header includes a backup copy at the end of the disk, akin to having a spare key to the library catalog in case the main one gets lost or damaged. This ensures we can find and access our data even if something goes wrong.
The GPT Header provides the location of its backup and the location of the GUID Partition Table Entry Array, which is a list of GPT partition entries that indicate where those sections (partitions) are located on the disk.

Figure 1: Layout of a hypothetical Windows 10 install with one volume (n = last sector of the drive)
The GPT Header starts with its signature, EFI PART. The rest of the values are broken down in the table below:
GPT Header Structure
The GPT Header starts with its signature, ‘EFI PART.’ The rest of the values are broken down in the table below:


Source : https://uefi.org/specs/UEFI/2.10/05_GUID_Partition_Table_Format.html

So far, the first 16 bytes of the GPT Header will remain constant across different GPT disks.
GPT Header CRC

Below is an example of how to calculate the CRC32 for the GPT header:

You can use a Python script to calculate the isolated bytes CRC:

Python script can be found at: https://github.com/eichbaumj/Python

The Python script will take the resulting CRC32 value and convert it into the format required for the GPT Header. The calculated value, in this case, is 0x1B2C37BC. But to store it in the field within the GPT header, the value is read little endian: 0xBC372C1B.

Disk GUID

The screenshot below shows the GUID highlighted in the GPT Header:

The GUID is a 16-byte hexadecimal value, but if you were to think you could just copy the values out and separate them appropriately with hyphens and slap curly braces around them, then you would be wrong. You would end up with the wrong value.
You can see HxD provides the GUID conversion in the Data Inspector to the right. But how does that happen? How does:
55 BA 55 51 2B D8 59 41 BC 1F C4 17 80 0F D7 63
Become:
{5155BA55-D82B-4159-BC1F-C417800FD763}
The GUID format
XX XX XX XX | XX XX | XX XX | XX XX | XX XX XX XX XX XX
55 BA 55 51 | 2B D8 | 59 41 | BC 1F | C4 17 80 0F D7 63
The first set of four bytes are converted to little-endian hex: 51 55 BA 55
The second set of 2 bytes is converted to little-endian hex: D8 2B
The third set of 2 bytes is converted to little-endian hex: 59 41
The remaining two sets of hex values are left as is, big-endian: BC 1F | C4 17 80 0F D7 63
Once all the conversions are complete, we can put them all together, placing hyphens where they need to be and enclosing it in curly braces:
{5155BA55-D82B-4159-BC1F-C417800FD763}
We can confirm this is the correct encoding of the GUID by launching diskpart from the command line and checking for the uniqueid of the disk:


GPT Partition Table Checksum CRC

We can use the same Python script but replace the hex values with those found in the Partition Entry Array.



And we can see that the value does correspond to what is found in the GPT Header.
Repairing a GPT Header
Ok, now that we know how the GPT Header is structured and that there is a backup located at the last sector of the disk, how do we go about repairing the GPT Header should it become corrupt or wiped?
To repair the GPT Header, copy the last 512 bytes from the end of the disk and paste them into LBA 1 (sector #2). Note that a few modifications are necessary.
Below is an example of what the backup GPT Header looks like at the end of a disk:

We can see that some values remain constant compared to the original GPT Header. These constants are highlighted in red below:

There are four values that need to be changed.
The first is the GPT Header CRC, which we will come back to. For now, those values can be zeroed out as we would need to use the CRC calculated after we’ve modified the other values to get the correct one again.

The next is the MyLBA value located at offset 24 for 4 bytes. This value points to the location of the GPT Header (where it is currently) and its current position is LBA 1 or 0x01000000000000000.

The 8-byte value at offset 32 is the value that points us to the location of the backup GPT Header. The backup currently points to the original, but we need to change this value to represent the last sector of the disk. This happened to the hex values that we just changed in the previous step. In this example, the value would need to be changed to 0xAFD23B7700000000.

The 8-byte value located at offset 72 needs to reflect the location and start of the GPT Partition Entry Array. Currently, the backup GPT header is pointing to the backup of that array. The actual GPT Partition Array should be at LBA 2. This value needs to be changed to 0x0200000000000000.

With those three values changed, it’s time to calculate the CRC32 value.
The resulting checksum is:

So now we can replace the 0x00000000 values at offset 16 with 0xBC372C1B:

HxD has a CRC32 checksum calculator built in under Analysis -> Checksums. The resultant value just needs to be added as a little-endian value.
For curiosity’s sake, if we were to isolate those 512 bytes for the original and the backup that we restored, the hash values indeed match indicating that we successfully reproduced the original GPT Header using the backup.

Conclusion
Understanding the intricacies of the GPT Header is essential for anyone involved in digital forensics, data recovery, or system administration. The GPT Header not only defines the layout and structure of the disk but also ensures data integrity through mechanisms such as CRC32 checksums and backup headers. By mastering the details of the GPT Header, you are better equipped to troubleshoot and repair disk issues, ensuring the reliability and accessibility of critical data.
As we continue this series, our next focus will be on the GPT Partition Table Entry Array. We will explore how partition entries are structured and how they work in concert with the GPT Header to maintain the organization and integrity of disk partitions. Stay tuned for a comprehensive guide on analyzing and repairing the GPT Partition Table Entry Array, further empowering you with the knowledge to handle GPT-partitioned disks confidently.
Missed Part 1?
Start from the beginning: Understanding the Protective MBR in GPT-Partitioned Disks (Part 1) – where we cover how GPT ensures backward compatibility with legacy systems.
Ready for the next step?
Continue to Part 3: Navigating the GPT Partition Entry Array – where we explore how partition entries are structured and how they complement the GPT Header.
Une réponse
Great pages (that one and part 1).
Many thanks!