Subversion Repositories QNX 8.QNX8 IFS tool

Rev

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
         // so 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)
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 ("Boot blob at offset 0x%zx (%zd):\n", current_offset, current_offset);
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/startup.bin", outdir);
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 *) &current_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 *) &current_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 *) &current_fsentry->u.file.path); // convert from pointer to char array
998
                  sprintf_s (outfile_pathname, sizeof (outfile_pathname), "%s/%s", outdir, (char *) &current_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
         // so 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)
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/boot.bin", outdir);
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