/** * is_gpt_valid() - tests one GPT header and PTEs for validity * * lba is the logical block address of the GPT header to test * gpt is a GPT header ptr, filled on return. * ptes is a PTEs ptr, filled on return. * * Description: returns 1 if valid, 0 on error. * If valid, returns pointers to PTEs. */ static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, gpt_header *pgpt_head, gpt_entry **pgpt_pte) { if (!dev_desc || !pgpt_head) { printf("%s: Invalid Argument(s)\n", __func__); return 0; } /* Read GPT Header from device */ if (dev_desc->block_read(dev_desc->dev, (lbaint_t)lba, 1, pgpt_head) != 1) { printf("*** ERROR: Can't read GPT header ***\n"); return 0; } if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba)) return 0; /* Read and allocate Partition Table Entries */ *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head); if (*pgpt_pte == NULL) { printf("GPT: Failed to allocate memory for PTE\n"); return 0; } if (validate_gpt_entries(pgpt_head, *pgpt_pte)) { free(*pgpt_pte); return 0; } /* We're done, all's well */ return 1; }
void tweak(int fd) { /* block legacy_mbr; read_block(fd, 0, &legacy_mbr); printf("Legacy MBR:\n"); hexdump_block(&legacy_mbr); */ printf("\nLoading the header.\n"); block header_block; read_block(fd, 1, &header_block); if(!validate_gpt_header(&header_block, 1)) { describe_failure("The header doesn't validate.\n"); return; } else describe_success("The header validates.\n"); struct gpt_header *header = (struct gpt_header *) &header_block; printf("\nLoading the entry array.\n"); block *entry_blocks = load_entry_array(fd, header); if(!validate_entry_array(header, entry_blocks)) { describe_failure("The entry array doesn't validate.\n"); return; } else describe_success("The entry array validates.\n"); printf("\nPatching the entry array to my very specific requirements.\n"); struct partition_entry *entry = get_partition_entry(header, entry_blocks, 1); uuid *new_uuid; new_uuid = get_type_name_uuid("Apple HFS+ (or just HFS)"); swab_and_copy_uuid(&entry->partition_type_uuid, new_uuid); overwrite_entry_name_ascii(entry, "Crookshanks"); entry = get_partition_entry(header, entry_blocks, 2); new_uuid = get_type_name_uuid("Basic data partition (could be Windows or Linux!)"); swab_and_copy_uuid(&entry->partition_type_uuid, new_uuid); //describe_trivium("\nBy the way, basic data is %s\n", uuid_to_ascii(new_uuid)); //describe_trivium("By the way, HFS+ is %s\n", uuid_to_ascii(new_uuid)); printf("\nPatching the checksums in the header, in effect accepting the changes.\n"); uint32_t new_array_crc32 = compute_entry_crc32(header, entry_blocks); header->partition_entry_array_crc32 = new_array_crc32; if(!validate_entry_array(header, entry_blocks)) { describe_failure("The patched entry array doesn't validate.\n"); return; } else describe_success("The patched entry array validates.\n"); uint32_t new_header_crc32 = compute_header_crc32(&header_block); header->header_crc32 = new_header_crc32; if(!validate_gpt_header(&header_block, 1)) { describe_failure("The patched header doesn't validate.\n"); return; } else describe_success("The patched header validates.\n"); describe_trivium("\nCreating the patched backup header, based on the patched header.\n"); block backup_header_block; memcpy(&backup_header_block, &header_block, sizeof(block)); struct gpt_header *backup_header = (struct gpt_header *) backup_header_block; backup_header->my_lba = header->alternate_lba; backup_header->alternate_lba = header->my_lba; uint32_t new_backup_header_crc32 = compute_header_crc32(&backup_header_block); backup_header->header_crc32 = new_backup_header_crc32; if(!validate_gpt_header(&backup_header_block, header->alternate_lba)) { describe_failure("The patched backup header doesn't validate.\n"); return; } else describe_success("The patched backup header validates.\n"); write_block(1, &header_block); write_block(2, entry_blocks); write_block(header->alternate_lba, &backup_header_block); }