mirror of
https://github.com/86Box/bios-tools.git
synced 2026-02-22 09:35:33 -07:00
bios_extract: Handle Intel compressed option ROMs
This commit is contained in:
@@ -127,7 +127,7 @@ int main(int argc, char *argv[])
|
||||
int FileLength = 0;
|
||||
uint32_t BIOSOffset = 0;
|
||||
unsigned char *BIOSImage = NULL,
|
||||
IntelAMI[256], /* just 13 bytes needed, but LH5Decode overflows the buffer */
|
||||
IntelAMI[256], /* could be shorter if not for LH5Decode overflowing the buffer */
|
||||
*Buffer = NULL;
|
||||
int fd;
|
||||
uint32_t Offset1 = 0, Offset2 = 0;
|
||||
@@ -199,30 +199,44 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* Bruteforce Intel AMI Color fork LH5. */
|
||||
for (i = 0; i < (FileLength - 10); i += 0x4000) {
|
||||
BIOSOffset = i;
|
||||
Offset2 = 1;
|
||||
for (Offset1 = 0; Offset1 < (FileLength - 10); Offset1 += 0x4000) {
|
||||
BIOSOffset = Offset1;
|
||||
CopyrightOffset:if ((LH5Decode(BIOSImage + BIOSOffset, FileLength - BIOSOffset, IntelAMI, 13) > -1) &&
|
||||
!memcmp(IntelAMI, "AMIBIOS(C)AMI", 13)) {
|
||||
printf("Found Intel AMIBIOS.\nOffset: %X\n", BIOSOffset);
|
||||
(!memcmp(IntelAMI, "AMIBIOS(C)AMI", 13) || ((IntelAMI[0] == 0x55) && (IntelAMI[1] == 0xaa)))) {
|
||||
if (Offset2 == 1) {
|
||||
printf("Found potential Intel AMIBIOS.\n");
|
||||
Offset2 = 86; /* magic exit code if no main body found */
|
||||
}
|
||||
|
||||
Buffer = MMapOutputFile("intelbody.bin", 65536);
|
||||
if (IntelAMI[0] == 0x55) {
|
||||
len = IntelAMI[2] * 512;
|
||||
sprintf((char *) IntelAMI, "intelopt_%05X.bin", BIOSOffset);
|
||||
} else {
|
||||
len = 65536;
|
||||
sprintf((char *) IntelAMI, "intelbody_%05X.bin", BIOSOffset);
|
||||
Offset2 = 0; /* main body found, all good */
|
||||
}
|
||||
|
||||
printf("0x%05X -> %s\t(%d bytes)\n",
|
||||
BIOSOffset, IntelAMI, len);
|
||||
Buffer = MMapOutputFile((char *) IntelAMI, len);
|
||||
if (!Buffer)
|
||||
return 1;
|
||||
|
||||
i = 65536;
|
||||
i = len;
|
||||
while ((LH5Decode(BIOSImage + BIOSOffset, FileLength - BIOSOffset, Buffer, i) == -1) &&
|
||||
(i > 16))
|
||||
i--;
|
||||
|
||||
munmap(Buffer, 65536);
|
||||
|
||||
return 0;
|
||||
munmap(Buffer, len);
|
||||
} else if (!(BIOSOffset & 0xff)) {
|
||||
BIOSOffset += 0x44;
|
||||
goto CopyrightOffset;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Error: Unable to detect BIOS Image type.\n");
|
||||
return 1;
|
||||
if (Offset2)
|
||||
fprintf(stderr, "Error: Unable to detect BIOS Image type.\n");
|
||||
return Offset2;
|
||||
}
|
||||
|
||||
@@ -327,6 +327,7 @@ class BIOSExtractor(Extractor):
|
||||
except:
|
||||
# Bad data can cause infinite loops.
|
||||
proc = None
|
||||
self.debug_print('Processing timed out on:', file_path)
|
||||
|
||||
# Assume failure if nothing was extracted. A lone boot block file also counts as a failure,
|
||||
# as the extractors produce them before attempting to extract any actual BIOS modules.
|
||||
@@ -336,11 +337,23 @@ class BIOSExtractor(Extractor):
|
||||
return False
|
||||
elif num_files_extracted == 1 and dest_dir_files[0] in ('amiboot.rom', 'ssboot.rom'):
|
||||
# Remove boot block file so that the destination directory can be rmdir'd later.
|
||||
try:
|
||||
os.remove(os.path.join(dest_dir_0, dest_dir_files[0]))
|
||||
except:
|
||||
pass
|
||||
util.remove_all(dest_dir_files, lambda x: os.path.join(dest_dir_0, x))
|
||||
return False
|
||||
elif proc and proc.returncode == 86:
|
||||
# We received the magic exit code indicating the Intel pipeline found
|
||||
# an option ROM but not the main body. This could indicate a non-Intel
|
||||
# BIOS with LH5-compressed option ROMs. Check the files just in case.
|
||||
have_intelopt = have_intelbody = False
|
||||
for dest_dir_file in dest_dir_files:
|
||||
if dest_dir_file[:9] == 'intelopt_':
|
||||
have_intelopt = True
|
||||
elif dest_dir_file[:10] == 'intelbody_':
|
||||
have_intelbody = True
|
||||
break
|
||||
if have_intelopt and not have_intelbody:
|
||||
# Remove all files so that the destination directory can be rmdir'd later.
|
||||
util.remove_all(dest_dir_files, lambda x: os.path.join(dest_dir_0, x))
|
||||
return False
|
||||
|
||||
# Extract Award BIOS PhoenixNet ROS filesystem.
|
||||
if not proc or b'Found Award BIOS.' in proc.stdout:
|
||||
@@ -1404,7 +1417,6 @@ class IntelExtractor(Extractor):
|
||||
if bootblock_offset < 0:
|
||||
bootblock_offset = 0
|
||||
dest_offset += bootblock_offset
|
||||
self.debug_print('bbo', hex(bootblock_offset), 'do', hex(dest_offset))
|
||||
out_f.seek(dest_offset)
|
||||
|
||||
# Copy data.
|
||||
@@ -1461,7 +1473,7 @@ class IntelExtractor(Extractor):
|
||||
out_f = open(dest_file_path + '.padded', 'wb')
|
||||
|
||||
# Write padding.
|
||||
self.debug_print('Padding by', hex(padding_size))
|
||||
self.debug_print('Adding', padding_size, 'bytes of initial padding')
|
||||
while padding_size > 0:
|
||||
out_f.write(b'\xFF' * min(padding_size, 1048576))
|
||||
padding_size -= 1048576
|
||||
|
||||
Reference in New Issue
Block a user