VOID\r
)\r
{\r
- printf ("Usage: " UTILITY_NAME " {-t time-date} [APPLICATION|BS_DRIVER|RT_DRIVER|SAL_RT_DRIVER|COMBINED_PEIM_DRIVER|SECURITY_CORE|PEI_CORE|PE32_PEIM|RELOCATABLE_PEIM] peimage [outimage]");\r
+ printf ("Usage: " UTILITY_NAME " {-t time-date} [BASE|SEC|PEI_CORE|PEIM|DXE_CORE|DXE_DRIVER|DXE_RUNTIME_DRIVER|DXE_SAL_DRIVER|DXE_SMM_DRIVER|TOOL|UEFI_DRIVER|UEFI_APPLICATION|USER_DEFINED] peimage [outimage]");\r
}\r
\r
static\r
return STATUS_SUCCESS;\r
}\r
\r
+static\r
+STATUS\r
+FReadFile (\r
+ FILE *in,\r
+ VOID **Buffer,\r
+ UINTN *Length\r
+ )\r
+{\r
+ fseek (in, 0, SEEK_END);\r
+ *Length = ftell (in);\r
+ *Buffer = malloc (*Length);\r
+ fseek (in, 0, SEEK_SET);\r
+ fread (*Buffer, *Length, 1, in);\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+static\r
+STATUS\r
+FWriteFile (\r
+ FILE *out,\r
+ VOID *Buffer,\r
+ UINTN Length\r
+ )\r
+{\r
+ fseek (out, 0, SEEK_SET);\r
+ fwrite (Buffer, Length, 1, out);\r
+ if ((ULONG) ftell (out) != Length) {\r
+ Error (NULL, 0, 0, "write error", NULL);\r
+ return STATUS_ERROR;\r
+ }\r
+ free (Buffer);\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
int\r
main (\r
int argc,\r
UCHAR outname[500];\r
FILE *fpIn;\r
FILE *fpOut;\r
- EFI_IMAGE_DOS_HEADER DosHdr;\r
- EFI_IMAGE_NT_HEADERS PeHdr;\r
+ VOID *ZeroBuffer;\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_IMAGE_NT_HEADERS *PeHdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER32 *Optional32;\r
+ EFI_IMAGE_OPTIONAL_HEADER64 *Optional64;\r
time_t TimeStamp;\r
struct tm TimeStruct;\r
EFI_IMAGE_DOS_HEADER BackupDosHdr;\r
ULONG Index;\r
+ ULONG Index1;\r
+ ULONG Index2;\r
+ ULONG Index3;\r
BOOLEAN TimeStampPresent;\r
+ UINTN AllignedRelocSize;\r
+ UINTN Delta;\r
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
+ UINT8 *FileBuffer;\r
+ UINTN FileLength;\r
+ RUNTIME_FUNCTION *RuntimeFunction;\r
+ UNWIND_INFO *UnwindInfo;\r
\r
SetUtilityName (UTILITY_NAME);\r
//\r
p += 1;\r
}\r
\r
- if (stricmp (p, "app") == 0 || stricmp (p, "APPLICATION") == 0) {\r
+ if (stricmp (p, "app") == 0 || stricmp (p, "UEFI_APPLICATION") == 0) {\r
Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;\r
Ext = ".efi";\r
\r
- } else if (stricmp (p, "bsdrv") == 0 || stricmp (p, "BS_DRIVER") == 0) {\r
+ } else if (stricmp (p, "bsdrv") == 0 || stricmp (p, "DXE_DRIVER") == 0) {\r
Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
Ext = ".efi";\r
\r
- } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "RT_DRIVER") == 0) {\r
+ } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "DXE_RUNTIME_DRIVER") == 0) {\r
Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;\r
Ext = ".efi";\r
\r
- } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "SAL_RT_DRIVER") == 0) {\r
+ } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "DXE_SAL_DRIVER") == 0) {\r
Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;\r
Ext = ".efi";\r
- } else if (stricmp (p, "SECURITY_CORE") == 0) {\r
+ } else if (stricmp (p, "SEC") == 0) {\r
Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
Ext = ".sec";\r
} else if (stricmp (p, "peim") == 0 ||\r
+ stricmp (p, "BASE") == 0 ||\r
stricmp (p, "PEI_CORE") == 0 ||\r
- stricmp (p, "PE32_PEIM") == 0 ||\r
- stricmp (p, "RELOCATABLE_PEIM") == 0 ||\r
- stricmp (p, "combined_peim_driver") == 0\r
+ stricmp (p, "PEIM") == 0 ||\r
+ stricmp (p, "DXE_SMM_DRIVER") == 0 ||\r
+ stricmp (p, "TOOL") == 0 ||\r
+ stricmp (p, "UEFI_APPLICATION") == 0 ||\r
+ stricmp (p, "USER_DEFINED") == 0 ||\r
+ stricmp (p, "UEFI_DRIVER") == 0 ||\r
+ stricmp (p, "DXE_CORE") == 0\r
) {\r
Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
Ext = ".pei";\r
} else {\r
+ printf ("%s", p);\r
Usage ();\r
return STATUS_ERROR;\r
}\r
Error (NULL, 0, 0, argv[2], "failed to open input file for reading");\r
return STATUS_ERROR;\r
}\r
+\r
+ FReadFile (fpIn, (VOID **)&FileBuffer, &FileLength);\r
+\r
//\r
// Read the dos & pe hdrs of the image\r
//\r
- fseek (fpIn, 0, SEEK_SET);\r
- fread (&DosHdr, sizeof (DosHdr), 1, fpIn);\r
- if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;\r
+ if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
Error (NULL, 0, 0, argv[2], "DOS header signature not found in source image");\r
fclose (fpIn);\r
return STATUS_ERROR;\r
}\r
\r
- fseek (fpIn, DosHdr.e_lfanew, SEEK_SET);\r
- fread (&PeHdr, sizeof (PeHdr), 1, fpIn);\r
- if (PeHdr.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
+ PeHdr = (EFI_IMAGE_NT_HEADERS *)(FileBuffer + DosHdr->e_lfanew);\r
+ if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
Error (NULL, 0, 0, argv[2], "PE header signature not found in source image");\r
fclose (fpIn);\r
return STATUS_ERROR;\r
}\r
+\r
//\r
// open output file\r
//\r
fclose (fpIn);\r
return STATUS_ERROR;\r
}\r
- //\r
- // Copy the file\r
- //\r
- if (FCopyFile (fpIn, fpOut) != STATUS_SUCCESS) {\r
- fclose (fpIn);\r
- fclose (fpOut);\r
- return STATUS_ERROR;\r
- }\r
+\r
//\r
// Zero all unused fields of the DOS header\r
//\r
- memcpy (&BackupDosHdr, &DosHdr, sizeof (DosHdr));\r
- memset (&DosHdr, 0, sizeof (DosHdr));\r
- DosHdr.e_magic = BackupDosHdr.e_magic;\r
- DosHdr.e_lfanew = BackupDosHdr.e_lfanew;\r
- fseek (fpOut, 0, SEEK_SET);\r
- fwrite (&DosHdr, sizeof (DosHdr), 1, fpOut);\r
-\r
- fseek (fpOut, sizeof (DosHdr), SEEK_SET);\r
- for (Index = sizeof (DosHdr); Index < (ULONG) DosHdr.e_lfanew; Index++) {\r
- fwrite (&DosHdr.e_cp, 1, 1, fpOut);\r
+ memcpy (&BackupDosHdr, DosHdr, sizeof (EFI_IMAGE_DOS_HEADER));\r
+ memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER));\r
+ DosHdr->e_magic = BackupDosHdr.e_magic;\r
+ DosHdr->e_lfanew = BackupDosHdr.e_lfanew;\r
+\r
+ for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (ULONG) DosHdr->e_lfanew; Index++) {\r
+ FileBuffer[Index] = DosHdr->e_cp;\r
}\r
+\r
//\r
// Path the PE header\r
//\r
- PeHdr.OptionalHeader.Subsystem = (USHORT) Type;\r
+ PeHdr->OptionalHeader.Subsystem = (USHORT) Type;\r
if (TimeStampPresent) {\r
- PeHdr.FileHeader.TimeDateStamp = (UINT32) TimeStamp;\r
+ PeHdr->FileHeader.TimeDateStamp = (UINT32) TimeStamp;\r
+ }\r
+\r
+ if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
+ Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->OptionalHeader;\r
+ Optional32->MajorLinkerVersion = 0;\r
+ Optional32->MinorLinkerVersion = 0;\r
+ Optional32->MajorOperatingSystemVersion = 0;\r
+ Optional32->MinorOperatingSystemVersion = 0;\r
+ Optional32->MajorImageVersion = 0;\r
+ Optional32->MinorImageVersion = 0;\r
+ Optional32->MajorSubsystemVersion = 0;\r
+ Optional32->MinorSubsystemVersion = 0;\r
+ Optional32->Win32VersionValue = 0;\r
+ Optional32->CheckSum = 0;\r
+ Optional32->SizeOfStackReserve = 0;\r
+ Optional32->SizeOfStackCommit = 0;\r
+ Optional32->SizeOfHeapReserve = 0;\r
+ Optional32->SizeOfHeapCommit = 0;\r
+\r
+ //\r
+ // Strip zero padding at the end of the .reloc section \r
+ //\r
+ if (Optional32->NumberOfRvaAndSizes >= 6) {\r
+ if (Optional32->DataDirectory[5].Size != 0) {\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
+ //\r
+ // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory\r
+ //\r
+ if (SectionHeader->VirtualAddress == Optional32->DataDirectory[5].VirtualAddress) {\r
+ SectionHeader->Misc.VirtualSize = Optional32->DataDirectory[5].Size;\r
+ AllignedRelocSize = (Optional32->DataDirectory[5].Size + Optional32->FileAlignment - 1) & (~(Optional32->FileAlignment - 1));\r
+ //\r
+ // Check to see if there is zero padding at the end of the base relocations\r
+ //\r
+ if (AllignedRelocSize < SectionHeader->SizeOfRawData) {\r
+ //\r
+ // Check to see if the base relocations are at the end of the file\r
+ //\r
+ if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional32->SizeOfImage) {\r
+ //\r
+ // All the required conditions are met to strip the zero padding of the end of the base relocations section\r
+ //\r
+ Optional32->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
+ Optional32->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
+ SectionHeader->SizeOfRawData = AllignedRelocSize;\r
+ FileLength = Optional32->SizeOfImage;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } \r
+ if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
+ Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->OptionalHeader;\r
+ Optional64->MajorLinkerVersion = 0;\r
+ Optional64->MinorLinkerVersion = 0;\r
+ Optional64->MajorOperatingSystemVersion = 0;\r
+ Optional64->MinorOperatingSystemVersion = 0;\r
+ Optional64->MajorImageVersion = 0;\r
+ Optional64->MinorImageVersion = 0;\r
+ Optional64->MajorSubsystemVersion = 0;\r
+ Optional64->MinorSubsystemVersion = 0;\r
+ Optional64->Win32VersionValue = 0;\r
+ Optional64->CheckSum = 0;\r
+ Optional64->SizeOfStackReserve = 0;\r
+ Optional64->SizeOfStackCommit = 0;\r
+ Optional64->SizeOfHeapReserve = 0;\r
+ Optional64->SizeOfHeapCommit = 0;\r
+\r
+ //\r
+ // Zero the .pdata section if the machine type is X64 and the Debug Directory is empty\r
+ //\r
+ if (PeHdr->FileHeader.Machine == 0x8664) { // X64\r
+ if (Optional64->NumberOfRvaAndSizes >= 4) {\r
+ if (Optional64->NumberOfRvaAndSizes < 7 || (Optional64->NumberOfRvaAndSizes >= 7 && Optional64->DataDirectory[6].Size == 0)) {\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
+ if (SectionHeader->VirtualAddress == Optional64->DataDirectory[3].VirtualAddress) {\r
+ RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData);\r
+ for (Index1 = 0; Index1 < Optional64->DataDirectory[3].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) {\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader);\r
+ for (Index2 = 0; Index2 < PeHdr->FileHeader.NumberOfSections; Index2++, SectionHeader++) {\r
+ if (RuntimeFunction->UnwindInfoAddress > SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {\r
+ UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));\r
+ if (UnwindInfo->Version == 1) {\r
+ memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16));\r
+ memset (UnwindInfo, 0, sizeof (UNWIND_INFO));\r
+ }\r
+ }\r
+ }\r
+ memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));\r
+ }\r
+ }\r
+ }\r
+ Optional64->DataDirectory[3].Size = 0;\r
+ Optional64->DataDirectory[3].VirtualAddress = 0;\r
+ }\r
+ }\r
+ }\r
+\r
+ //\r
+ // Strip zero padding at the end of the .reloc section \r
+ //\r
+ if (Optional64->NumberOfRvaAndSizes >= 6) {\r
+ if (Optional64->DataDirectory[5].Size != 0) {\r
+ SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader);\r
+ for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
+ //\r
+ // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory\r
+ //\r
+ if (SectionHeader->VirtualAddress == Optional64->DataDirectory[5].VirtualAddress) {\r
+ SectionHeader->Misc.VirtualSize = Optional64->DataDirectory[5].Size;\r
+ AllignedRelocSize = (Optional64->DataDirectory[5].Size + Optional64->FileAlignment - 1) & (~(Optional64->FileAlignment - 1));\r
+ //\r
+ // Check to see if there is zero padding at the end of the base relocations\r
+ //\r
+ if (AllignedRelocSize < SectionHeader->SizeOfRawData) {\r
+ //\r
+ // Check to see if the base relocations are at the end of the file\r
+ //\r
+ if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional64->SizeOfImage) {\r
+ //\r
+ // All the required conditions are met to strip the zero padding of the end of the base relocations section\r
+ //\r
+ Optional64->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
+ Optional64->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
+ SectionHeader->SizeOfRawData = AllignedRelocSize;\r
+ FileLength = Optional64->SizeOfImage;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
}\r
\r
- PeHdr.OptionalHeader.SizeOfStackReserve = 0;\r
- PeHdr.OptionalHeader.SizeOfStackCommit = 0;\r
- PeHdr.OptionalHeader.SizeOfHeapReserve = 0;\r
- PeHdr.OptionalHeader.SizeOfHeapCommit = 0;\r
- fseek (fpOut, DosHdr.e_lfanew, SEEK_SET);\r
- fwrite (&PeHdr, sizeof (PeHdr), 1, fpOut);\r
+ FWriteFile (fpOut, FileBuffer, FileLength);\r
\r
//\r
// Done\r