Rev 30 | Rev 34 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 30 | Rev 33 | ||
---|---|---|---|
Line 200... | Line 200... | ||
200 | size_t fsentry_count = 0; |
200 | size_t fsentry_count = 0; |
201 | fsentry_t *current_fsentry = NULL; |
201 | fsentry_t *current_fsentry = NULL; |
202 | buffer_t decompression_dst; |
202 | buffer_t decompression_dst; |
203 | char recorded_sha512[2 * SHA512_DIGEST_LENGTH + 1] = ""; |
203 | char recorded_sha512[2 * SHA512_DIGEST_LENGTH + 1] = ""; |
204 | char computed_sha512[2 * SHA512_DIGEST_LENGTH + 1] = ""; |
204 | char computed_sha512[2 * SHA512_DIGEST_LENGTH + 1] = ""; |
- | 205 | char *executable_format = NULL; |
|
205 | size_t startupfile_blobsize = 0; |
206 | size_t startupfile_blobsize = 0; |
206 | size_t compressed_blocksize; |
207 | size_t compressed_blocksize; |
207 | void *reallocated_ptr; |
208 | void *reallocated_ptr; |
208 | bool is_foreign_endianness; |
209 | bool is_foreign_endianness; |
209 | uint8_t *decompressor_out; |
210 | uint8_t *decompressor_out; |
Line 620... | Line 621... | ||
620 | } |
621 | } |
621 | 622 | ||
622 | // else it has to be a boot blob, of which we don't know the size, except that it has to fit in 0xffff bytes and be immediately followed by a startup header |
623 | // else it has to be a boot blob, of which we don't know the size, except that it has to fit in 0xffff bytes and be immediately followed by a startup header |
623 | else |
624 | else |
624 | { |
625 | { |
- | 626 | // if the first two bytes are Mark Zbikowski's initials, it's a PE executable, which means this is an EFI image |
|
- | 627 | executable_format = ((file.size > 2) && (memcmp (file.bytes, "MZ", 2) == 0) ? "UEFI" : "BIOS"); // anything else is a BIOS image |
|
- | 628 | ||
625 | // |
629 | // scan for the first startup header magic and version (which makes us 6 bytes to scan for, i.e. "\xeb\x7e\xff\x00" for the magic and "\x01\x00" (LSB) for the version 1) |
626 | for (byte_index = current_offset; byte_index < file.size - 6; byte_index++) |
630 | for (byte_index = current_offset; byte_index < file.size - 6; byte_index++) |
627 | if (memcmp (&file.bytes[byte_index], "\xeb\x7e\xff\x00" "\x01\x00", 4 + 2) == 0) |
631 | if (memcmp (&file.bytes[byte_index], "\xeb\x7e\xff\x00" "\x01\x00", 4 + 2) == 0) |
628 | break; // stop as soon as we find it |
632 | break; // stop as soon as we find it |
629 | 633 | ||
630 | if (byte_index >= file.size - 6) |
634 | if (byte_index >= file.size - 6) |
631 | break; // if not found, stop scanning |
635 | break; // if not found, stop scanning |
632 | 636 | ||
633 | bootfile_blobsize = byte_index - current_offset; |
637 | bootfile_blobsize = byte_index - current_offset; |
- | 638 | printf ("%s boot code at offset 0x%zx (%zd):\n", executable_format, current_offset, current_offset); |
|
- | 639 | if ((strcmp (executable_format, "UEFI") == 0) && (byte_index >= sizeof (uefi64_header_t))) |
|
- | 640 | { |
|
- | 641 | uefi64_header_t *uefi_header = (uefi64_header_t *) file.bytes; // dump UEFI header details |
|
- | 642 | printf (" MZ header: signature: 5a 4d - 'MZ', good\n"); // we already validated this |
|
- | 643 | printf (" MZ header: number of bytes in last page: %d - %s\n", uefi_header->dos_header.bytes_in_last_page, (uefi_header->dos_header.bytes_in_last_page == 144 ? "good" : "unexpected value!?")); |
|
- | 644 | printf (" MZ header: number of 512-byte pages: %d - %s\n", uefi_header->dos_header.number_of_pages, (uefi_header->dos_header.number_of_pages == 3 ? "good" : "unexpected value!?")); |
|
- | 645 | printf (" MZ header: number of relocations: %d - %s\n", uefi_header->dos_header.number_of_relocations, (uefi_header->dos_header.number_of_relocations == 0 ? "good" : "unexpected value!?")); |
|
- | 646 | printf (" MZ header: header size in 16-byte paragraphs: %d - %s\n", uefi_header->dos_header.header_size_in_paragraphs, (uefi_header->dos_header.header_size_in_paragraphs == 4 ? "good" : "unexpected value!?")); |
|
- | 647 | printf (" MZ header: required/requested 16-byte paragraphs: %d/%d - %s\n", uefi_header->dos_header.required_paragraphs, uefi_header->dos_header.requested_paragraphs, (memcmp (&uefi_header->dos_header.required_paragraphs, "\0\0\xff\xff", 4) == 0 ? "good" : "unexpected value!?")); |
|
- | 648 | printf (" MZ header: initial relative relocatable segment offset fo SS: 0x%x - %s\n", uefi_header->dos_header.initial_relative_relocatable_segment_address_for_ss, (uefi_header->dos_header.initial_relative_relocatable_segment_address_for_ss == 0 ? "good" : "unexpected value!?")); |
|
- | 649 | printf (" MZ header: initial stack pointer value: 0x%04x - %s\n", uefi_header->dos_header.initial_stack_pointer_value, (uefi_header->dos_header.initial_stack_pointer_value == 184 ? "good" : "unexpected value!?")); |
|
- | 650 | printf (" MZ header: checksum (unused): 0x%x - %s\n", uefi_header->dos_header.unused_checksum, (uefi_header->dos_header.unused_checksum == 0 ? "good" : "unexpected value!?")); |
|
- | 651 | printf (" MZ header: initial instruction pointer value: 0x%04x - %s\n", uefi_header->dos_header.initial_instruction_pointer_value, (uefi_header->dos_header.initial_instruction_pointer_value == 0 ? "good" : "unexpected value!?")); |
|
- | 652 | printf (" MZ header: initial relative relocatable segment offset fo CS: 0x%x - %s\n", uefi_header->dos_header.initial_relative_relocatable_segment_address_for_cs, (uefi_header->dos_header.initial_relative_relocatable_segment_address_for_cs == 0 ? "good" : "unexpected value!?")); |
|
- | 653 | printf (" MZ header: absolute offset to relocation table: 0x%x - %s\n", uefi_header->dos_header.absolute_offset_to_relocation_table, (uefi_header->dos_header.absolute_offset_to_relocation_table == 64 ? "good" : "unexpected value!?")); |
|
- | 654 | printf (" MZ header: reserved_words1[4]: %s\n", (memcmp (uefi_header->dos_header.reserved_words1, "\0\0\0\0\0\0\0\0", 4 * sizeof (uint16_t)) == 0 ? "zerofilled, good" : "contains data, unexpected value!?")); |
|
- | 655 | printf (" MZ header: OEM identifier: 0x%04x - %s\n", uefi_header->dos_header.oem_identifier, (uefi_header->dos_header.oem_identifier == 0 ? "good" : "unexpected value!?")); |
|
- | 656 | printf (" MZ header: OEM info: 0x%04x - %s\n", uefi_header->dos_header.oem_info, (uefi_header->dos_header.oem_info == 0 ? "good" : "unexpected value!?")); |
|
- | 657 | printf (" MZ header: reserved_words2[10]: %s\n", (memcmp (uefi_header->dos_header.reserved_words2, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 10 * sizeof (uint16_t)) == 0 ? "zerofilled, good" : "contains data, unexpected value!?")); |
|
- | 658 | printf (" MZ header: absolute offset to PE header: 0x%08x (%d) - %s\n", uefi_header->dos_header.absolute_offset_to_pe_header, uefi_header->dos_header.absolute_offset_to_pe_header, (uefi_header->dos_header.absolute_offset_to_pe_header == 128 ? "good" : "unexpected value!?")); |
|
- | 659 | hex_printf (uefi_header->dos_stub_bytes, 64, " MZ header: DOS stub code bytes (64 bytes):\n"); |
|
- | 660 | printf (" PE header: signature: %02x %02x %02x %02x - %s\n", uefi_header->pe_header.signature[0], uefi_header->pe_header.signature[1], uefi_header->pe_header.signature[2], uefi_header->pe_header.signature[3], (memcmp (uefi_header->pe_header.signature, "PE\0\0", 4) == 0 ? "'PE\\0\\0' - good" : "unexpected value!?")); |
|
- | 661 | printf (" PE header: machine type: 0x%04x - %s\n", uefi_header->pe_header.machine_type, (uefi_header->pe_header.machine_type == 0x8664 ? "AMD64, good" : "unexpected value!?")); |
|
- | 662 | printf (" PE header: number of sections: %d - %s\n", uefi_header->pe_header.number_of_sections, (uefi_header->pe_header.number_of_sections == 1 ? "good" : "unexpected value!?")); |
|
- | 663 | printf (" PE header: symbols table offset: 0x%x (%d) - %s\n", uefi_header->pe_header.offset_to_symbols_table, uefi_header->pe_header.offset_to_symbols_table, (uefi_header->pe_header.offset_to_symbols_table == 0 ? "good" : "unexpected value!?")); |
|
- | 664 | printf (" PE header: number of symbols: %d - %s\n", uefi_header->pe_header.number_of_symbols, (uefi_header->pe_header.number_of_symbols == 0 ? "good" : "unexpected value!?")); |
|
- | 665 | printf (" PE header: size of optional header: %d - %s\n", uefi_header->pe_header.size_of_optional_header, (uefi_header->pe_header.size_of_optional_header == 240 ? "good" : "unexpected value!?")); |
|
- | 666 | printf (" PE header: characteristics bitmap: 0x%04x - %s\n", uefi_header->pe_header.characteristics_bitmap, (uefi_header->pe_header.characteristics_bitmap == 0x223 ? "executable + uses large addresses + relocs stripped + debug info stripped, good" : "unexpected value!?")); |
|
- | 667 | printf (" optional header: signature: %02x %02x - %s\n", uefi_header->optional_header64.signature[0], uefi_header->optional_header64.signature[1], (memcmp (uefi_header->optional_header64.signature, "\x0b\x02", 2) == 0 ? "64-bit optional header magic, good" : "unexpected value!?")); |
|
- | 668 | printf (" optional header: linker version: %u.%u - %s\n", uefi_header->optional_header64.linker_version_major, uefi_header->optional_header64.linker_version_minor, (memcmp (&uefi_header->optional_header64.linker_version_major, "\0\0", 2) == 0 ? "good" : "unexpected value!?")); |
|
- | 669 | printf (" optional header: code size: 0x%x (%d) - %s\n", uefi_header->optional_header64.code_size, uefi_header->optional_header64.code_size, (byte_index + uefi_header->optional_header64.code_size == file.size ? "good" : "BAD (should equal file size minus UEFI boot prefix size)")); |
|
- | 670 | printf (" optional header: size of initialized data: 0x%x (%d) - %s\n", uefi_header->optional_header64.size_of_initialized_data, uefi_header->optional_header64.size_of_initialized_data, (uefi_header->optional_header64.size_of_initialized_data == 0 ? "good" : "unexpected value!?")); |
|
- | 671 | printf (" optional header: size of uninitialized data: 0x%x (%d) - %s\n", uefi_header->optional_header64.size_of_uninitialized_data, uefi_header->optional_header64.size_of_uninitialized_data, (uefi_header->optional_header64.size_of_uninitialized_data == 0 ? "good" : "unexpected value!?")); |
|
- | 672 | printf (" optional header: entrypoint address: 0x%x (%d)\n", uefi_header->optional_header64.entrypoint_address, uefi_header->optional_header64.entrypoint_address); // TODO: validate |
|
- | 673 | printf (" optional header: code base: 0x%x (%d) - %s\n", uefi_header->optional_header64.code_base, uefi_header->optional_header64.code_base, (uefi_header->optional_header64.code_base == 0 ? "good" : "unexpected value!?")); |
|
- | 674 | printf (" optional header: image base: 0x%zx (%zd)\n", uefi_header->optional_header64.image_base, uefi_header->optional_header64.image_base); // TODO: validate |
|
- | 675 | printf (" optional header: section alignment: 0x%x (%d) - %s\n", uefi_header->optional_header64.section_alignment, uefi_header->optional_header64.section_alignment, ((uefi_header->pe_header.machine_type == 0x8664) && (uefi_header->optional_header64.section_alignment == 4096) ? "good" : "unexpected value!? (should equal system page size)")); |
|
- | 676 | printf (" optional header: file alignment: 0x%x (%d) - %s\n", uefi_header->optional_header64.file_alignment, uefi_header->optional_header64.file_alignment, (uefi_header->optional_header64.file_alignment == 512 ? "good" : "unexpected value!? (must be a power of 2 between 512 and 65536)")); |
|
- | 677 | printf (" optional header: OS version: %u.%u - %s\n", uefi_header->optional_header64.os_version_major, uefi_header->optional_header64.os_version_minor, (memcmp (&uefi_header->optional_header64.os_version_major, "\0\0", 2) == 0 ? "good" : "unexpected value!?")); |
|
- | 678 | printf (" optional header: image version: %u.%u - %s\n", uefi_header->optional_header64.image_version_major, uefi_header->optional_header64.image_version_minor, (memcmp (&uefi_header->optional_header64.image_version_major, "\0\0", 2) == 0 ? "good" : "unexpected value!?")); |
|
- | 679 | printf (" optional header: subsystem version: %u.%u - %s\n", uefi_header->optional_header64.subsystem_version_major, uefi_header->optional_header64.subsystem_version_minor, (memcmp (&uefi_header->optional_header64.subsystem_version_major, "\0\0", 2) == 0 ? "good" : "unexpected value!?")); |
|
- | 680 | printf (" optional header: Win32 version value: 0x%x (%d) - %s\n", uefi_header->optional_header64.win32_version_value, uefi_header->optional_header64.win32_version_value, (uefi_header->optional_header64.win32_version_value == 0 ? "good" : "unexpected value!?")); |
|
- | 681 | printf (" optional header: image size: 0x%x (%d) - %s\n", uefi_header->optional_header64.image_size, uefi_header->optional_header64.image_size, (uefi_header->optional_header64.image_size == file.size ? "good" : "BAD (should equal file size)")); |
|
- | 682 | printf (" optional header: size of headers: 0x%x (%d) - %s\n", uefi_header->optional_header64.size_of_headers, uefi_header->optional_header64.size_of_headers, (uefi_header->optional_header64.size_of_headers == byte_index ? "good" : "BAD (should equal UEFI boot prefix size)")); |
|
- | 683 | printf (" optional header: checksum (unused): 0x%x - %s\n", uefi_header->optional_header64.unused_checksum, (uefi_header->optional_header64.unused_checksum == 0 ? "good" : "unexpected value!?")); |
|
- | 684 | printf (" optional header: subsystem type: 0x%x (%d) - %s\n", uefi_header->optional_header64.subsystem_type, uefi_header->optional_header64.subsystem_type, (uefi_header->optional_header64.subsystem_type == 10 ? "IMAGE_SUBSYSTEM_EFI_APPLICATION, good" : "BAD (should be IMAGE_SUBSYSTEM_EFI_APPLICATION i.e. 10 decimal)")); |
|
- | 685 | printf (" optional header: DLL characteristics bitmap: 0x%x (%d) - %s\n", uefi_header->optional_header64.dll_characteristics_bitmap, uefi_header->optional_header64.dll_characteristics_bitmap, (uefi_header->optional_header64.dll_characteristics_bitmap == 0 ? "nil, good" : "BAD (should be 0)")); |
|
634 | printf (" |
686 | printf (" optional header: stack commit/reserve size: %zd/%zd - %s\n", uefi_header->optional_header64.stack_commit_size, uefi_header->optional_header64.stack_reserve_size, ((uefi_header->optional_header64.stack_commit_size == uefi_header->optional_header64.section_alignment) && (uefi_header->optional_header64.stack_reserve_size == uefi_header->optional_header64.section_alignment) ? "good" : "unexpected value!? (both should equal system page size)")); |
- | 687 | printf (" optional header: heap commit/reserve size: %zd/%zd - %s\n", uefi_header->optional_header64.heap_commit_size, uefi_header->optional_header64.heap_reserve_size, ((uefi_header->optional_header64.heap_commit_size == 0) && (uefi_header->optional_header64.heap_reserve_size == 0) ? "good" : "unexpected value!? (both should be zero)")); |
|
- | 688 | printf (" optional header: loader flags: 0x%x (%d) - %s\n", uefi_header->optional_header64.unused_loader_flags, uefi_header->optional_header64.unused_loader_flags, (uefi_header->optional_header64.unused_loader_flags == 0 ? "good" : "BAD (should be zero)")); |
|
- | 689 | printf (" optional header: number of data directories: %d - %s\n", uefi_header->optional_header64.number_of_data_directories, (uefi_header->optional_header64.number_of_data_directories == 16 ? "good" : "unexpected value!?")); |
|
- | 690 | printf (" optional header: data directories: %s\n", (memcmp (uefi_header->optional_header64.data_directories, "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0", 8 * 16) == 0 ? "zerofilled, good" : "contains data, unexpected value!?")); |
|
- | 691 | printf (" image section header: section name: '%.8s' - %s\n", uefi_header->unique_section.section_name, (memcmp (uefi_header->unique_section.section_name, "image\0\0\0", 8) == 0 ? "good" : "unexpected value!?")); |
|
- | 692 | printf (" image section header: virtual size: 0x%x (%d) - %s\n", uefi_header->unique_section.virtual_size, uefi_header->unique_section.virtual_size, (uefi_header->unique_section.virtual_size == uefi_header->optional_header64.code_size ? "good" : "BAD (should equal code size)")); |
|
- | 693 | printf (" image section header: virtual address: 0x%x (%d) - %s\n", uefi_header->unique_section.virtual_address, uefi_header->unique_section.virtual_address, (uefi_header->unique_section.virtual_address == byte_index ? "good" : "BAD (should equal UEFI boot prefix size)")); |
|
- | 694 | printf (" image section header: raw data size: 0x%x (%d) - %s\n", uefi_header->unique_section.rawdata_size, uefi_header->unique_section.rawdata_size, (uefi_header->unique_section.rawdata_size == uefi_header->optional_header64.code_size ? "good" : "BAD (should equal code size)")); |
|
- | 695 | printf (" image section header: raw data offset: 0x%x (%d) - %s\n", uefi_header->unique_section.rawdata_offset, uefi_header->unique_section.rawdata_offset, (uefi_header->unique_section.rawdata_offset == byte_index ? "good" : "BAD (should equal UEFI boot prefix size)")); |
|
- | 696 | printf (" image section header: offset to relocations: 0x%x (%d) - %s\n", uefi_header->unique_section.offset_to_relocations, uefi_header->unique_section.offset_to_relocations, (uefi_header->unique_section.offset_to_relocations == 0 ? "good" : "unexpected value!?")); |
|
- | 697 | printf (" image section header: offset to line numbers: 0x%x (%d) - %s\n", uefi_header->unique_section.offset_to_linenos, uefi_header->unique_section.offset_to_linenos, (uefi_header->unique_section.offset_to_linenos == 0 ? "good" : "unexpected value!?")); |
|
- | 698 | printf (" image section header: number of relocations: 0x%x (%d) - %s\n", uefi_header->unique_section.relocation_count, uefi_header->unique_section.relocation_count, (uefi_header->unique_section.relocation_count == 0 ? "good" : "unexpected value!?")); |
|
- | 699 | printf (" image section header: number of line numbers: 0x%x (%d) - %s\n", uefi_header->unique_section.lineno_count, uefi_header->unique_section.lineno_count, (uefi_header->unique_section.lineno_count == 0 ? "good" : "unexpected value!?")); |
|
- | 700 | printf (" image section header: characteristics bitmap: 0x%04x - %s\n", uefi_header->unique_section.characteristics_bitmap, (uefi_header->unique_section.characteristics_bitmap == 0x60 ? "image contains code + image contains initialized data, good" : "unexpected value!?")); |
|
- | 701 | hex_printf (uefi_header->trailing_padding, byte_index - 432, " trailing padding (%zd bytes):\n", byte_index - 432); |
|
- | 702 | } |
|
- | 703 | else // BIOS boot prefixes are opaque so far (FIXME: decompile to ASM?) |
|
- | 704 | { |
|
635 | printf (" size 0x%zx (%zd) bytes\n", bootfile_blobsize, bootfile_blobsize); |
705 | printf (" size 0x%zx (%zd) bytes\n", bootfile_blobsize, bootfile_blobsize); |
636 | printf (" checksum 0x%08x\n", update_checksum (&file.bytes[current_offset], bootfile_blobsize, false)); // NOTE: endianness is not known yet -- assume same |
706 | printf (" checksum 0x%08x\n", update_checksum (&file.bytes[current_offset], bootfile_blobsize, false)); // NOTE: endianness is not known yet -- assume same |
- | 707 | } |
|
637 | 708 | ||
638 | current_offset = byte_index; // now reach the next segment |
709 | current_offset = byte_index; // now reach the next segment |
639 | } |
710 | } |
640 | } |
711 | } |
641 | 712 | ||
Line 667... | Line 738... | ||
667 | fsentry_t *current_fsentry = NULL; |
738 | fsentry_t *current_fsentry = NULL; |
668 | buffer_t decompression_dst; |
739 | buffer_t decompression_dst; |
669 | size_t startupfile_blobsize = 0; |
740 | size_t startupfile_blobsize = 0; |
670 | size_t compressed_blocksize; |
741 | size_t compressed_blocksize; |
671 | struct utimbuf file_times = { 0, 0 }; |
742 | struct utimbuf file_times = { 0, 0 }; |
- | 743 | char *exeformat_suffix = ""; |
|
672 | void *reallocated_ptr; |
744 | void *reallocated_ptr; |
673 | uint8_t *decompressor_out; |
745 | uint8_t *decompressor_out; |
674 | uint8_t *decompressor_in; |
746 | uint8_t *decompressor_in; |
675 | size_t decompressor_outlen; |
747 | size_t decompressor_outlen; |
676 | size_t bootfile_blobsize = 0; |
748 | size_t bootfile_blobsize = 0; |
Line 725... | Line 797... | ||
725 | startupfile_blobsize = startup_header->startup_size - sizeof (startup_header_t) - sizeof (startup_trailer_v1_t); |
797 | startupfile_blobsize = startup_header->startup_size - sizeof (startup_header_t) - sizeof (startup_trailer_v1_t); |
726 | 798 | ||
727 | current_offset += sizeof (startup_header_t); // jump over the startup header and reach the startup blob |
799 | current_offset += sizeof (startup_header_t); // jump over the startup header and reach the startup blob |
728 | 800 | ||
729 | // write startup blob |
801 | // write startup blob |
730 | sprintf_s (outfile_pathname, sizeof (outfile_pathname), "%s/ |
802 | sprintf_s (outfile_pathname, sizeof (outfile_pathname), "%s/startup%s.bin", outdir, exeformat_suffix); |
731 | fopen_s (&fp, outfile_pathname, "wb"); |
803 | fopen_s (&fp, outfile_pathname, "wb"); |
732 | ASSERT (fp, "failed to open '%s': %s", outfile_pathname, strerror (errno)); |
804 | ASSERT (fp, "failed to open '%s': %s", outfile_pathname, strerror (errno)); |
733 | fwrite (&file.bytes[current_offset], 1, startupfile_blobsize, fp); |
805 | fwrite (&file.bytes[current_offset], 1, startupfile_blobsize, fp); |
734 | fclose (fp); |
806 | fclose (fp); |
735 | 807 | ||
Line 750... | Line 822... | ||
750 | if (cf != STARTUP_HDR_FLAGS1_COMPRESS_NONE) |
822 | if (cf != STARTUP_HDR_FLAGS1_COMPRESS_NONE) |
751 | { |
823 | { |
752 | // it appears mkifs compresses data in blocks, prefixed by 2-byte block size in BIG ENDIAN |
824 | // it appears mkifs compresses data in blocks, prefixed by 2-byte block size in BIG ENDIAN |
753 | Buffer_InitWithSize (&decompression_dst, startup_header->imagefs_size * 11 / 10); // mallocate and add 10% for safety |
825 | Buffer_InitWithSize (&decompression_dst, startup_header->imagefs_size * 11 / 10); // mallocate and add 10% for safety |
754 | decompression_dst.size = 0; |
826 | decompression_dst.size = 0; |
755 | 827 | ||
756 | if (cf == STARTUP_HDR_FLAGS1_COMPRESS_UCL) |
828 | if (cf == STARTUP_HDR_FLAGS1_COMPRESS_UCL) |
757 | ASSERT (ucl_init () == UCL_E_OK, "UCL library initialization failed -- please recompile this tool with less aggressive optimizations"); |
829 | ASSERT (ucl_init () == UCL_E_OK, "UCL library initialization failed -- please recompile this tool with less aggressive optimizations"); |
758 | else if (cf == STARTUP_HDR_FLAGS1_COMPRESS_LZO) |
830 | else if (cf == STARTUP_HDR_FLAGS1_COMPRESS_LZO) |
759 | ASSERT (lzo_init () == LZO_E_OK, "LZO library initialization failed -- please recompile this tool with less aggressive optimizations"); |
831 | ASSERT (lzo_init () == LZO_E_OK, "LZO library initialization failed -- please recompile this tool with less aggressive optimizations"); |
760 | else if (cf == STARTUP_HDR_FLAGS1_COMPRESS_ZLIB) |
832 | else if (cf == STARTUP_HDR_FLAGS1_COMPRESS_ZLIB) |
Line 918... | Line 990... | ||
918 | fwrite ((char *) ¤t_fsentry->u.symlink.path + current_fsentry->u.symlink.sym_offset, 1, current_fsentry->u.symlink.sym_size, fp); // convert from pointer to char array |
990 | fwrite ((char *) ¤t_fsentry->u.symlink.path + current_fsentry->u.symlink.sym_offset, 1, current_fsentry->u.symlink.sym_size, fp); // convert from pointer to char array |
919 | fclose (fp); |
991 | fclose (fp); |
920 | #else // !_WIN32, thus POSIX |
992 | #else // !_WIN32, thus POSIX |
921 | symlink (current_fsentry->u.symlink.contents, outfile_pathname); // on UNIX systems, just create the symlink for real |
993 | symlink (current_fsentry->u.symlink.contents, outfile_pathname); // on UNIX systems, just create the symlink for real |
922 | #endif // _WIN32 |
994 | #endif // _WIN32 |
923 | } |
995 | } |
924 | else if (S_ISREG (current_fsentry->header.mode)) |
996 | else if (S_ISREG (current_fsentry->header.mode)) |
925 | { |
997 | { |
926 | sprintf_s (outfile_pathname, sizeof (outfile_pathname), "%s/%s", outdir, (char *) ¤t_fsentry->u.file.path); // convert from pointer to char array |
998 | sprintf_s (outfile_pathname, sizeof (outfile_pathname), "%s/%s", outdir, (char *) ¤t_fsentry->u.file.path); // convert from pointer to char array |
927 | create_intermediate_dirs (outfile_pathname); |
999 | create_intermediate_dirs (outfile_pathname); |
928 | fopen_s (&fp, outfile_pathname, "wb"); // on Windows create symlinks as plain files |
1000 | fopen_s (&fp, outfile_pathname, "wb"); // on Windows create symlinks as plain files |
929 | ASSERT (fp, "failed to open '%s': %s", outfile_pathname, strerror (errno)); |
1001 | ASSERT (fp, "failed to open '%s': %s", outfile_pathname, strerror (errno)); |
930 | fwrite (&file.bytes[current_offset], 1, current_fsentry->u.file.size, fp); |
1002 | fwrite (&file.bytes[current_offset], 1, current_fsentry->u.file.size, fp); |
931 | fclose (fp); |
1003 | fclose (fp); |
932 | } |
1004 | } |
933 | else // must be a device node. Since we might not be the super-user and/or on Win32, create plain file with "X:Y" as data |
1005 | else // must be a device node. Since we might not be the super-user and/or on Win32, create plain file with "X:Y" as data |
934 | { |
1006 | { |
Line 960... | Line 1032... | ||
960 | } |
1032 | } |
961 | 1033 | ||
962 | // else it has to be a boot blob, of which we don't know the size, except that it has to fit in 0xffff bytes and be immediately followed by a startup header |
1034 | // else it has to be a boot blob, of which we don't know the size, except that it has to fit in 0xffff bytes and be immediately followed by a startup header |
963 | else |
1035 | else |
964 | { |
1036 | { |
- | 1037 | // if the first two bytes are Mark Zbikowski's initials, it's a PE executable, which means this is an EFI image |
|
- | 1038 | exeformat_suffix = ((file.size > 2) && (memcmp (file.bytes, "MZ", 2) == 0) ? "-uefi" : "-bios"); // anything else is a BIOS image |
|
- | 1039 | ||
965 | // |
1040 | // scan for the first startup header magic and version (which makes us 6 bytes to scan for, i.e. "\xeb\x7e\xff\x00" for the magic and "\x01\x00" (LSB) for the version 1) |
966 | for (byte_index = current_offset; byte_index < file.size - 6; byte_index++) |
1041 | for (byte_index = current_offset; byte_index < file.size - 6; byte_index++) |
967 | if (memcmp (&file.bytes[byte_index], "\xeb\x7e\xff\x00" "\x01\x00", 4 + 2) == 0) |
1042 | if (memcmp (&file.bytes[byte_index], "\xeb\x7e\xff\x00" "\x01\x00", 4 + 2) == 0) |
968 | break; // stop as soon as we find it |
1043 | break; // stop as soon as we find it |
969 | 1044 | ||
970 | if (byte_index >= file.size - 6) |
1045 | if (byte_index >= file.size - 6) |
971 | break; // if not found, stop scanning |
1046 | break; // if not found, stop scanning |
972 | 1047 | ||
973 | bootfile_blobsize = byte_index - current_offset; |
1048 | bootfile_blobsize = byte_index - current_offset; |
974 | 1049 | ||
975 | // write boot blob |
1050 | // write boot blob |
976 | sprintf_s (outfile_pathname, sizeof (outfile_pathname), "%s/ |
1051 | sprintf_s (outfile_pathname, sizeof (outfile_pathname), "%s/boot%s.bin", outdir, exeformat_suffix); |
977 | fopen_s (&fp, outfile_pathname, "wb"); |
1052 | fopen_s (&fp, outfile_pathname, "wb"); |
978 | ASSERT (fp, "failed to open '%s': %s", outfile_pathname, strerror (errno)); |
1053 | ASSERT (fp, "failed to open '%s': %s", outfile_pathname, strerror (errno)); |
979 | fwrite (&file.bytes[current_offset], 1, bootfile_blobsize, fp); |
1054 | fwrite (&file.bytes[current_offset], 1, bootfile_blobsize, fp); |
980 | fclose (fp); |
1055 | fclose (fp); |
981 | 1056 |