[RTL/NDK]: For some strange reason, we were missing LdrRelocateImage. Also we had the right type for LdrRelocateImageWithBias, but not the former. Fix that.

[BOOTLIB]: Finish the rest of the image loader. However, relocations appear to fail.

svn path=/trunk/; revision=70634
This commit is contained in:
Alex Ionescu 2016-01-21 16:16:12 +00:00
parent 55b6c66d7a
commit 445a748bf8
4 changed files with 131 additions and 34 deletions

View file

@ -153,7 +153,11 @@ DEFINE_GUID(BadMemoryGuid, 0x54B8275B, 0xD431, 0x473F, 0xAC, 0xFB, 0xE5, 0x36, 0
#define BL_LOAD_PE_IMG_EXISTING_BUFFER BL_LOAD_IMG_EXISTING_BUFFER
#define BL_LOAD_PE_IMG_COMPUTE_HASH 0x10
#define BL_LOAD_PE_IMG_CHECK_SUBSYSTEM 0x80
#define BL_LOAD_PE_IMG_SKIP_RELOCATIONS 0x100
#define BL_LOAD_PE_IMG_CHECK_FORCED_INTEGRITY 0x200
#define BL_LOAD_PE_IMG_IGNORE_CHECKSUM_MISMATCH 0x10000
#define BL_LOAD_PE_IMG_VALIDATE_ORIGINAL_FILENAME 0x400000
#define BL_UTL_CHECKSUM_COMPLEMENT 0x10000
#define BL_UTL_CHECKSUM_ROTATE 0x20000

View file

@ -656,33 +656,27 @@ ImgpLoadPEImage (
_In_ PBL_IMG_FILE ImageFile,
_In_ BL_MEMORY_TYPE MemoryType,
_Inout_ PVOID* ImageBase,
_Out_ PULONG ImageSize,
_Out_opt_ PULONG ImageSize,
_Inout_opt_ PVOID Hash,
_In_ ULONG Flags
)
{
NTSTATUS Status;
ULONG FileSize, HeaderSize;
PVOID ImageBuffer;
BL_IMG_FILE LocalFileBuffer;
PBL_IMG_FILE LocalFile;
PVOID VirtualAddress;
PVOID VirtualAddress, PreferredBase, ImageBuffer, CertBuffer, HashBuffer;
ULONGLONG VirtualSize;
PIMAGE_DATA_DIRECTORY CertDirectory;
PHYSICAL_ADDRESS PhysicalAddress;
PIMAGE_NT_HEADERS NtHeaders;
USHORT SectionCount;
USHORT CheckSum, PartialSum;
USHORT SectionCount, CheckSum, PartialSum, FinalSum;
PIMAGE_SECTION_HEADER Section;
ULONG_PTR EndOfHeaders, SectionStart;
ULONG i;
BOOLEAN First;
ULONG_PTR Slack, SectionEnd;
ULONG SectionSize, RawSize;
ULONG BytesRead, RemainingLength;
ULONG_PTR EndOfHeaders, SectionStart, Slack, SectionEnd;
ULONG i, SectionSize, RawSize, BytesRead, RemainingLength, Offset, AlignSize;
BOOLEAN First, ImageHashValid;
UCHAR LocalBuffer[1024];
USHORT FinalSum;
ULONG Offset;
ULONG AlignSize;
UCHAR TrustedBootInformation[52];
/* Initialize locals */
LocalFile = NULL;
@ -690,8 +684,13 @@ ImgpLoadPEImage (
FileSize = 0;
First = FALSE;
VirtualAddress = NULL;
CertBuffer = NULL;
CertDirectory = NULL;
HashBuffer = NULL;
Offset = 0;
VirtualSize = 0;
ImageHashValid = FALSE;
RtlZeroMemory(&TrustedBootInformation, sizeof(TrustedBootInformation));
/* Get the size of the image */
Status = ImgpGetFileSize(ImageFile, &FileSize);
@ -1084,18 +1083,98 @@ ImgpLoadPEImage (
}
/* If the checksum doesn't match, and caller is enforcing, bail out */
EfiPrintf(L"Final checksum: %lx. Original: %lx\r\n", FinalSum, CheckSum);
if ((FinalSum != CheckSum) && !(Flags & 0x10000))
if ((FinalSum != CheckSum) &&
!(Flags & BL_LOAD_PE_IMG_IGNORE_CHECKSUM_MISMATCH))
{
Status = STATUS_IMAGE_CHECKSUM_MISMATCH;
goto Quickie;
}
}
/* Check if the .rsrc section should be checked with the filename */
if (Flags & BL_LOAD_PE_IMG_VALIDATE_ORIGINAL_FILENAME)
{
EfiPrintf(L"Not yet supported\r\n");
Status = 0xC0430007; // STATUS_SECUREBOOT_FILE_REPLACED
goto Quickie;
}
/* Check if we should relocate */
if (!(Flags & BL_LOAD_PE_IMG_SKIP_RELOCATIONS))
{
/* Check if we loaded at a different address */
PreferredBase = (PVOID)NtHeaders->OptionalHeader.ImageBase;
if (VirtualAddress != PreferredBase)
{
/* Yep -- do relocations */
Status = LdrRelocateImage(VirtualAddress,
"Boot Environment Library",
STATUS_SUCCESS,
STATUS_UNSUCCESSFUL,
STATUS_INVALID_IMAGE_FORMAT);
if (!NT_SUCCESS(Status))
{
/* That's bad */
goto Quickie;
}
}
}
#if BL_TPM_SUPPORT
/* Check if the image hash was valid */
if (!ImageHashValid)
{
/* Send a TPM/SI notification without a context */
BlEnNotifyEvent(0x10000002, NULL);
}
/* Now send a TPM/SI notification with the hash of the loaded image */
BlMmTranslateVirtualAddress(VirtualAddress, &Context.ImageBase);
Context.HashAlgorithm = HashAlgorithm;
Context.HashSize = HashSize;
Context.FileName = ImageFile->FileName;
Context.ImageSize = VirtualSize;
Context.HashValid = ImageHashValid;
Context.Hash = Hash;
BlEnNotifyEvent(0x10000002, &Context);
#endif
/* Return the loaded address to the caller */
*ImageBase = VirtualAddress;
/* If the caller wanted the image size, return it too */
if (ImageSize)
{
*ImageSize = VirtualSize;
}
EfiPrintf(L"MORE PE TODO: %lx\r\n", NtHeaders->OptionalHeader.AddressOfEntryPoint);
EfiStall(100000000);
Quickie:
/* Check if we computed the image hash OK */
if (ImageHashValid)
{
/* Then free the information that ImgpValidateImageHash set up */
EfiPrintf(L"leadking trusted boot\r\n");
//ImgpDestroyTrustedBootInformation(&TrustedBootInformation);
}
/* Check if we had a hash buffer */
if (HashBuffer)
{
/* Free it */
EfiPrintf(L"Leadking hash: %p\r\n", HashBuffer);
//MmPapFreePages(HashBuffer, TRUE);
}
/* Check if we have a certificate diretory */
if ((CertBuffer) && (CertDirectory))
{
/* Free it */
BlImgUnallocateImageBuffer(CertBuffer, CertDirectory->Size, 0);
}
/* Check if we had an image buffer allocated */
if ((ImageBuffer) && (FileSize))
{
@ -1505,6 +1584,8 @@ ImgArchEfiStartBootApplication (
)
{
/* Not yet implemented. This is the last step! */
EfiPrintf(L"EFI APPLICATION START!!!\r\n");
EfiStall(100000000);
return STATUS_NOT_IMPLEMENTED;
}

View file

@ -98,7 +98,7 @@ ULONG
NTAPI
LdrRelocateImage(
_In_ PVOID NewBase,
_In_ PUCHAR LoaderName,
_In_ PCCH LoaderName,
_In_ ULONG Success,
_In_ ULONG Conflict,
_In_ ULONG Invalid

View file

@ -346,24 +346,24 @@ RtlImageRvaToVa(
{
PIMAGE_SECTION_HEADER Section = NULL;
if (SectionHeader)
Section = *SectionHeader;
if ((Section == NULL) ||
(Rva < SWAPD(Section->VirtualAddress)) ||
(Rva >= SWAPD(Section->VirtualAddress) + SWAPD(Section->SizeOfRawData)))
{
Section = RtlImageRvaToSection(NtHeader, BaseAddress, Rva);
if (Section == NULL)
return NULL;
if (SectionHeader)
Section = *SectionHeader;
*SectionHeader = Section;
}
if ((Section == NULL) ||
(Rva < SWAPD(Section->VirtualAddress)) ||
(Rva >= SWAPD(Section->VirtualAddress) + SWAPD(Section->SizeOfRawData)))
{
Section = RtlImageRvaToSection(NtHeader, BaseAddress, Rva);
if (Section == NULL)
return NULL;
if (SectionHeader)
*SectionHeader = Section;
}
return (PVOID)((ULONG_PTR)BaseAddress + Rva +
(ULONG_PTR)SWAPD(Section->PointerToRawData) -
(ULONG_PTR)SWAPD(Section->VirtualAddress));
return (PVOID)((ULONG_PTR)BaseAddress + Rva +
(ULONG_PTR)SWAPD(Section->PointerToRawData) -
(ULONG_PTR)SWAPD(Section->VirtualAddress));
}
PIMAGE_BASE_RELOCATION
@ -426,7 +426,7 @@ LdrProcessRelocationBlockLongLong(
default:
DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
DPRINT1("Address %p, Current %u, Count %u, *TypeOffset %x\n",
(PVOID)Address, i, Count, SWAPW(*TypeOffset));
(PVOID)Address, i, Count, SWAPW(*TypeOffset));
return (PIMAGE_BASE_RELOCATION)NULL;
}
@ -436,6 +436,18 @@ LdrProcessRelocationBlockLongLong(
return (PIMAGE_BASE_RELOCATION)TypeOffset;
}
ULONG
NTAPI
LdrRelocateImage(
IN PVOID BaseAddress,
IN PCCH LoaderName,
IN ULONG Success,
IN ULONG Conflict,
IN ULONG Invalid)
{
return LdrRelocateImageWithBias(BaseAddress, 0, LoaderName, Success, Conflict, Invalid);
}
ULONG
NTAPI
LdrRelocateImageWithBias(