mirror of
https://github.com/86Box/bios-tools.git
synced 2026-02-22 09:35:33 -07:00
bios_extract: Replace Phoenix remainder, amiboot, etc. with an unified remainder saving API
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#define _GNU_SOURCE 1 /* for memmem */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
@@ -180,25 +181,6 @@ AMI940725Extract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
|
||||
printf("AMI94 Version\t: %s (%s)\n", Version, Date);
|
||||
|
||||
/* First, the boot rom */
|
||||
uint32_t BootOffset;
|
||||
int fd;
|
||||
|
||||
BootOffset = AMIBOffset & 0xFFFE0000;
|
||||
|
||||
printf("0x%05X (%6d bytes) -> amiboot.rom\n", BootOffset,
|
||||
BIOSLength - BootOffset);
|
||||
|
||||
fd = open("amiboot.rom", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error: unable to open %s: %s\n\n",
|
||||
"amiboot.rom", strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
write(fd, BIOSImage + BootOffset, BIOSLength - BootOffset);
|
||||
close(fd);
|
||||
|
||||
for (i = 0; i < 0x80; i++) {
|
||||
char filename[64];
|
||||
unsigned char *Buffer;
|
||||
@@ -246,10 +228,14 @@ NotCompressed:
|
||||
strcpy(&filename[strlen(filename) - 3], "cmp");
|
||||
}
|
||||
goto NotCompressed;
|
||||
} else {
|
||||
SetRemainder(Offset, ROMSize + 8, FALSE);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
memcpy(Buffer, BIOSImage + Offset + 8,
|
||||
BufferSize);
|
||||
SetRemainder(Offset, BufferSize + 8, FALSE);
|
||||
}
|
||||
|
||||
munmap(Buffer, BufferSize);
|
||||
|
||||
@@ -312,25 +298,6 @@ AMI941010Extract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
|
||||
printf("AMI94 Version\t: %s (%s)\n", Version, Date);
|
||||
|
||||
/* First, the boot rom */
|
||||
uint32_t BootOffset;
|
||||
int fd;
|
||||
|
||||
BootOffset = AMIBOffset & 0xFFFE0000;
|
||||
|
||||
printf("0x%05X (%6d bytes) -> amiboot.rom\n", BootOffset,
|
||||
BIOSLength - BootOffset);
|
||||
|
||||
fd = open("amiboot.rom", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error: unable to open %s: %s\n\n",
|
||||
"amiboot.rom", strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
write(fd, BIOSImage + BootOffset, BIOSLength - BootOffset);
|
||||
close(fd);
|
||||
|
||||
/* now dump the individual modules */
|
||||
headerinfo = (struct headerinfo *)(BIOSImage + ABCOffset + 0x10);
|
||||
for (i = 0; i < headerinfo->ModuleCount; i++) {
|
||||
@@ -388,10 +355,14 @@ NotCompressed:
|
||||
strcpy(&filename[strlen(filename) - 3], "cmp");
|
||||
}
|
||||
goto NotCompressed;
|
||||
} else {
|
||||
SetRemainder(ABCOffset + part->RealCS, ROMSize + 8, FALSE);
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
memcpy(Buffer, BIOSImage + ABCOffset + part->RealCS,
|
||||
BufferSize);
|
||||
SetRemainder(ABCOffset + part->RealCS, BufferSize, FALSE);
|
||||
}
|
||||
|
||||
munmap(Buffer, BufferSize);
|
||||
}
|
||||
@@ -482,25 +453,6 @@ AMI95Extract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* First, the boot rom */
|
||||
uint32_t BootOffset;
|
||||
int fd;
|
||||
|
||||
BootOffset = AMIBOffset & 0xFFFF0000;
|
||||
|
||||
printf("0x%05X (%6d bytes) -> amiboot.rom\n", BootOffset,
|
||||
BIOSLength - BootOffset);
|
||||
|
||||
fd = open("amiboot.rom", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error: unable to open %s: %s\n\n",
|
||||
"amiboot.rom", strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
write(fd, BIOSImage + BootOffset, BIOSLength - BootOffset);
|
||||
close(fd);
|
||||
|
||||
/* now dump the individual modules */
|
||||
if (BIOSLength > 0x100000) {
|
||||
OffsetMode = 'A';
|
||||
@@ -626,6 +578,7 @@ NotCompressed:
|
||||
} else
|
||||
memcpy(Buffer, BIOSImage + NewOffset,
|
||||
ROMSize);
|
||||
SetRemainder(Offset - BIOSOffset, (NewOffset - (Offset - BIOSOffset)) + ROMSize, FALSE);
|
||||
|
||||
munmap(Buffer, BufferSize);
|
||||
|
||||
@@ -683,7 +636,14 @@ AFUDOSExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
|
||||
munmap(Buffer, hdr->ExpSize);
|
||||
|
||||
char *argv[] = {"", "afudos.bin"};
|
||||
if (remainder_buf) {
|
||||
SetRemainder(((unsigned char *)hdr) - BIOSImage, hdr->ROMSize, FALSE);
|
||||
SaveRemainder(BIOSImage);
|
||||
free(remainder_buf);
|
||||
rename("remainder.rom", "afudos_remainder.rom");
|
||||
}
|
||||
|
||||
char *argv[] = {"\x01", "afudos.bin"};
|
||||
int ret = main(2, argv);
|
||||
unlink("afudos.bin");
|
||||
|
||||
|
||||
@@ -35,11 +35,10 @@ AwardExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
uint32_t Offset1, uint32_t BCPSegmentOffset)
|
||||
{
|
||||
unsigned char *p, *Buffer;
|
||||
int HeaderSize;
|
||||
int HeaderSize = 0;
|
||||
unsigned int BufferSize, PackedSize;
|
||||
char *filename;
|
||||
char *filename = {0};
|
||||
unsigned short crc;
|
||||
Bool First = TRUE;
|
||||
|
||||
printf("Found Award BIOS.\n");
|
||||
|
||||
@@ -50,24 +49,6 @@ AwardExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
break;
|
||||
p -= 2;
|
||||
|
||||
if (First) {
|
||||
First = FALSE;
|
||||
BufferSize = p - BIOSImage;
|
||||
if (BufferSize > 0) {
|
||||
filename = "awardboot.rom";
|
||||
printf("0x%05X (%6d bytes) -> %s\n",
|
||||
0, BufferSize, filename);
|
||||
|
||||
Buffer = MMapOutputFile(filename, BufferSize);
|
||||
if (!Buffer)
|
||||
return FALSE;
|
||||
|
||||
memcpy(Buffer, BIOSImage, BufferSize);
|
||||
|
||||
munmap(Buffer, BufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
HeaderSize = LH5HeaderParse(p, BIOSLength - (p - BIOSImage),
|
||||
&BufferSize, &PackedSize, &filename,
|
||||
&crc);
|
||||
@@ -82,12 +63,13 @@ AwardExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
if (!Buffer)
|
||||
return FALSE;
|
||||
|
||||
LH5Decode(p + HeaderSize, PackedSize, Buffer, BufferSize);
|
||||
if (LH5Decode(p + HeaderSize, PackedSize, Buffer, BufferSize) != -1)
|
||||
SetRemainder(p - BIOSImage, HeaderSize + PackedSize, FALSE);
|
||||
|
||||
munmap(Buffer, BufferSize);
|
||||
|
||||
p += HeaderSize + PackedSize;
|
||||
}
|
||||
|
||||
return !First;
|
||||
return !!filename[0];
|
||||
}
|
||||
|
||||
@@ -92,6 +92,84 @@ unsigned char *MMapOutputFile(char *filename, int size)
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
unsigned char *remainder_buf = NULL;
|
||||
static int remainder_size = 0, remainder_padding = 0;
|
||||
|
||||
void InitRemainder(unsigned char *BIOSImage, int BIOSLength)
|
||||
{
|
||||
unsigned char *new_remainder_buf = realloc(remainder_buf, BIOSLength);
|
||||
if (new_remainder_buf) {
|
||||
remainder_buf = new_remainder_buf;
|
||||
remainder_size = BIOSLength;
|
||||
}
|
||||
|
||||
if (!remainder_buf)
|
||||
return;
|
||||
|
||||
/* Remove padding from the start only, as the end will have the entry point anyway. */
|
||||
if (remainder_size < BIOSLength)
|
||||
BIOSLength = remainder_size;
|
||||
unsigned char *p = BIOSImage, *q = BIOSImage + BIOSLength;
|
||||
while ((p < q) && ((*p == 0x00) || (*p == 0xff)))
|
||||
p++;
|
||||
|
||||
remainder_padding = p - BIOSImage;
|
||||
if (remainder_padding > 0) {
|
||||
BIOSLength -= remainder_padding;
|
||||
memset(remainder_buf, 0x00, remainder_padding);
|
||||
}
|
||||
memset(remainder_buf + remainder_padding, 0xff, BIOSLength);
|
||||
}
|
||||
|
||||
void SetRemainder(uint32_t Offset, uint32_t Length, int val)
|
||||
{
|
||||
if (!remainder_buf)
|
||||
return;
|
||||
|
||||
if ((remainder_size - Offset) < Length)
|
||||
Length = remainder_size - Offset;
|
||||
memset(remainder_buf + Offset, 0xff * !!val, Length);
|
||||
}
|
||||
|
||||
int SaveRemainder(unsigned char *BIOSImage)
|
||||
{
|
||||
if (!remainder_buf)
|
||||
return TRUE;
|
||||
|
||||
if (remainder_padding > 0)
|
||||
printf("Padding (%6d bytes) -> [discarded]\n",
|
||||
remainder_padding);
|
||||
|
||||
int fd = open("remainder.rom", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error: unable to open remainder.rom: %s\n\n",
|
||||
strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int remaining = remainder_size, copy;
|
||||
unsigned char *p = remainder_buf, *q, c = *p;
|
||||
while (p) {
|
||||
c = ~c;
|
||||
q = memchr(p, c, remaining);
|
||||
if (q)
|
||||
copy = q - p;
|
||||
else
|
||||
copy = remaining;
|
||||
if (!c)
|
||||
write(fd, BIOSImage + (p - remainder_buf), copy);
|
||||
remaining -= copy;
|
||||
p = q;
|
||||
}
|
||||
|
||||
printf("Remains (%6ld bytes) -> remainder.rom\n",
|
||||
lseek(fd, 0, SEEK_CUR));
|
||||
|
||||
close(fd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* TODO: Make bios identification more flexible */
|
||||
|
||||
static struct {
|
||||
@@ -191,11 +269,17 @@ int main(int argc, char *argv[])
|
||||
Offset2 = Offset1;
|
||||
}
|
||||
|
||||
if (BIOSIdentification[i].Handler
|
||||
(BIOSImage, FileLength, BIOSOffset, Offset1, Offset2))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
if ((argv[0][0] != 0x01) || (argv[0][1] != 0x00))
|
||||
InitRemainder(BIOSImage, FileLength);
|
||||
|
||||
len = BIOSIdentification[i].Handler
|
||||
(BIOSImage, FileLength, BIOSOffset, Offset1, Offset2);
|
||||
if (remainder_buf) {
|
||||
len &= SaveRemainder(BIOSImage);
|
||||
free(remainder_buf);
|
||||
remainder_buf = NULL;
|
||||
}
|
||||
return len ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Bruteforce Intel AMI Color fork LH5. */
|
||||
@@ -206,28 +290,32 @@ CopyrightOffset:if ((LH5Decode(BIOSImage + BIOSOffset, FileLength - BIOSOffset,
|
||||
(!memcmp(IntelAMI, "AMIBIOS(C)AMI", 13) || ((IntelAMI[0] == 0x55) && (IntelAMI[1] == 0xaa)))) {
|
||||
if (Offset2 == 1) {
|
||||
printf("Found potential Intel AMIBIOS.\n");
|
||||
InitRemainder(BIOSImage, FileLength);
|
||||
Offset2 = 86; /* magic exit code if no main body found */
|
||||
}
|
||||
|
||||
if (IntelAMI[0] == 0x55) {
|
||||
len = IntelAMI[2] * 512;
|
||||
sprintf((char *) IntelAMI, "intelopt_%05X.bin", BIOSOffset);
|
||||
sprintf((char *) IntelAMI, "intelopt_%05X.rom", BIOSOffset);
|
||||
} else {
|
||||
len = 65536;
|
||||
sprintf((char *) IntelAMI, "intelbody_%05X.bin", BIOSOffset);
|
||||
sprintf((char *) IntelAMI, "intelbody_%05X.rom", 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 = len;
|
||||
while ((LH5Decode(BIOSImage + BIOSOffset, FileLength - BIOSOffset, Buffer, i) == -1) &&
|
||||
while (((fd = LH5Decode(BIOSImage + BIOSOffset, FileLength - BIOSOffset, Buffer, i)) == -1) &&
|
||||
(i > 16))
|
||||
i--;
|
||||
if (fd > 0) {
|
||||
printf("0x%05X (%6d bytes) -> %s\t(%d bytes)\n",
|
||||
BIOSOffset, fd, IntelAMI, len);
|
||||
SetRemainder(BIOSOffset, fd, FALSE);
|
||||
}
|
||||
|
||||
munmap(Buffer, len);
|
||||
} else if (!(BIOSOffset & 0xff)) {
|
||||
@@ -238,5 +326,7 @@ CopyrightOffset:if ((LH5Decode(BIOSImage + BIOSOffset, FileLength - BIOSOffset,
|
||||
|
||||
if (Offset2)
|
||||
fprintf(stderr, "Error: Unable to detect BIOS Image type.\n");
|
||||
else
|
||||
return !SaveRemainder(BIOSImage);
|
||||
return Offset2;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@
|
||||
|
||||
/* bios_extract.c */
|
||||
unsigned char *MMapOutputFile(char *filename, int size);
|
||||
extern unsigned char *remainder_buf;
|
||||
void InitRemainder(unsigned char *BIOSImage, int BIOSLength);
|
||||
void SetRemainder(uint32_t Offset, uint32_t Length, int val);
|
||||
int SaveRemainder(unsigned char *BIOSImage);
|
||||
|
||||
int main(int argc, char *argv[]);
|
||||
|
||||
/* ami.c */
|
||||
|
||||
@@ -549,5 +549,5 @@ LH5Decode(unsigned char *PackedBuffer, int PackedBufferSize,
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return CompressedOffset;
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ phx_write_file(unsigned char *BIOSImage, char *filename, short filetype,
|
||||
|
||||
#define MODULE_SIGNATURE_INVALID(Module) (Module->Signature[0] || (Module->Signature[1] != 0x31) || (Module->Signature[2] != 0x31))
|
||||
|
||||
static int PhoenixModule(unsigned char *BIOSImage, int BIOSLength, int Offset, unsigned char *remainder)
|
||||
static int PhoenixModule(unsigned char *BIOSImage, int BIOSLength, int Offset)
|
||||
{
|
||||
struct PhoenixModuleHeader *Module, *NewModule;
|
||||
|
||||
@@ -395,8 +395,7 @@ valid_signature:
|
||||
|
||||
memcpy(ModuleData, BIOSImage + Offset + Module->HeadLen,
|
||||
FragLength);
|
||||
if (remainder)
|
||||
memset(remainder + Offset, 0, Module->HeadLen + FragLength);
|
||||
SetRemainder(Offset, Module->HeadLen + FragLength, FALSE);
|
||||
|
||||
Packed = FragLength;
|
||||
FragOffset = le32toh(Module->NextFrag) & (BIOSLength - 1);
|
||||
@@ -418,8 +417,7 @@ valid_signature:
|
||||
Remain = BIOSLength - ((ModuleData + Packed) - BIOSImage);
|
||||
memcpy(ModuleData + Packed, BIOSImage + FragOffset + 9,
|
||||
(Remain < FragLength) ? Remain : FragLength);
|
||||
if (remainder)
|
||||
memset(remainder + FragOffset + 9, 0, (Remain < FragLength) ? Remain : FragLength);
|
||||
SetRemainder(FragOffset + 9, (Remain < FragLength) ? Remain : FragLength, FALSE);
|
||||
Packed += FragLength;
|
||||
FragOffset =
|
||||
le32toh(Fragment->NextFrag) & (BIOSLength - 1);
|
||||
@@ -507,7 +505,7 @@ BadFragment:
|
||||
le32toh(Module->ExpLen));
|
||||
munmap(Buffer, le32toh(Module->ExpLen));
|
||||
/* Write compressed data if decompression failed. */
|
||||
if (ExtractResult)
|
||||
if (ExtractResult == -1)
|
||||
goto Uncompressed;
|
||||
break;
|
||||
|
||||
@@ -535,8 +533,8 @@ Uncompressed:
|
||||
|
||||
if (IsFragment)
|
||||
free(ModuleData);
|
||||
else if (remainder)
|
||||
memset(remainder + Offset, 0, Module->HeadLen + Packed);
|
||||
else
|
||||
SetRemainder(Offset, Module->HeadLen + Packed, FALSE);
|
||||
|
||||
if (le16toh(Module->Offset) || le16toh(Module->Segment)) {
|
||||
if (!Module->Compression)
|
||||
@@ -974,7 +972,7 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
struct PhoenixBCD6F1 *BCD6F1;
|
||||
uint32_t Offset, Length;
|
||||
int fd;
|
||||
unsigned char *p, *Buffer, *remainder,
|
||||
unsigned char *p, *Buffer,
|
||||
module_signature[] = {0x00, 0x31, 0x31},
|
||||
bcd6f1_signature[] = {'B', 'C', 0xd6, 0xf1, 0x00, 0x00, 0x12},
|
||||
optrom_signature[] = {0x55, 0xaa},
|
||||
@@ -994,12 +992,9 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
*/
|
||||
if (BIOSLength > 0x100000 && BIOSOffset > 0) {
|
||||
BIOSLength = BIOSLength + BIOSOffset - 0x100000;
|
||||
InitRemainder(BIOSImage, BIOSLength);
|
||||
}
|
||||
|
||||
remainder = malloc(BIOSLength);
|
||||
if (remainder)
|
||||
memcpy(remainder, BIOSImage, BIOSLength);
|
||||
|
||||
for (ID = (struct PhoenixID *)(BIOSImage + BCPSegmentOffset + 10);
|
||||
((void *)ID < (void *)(BIOSImage + BIOSLength)) && ID->Name[0];
|
||||
ID =
|
||||
@@ -1078,7 +1073,7 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
}
|
||||
|
||||
while (Offset) {
|
||||
Offset = PhoenixModule(BIOSImage, BIOSLength, Offset, remainder);
|
||||
Offset = PhoenixModule(BIOSImage, BIOSLength, Offset);
|
||||
Offset &= BIOSLength - 1;
|
||||
}
|
||||
|
||||
@@ -1102,8 +1097,7 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
if (!Buffer)
|
||||
break;
|
||||
|
||||
if (remainder)
|
||||
memset(remainder + (p - BIOSImage), 0, sizeof(struct PhoenixBCD6F1) + le32toh(BCD6F1->FragLength));
|
||||
SetRemainder(p - BIOSImage, sizeof(struct PhoenixBCD6F1) + le32toh(BCD6F1->FragLength), FALSE);
|
||||
|
||||
p += sizeof(struct PhoenixBCD6F1);
|
||||
if (phx.compression == 0)
|
||||
@@ -1144,8 +1138,7 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
write(fd, p, Length);
|
||||
close(fd);
|
||||
|
||||
if (remainder)
|
||||
memset(remainder + (p - BIOSImage), 0, Length);
|
||||
SetRemainder(p - BIOSImage, Length, FALSE);
|
||||
p += Length;
|
||||
}
|
||||
|
||||
@@ -1177,8 +1170,7 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
write(fd, p, Length);
|
||||
close(fd);
|
||||
|
||||
if (remainder)
|
||||
memset(remainder + (p - BIOSImage), 0, Length);
|
||||
SetRemainder(p - BIOSImage, Length, FALSE);
|
||||
p += Length;
|
||||
}
|
||||
|
||||
@@ -1193,7 +1185,7 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
|
||||
Module = (struct PhoenixModuleHeader *)p;
|
||||
if (!MODULE_SIGNATURE_INVALID(Module))
|
||||
PhoenixModule(BIOSImage, BIOSLength, p - BIOSImage, remainder);
|
||||
PhoenixModule(BIOSImage, BIOSLength, p - BIOSImage);
|
||||
|
||||
p += sizeof(struct PhoenixModuleHeader);
|
||||
}
|
||||
@@ -1223,8 +1215,7 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
write(fd, p, Length);
|
||||
close(fd);
|
||||
|
||||
if (remainder)
|
||||
memset(remainder + (p - BIOSImage), 0, Length);
|
||||
SetRemainder(p - BIOSImage, Length, FALSE);
|
||||
p += Length;
|
||||
}
|
||||
|
||||
@@ -1258,8 +1249,7 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
write(fd, p, Length);
|
||||
close(fd);
|
||||
|
||||
if (remainder)
|
||||
memset(remainder + (p - BIOSImage), 0, Length);
|
||||
SetRemainder(p - BIOSImage, Length, FALSE);
|
||||
p += Length;
|
||||
}
|
||||
|
||||
@@ -1289,39 +1279,11 @@ PhoenixExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
Offset, Length);
|
||||
write(fd, BIOSImage + Offset, Length);
|
||||
close(fd);
|
||||
if (remainder)
|
||||
memset(remainder + Offset, 0, Length);
|
||||
SetRemainder(Offset, Length, FALSE);
|
||||
}
|
||||
|
||||
/* Extract remaining data */
|
||||
if (remainder) {
|
||||
/* Manually flag BCPSEGMENT data as remaining, just in case */
|
||||
Offset = BCPSegmentOffset;
|
||||
Length = ((unsigned char *)ID) - (BIOSImage + Offset);
|
||||
if ((Offset + Length) > BIOSLength)
|
||||
Length = BIOSLength - Offset;
|
||||
memset(remainder + Offset, 0x55, Length);
|
||||
|
||||
fd = open("remainder.rom", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error: unable to open remainder.rom: %s\n\n",
|
||||
strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
printf("0x%05X (%6d bytes) -> remainder.rom\n",
|
||||
Offset, Length);
|
||||
if (remainder) {
|
||||
Offset = 0;
|
||||
Length = BIOSLength - 1;
|
||||
while ((Offset <= Length) && ((remainder[Offset] == 0x00) || (remainder[Offset] == 0xff)))
|
||||
Offset++;
|
||||
while ((Offset <= Length) && ((remainder[Length] == 0x00) || (remainder[Length] == 0xff)))
|
||||
Length--;
|
||||
if ((Offset <= Length) && (Length > 0))
|
||||
write(fd, BIOSImage + Offset, Length);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
/* Manually flag BCPSEGMENT data as remaining, just in case */
|
||||
SetRemainder(BCPSegmentOffset, ((unsigned char *)ID) - (BIOSImage + BCPSegmentOffset), TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -90,8 +90,7 @@ SystemSoftExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
Length = le16toh(part->PackedLen);
|
||||
sprintf(filename, "ssbody_%05X.rom", Offset);
|
||||
if (Magic == 0x88FF) {
|
||||
/* another tool called insydeco might be able to decompress
|
||||
Insyde modules, but it's been lost to time... */
|
||||
/* nobody seems to know how this compression works */
|
||||
strcpy(ModuleName, "Insyde module");
|
||||
} else {
|
||||
IsPart = 1;
|
||||
@@ -225,6 +224,9 @@ SystemSoftExtract(unsigned char *BIOSImage, int BIOSLength, int BIOSOffset,
|
||||
printf("\t\t\t%s\n", ModuleName);
|
||||
}
|
||||
|
||||
i = ((unsigned char *)part) - BIOSImage;
|
||||
SetRemainder(i, Offset - i, FALSE);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
@@ -329,18 +329,17 @@ class BIOSExtractor(Extractor):
|
||||
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.
|
||||
# Assume failure if nothing was extracted. A lone remainder file also counts as a failure.
|
||||
dest_dir_files = os.listdir(dest_dir_0)
|
||||
num_files_extracted = len(dest_dir_files)
|
||||
if num_files_extracted < 1:
|
||||
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.
|
||||
elif num_files_extracted == 1 and dest_dir_files[0] == 'remainder.rom':
|
||||
# Remove remainder file 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
|
||||
elif proc and proc.returncode == 86:
|
||||
# We received the magic exit code indicating the Intel pipeline found
|
||||
# We received the magic exit code that tells us 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
|
||||
@@ -355,6 +354,11 @@ class BIOSExtractor(Extractor):
|
||||
util.remove_all(dest_dir_files, lambda x: os.path.join(dest_dir_0, x))
|
||||
return False
|
||||
|
||||
# A missing remainder.rom may indicate an extraction interrupted by a segfault
|
||||
# or something else gone wrong. Copy the original file to its place for safety.
|
||||
if 'remainder.rom' not in dest_dir_files:
|
||||
util.hardlink_or_copy(file_path, os.path.join(dest_dir_0, 'remainder.rom'))
|
||||
|
||||
# Extract Award BIOS PhoenixNet ROS filesystem.
|
||||
if not proc or b'Found Award BIOS.' in proc.stdout:
|
||||
for dest_dir_file in dest_dir_files:
|
||||
|
||||
Reference in New Issue
Block a user