mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
- Update FreeLDR PE Loading to actually use its Mm routines to allocate a buffer to read an image file into, then to allocate the actual load base and use the same code as in sysldr.c right now to PE-load the image into memory, then free the original read buffer. Not yet enabled for drivers!
- This means that: - 1) FreeLDR now keeps memory accounting information for the image files it loads, instead of us randomly writing to memory. - 2) We now skip sections marked as NO_LOAD. The kernel already re-mapped drivers doing this, but it didn't remap the kernel/hal, plus we still had to map the drivers once in FreeLDR, so we're saving a meg+ of kernel memory. svn path=/trunk/; revision=25894
This commit is contained in:
parent
8ccd7405b6
commit
9969d07b68
3 changed files with 82 additions and 47 deletions
|
@ -598,46 +598,64 @@ LdrPEFixupImports(IN PVOID DllBase,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
ULONG
|
||||
NTAPI
|
||||
FrLdrReMapImage(IN PIMAGE_NT_HEADERS NtHeader,
|
||||
IN PVOID Base)
|
||||
FrLdrReMapImage(IN PVOID Base,
|
||||
IN PVOID LoadBase)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PIMAGE_SECTION_HEADER Section;
|
||||
ULONG SectionCount, SectionSize;
|
||||
PVOID SourceSection, TargetSection;
|
||||
INT i;
|
||||
ULONG i, Size, DriverSize = 0;
|
||||
|
||||
/* Load the first section */
|
||||
/* Get the first section */
|
||||
NtHeader = RtlImageNtHeader(Base);
|
||||
Section = IMAGE_FIRST_SECTION(NtHeader);
|
||||
SectionCount = NtHeader->FileHeader.NumberOfSections - 1;
|
||||
|
||||
/* Now go to the last section */
|
||||
Section += SectionCount;
|
||||
|
||||
/* Walk each section backwards */
|
||||
for (i = SectionCount; i >= 0; i--, Section--)
|
||||
/* Determine the size of the module */
|
||||
for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
/* Get the disk location and the memory location, and the size */
|
||||
SourceSection = RVA(Base, Section->PointerToRawData);
|
||||
TargetSection = RVA(Base, Section->VirtualAddress);
|
||||
SectionSize = Section->SizeOfRawData;
|
||||
|
||||
/* If the section is already mapped correctly, go to the next */
|
||||
if (SourceSection == TargetSection) continue;
|
||||
|
||||
/* Load it into memory */
|
||||
RtlMoveMemory(TargetSection, SourceSection, SectionSize);
|
||||
|
||||
/* Check for uninitialized data */
|
||||
if (Section->SizeOfRawData < Section->Misc.VirtualSize)
|
||||
/* Skip this section if we're not supposed to load it */
|
||||
if (!(Section[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD))
|
||||
{
|
||||
/* Zero it out */
|
||||
RtlZeroMemory(RVA(Base, Section->VirtualAddress +
|
||||
Section->SizeOfRawData),
|
||||
Section->Misc.VirtualSize - Section->SizeOfRawData);
|
||||
/* Add the size of this section into the total size */
|
||||
Size = Section[i].VirtualAddress + Section[i].Misc.VirtualSize;
|
||||
DriverSize = max(DriverSize, Size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Round up the driver size to section alignment */
|
||||
DriverSize = ROUND_UP(DriverSize, NtHeader->OptionalHeader.SectionAlignment);
|
||||
|
||||
/* Allocate memory for the driver */
|
||||
LoadBase = MmAllocateMemoryAtAddress(DriverSize, LoadBase);
|
||||
ASSERT(LoadBase);
|
||||
|
||||
/* Copy headers over */
|
||||
RtlMoveMemory(LoadBase,
|
||||
Base,
|
||||
NtHeader->OptionalHeader.SizeOfHeaders);
|
||||
|
||||
/* Copy image sections into virtual section */
|
||||
for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
|
||||
{
|
||||
/* Get the size of this section and check if it's valid and on-disk */
|
||||
Size = Section[i].VirtualAddress + Section[i].Misc.VirtualSize;
|
||||
if ((Size <= DriverSize) && (Section[i].SizeOfRawData))
|
||||
{
|
||||
/* Copy the data from the disk to the image */
|
||||
RtlCopyMemory((PVOID)((ULONG_PTR)LoadBase +
|
||||
Section[i].VirtualAddress),
|
||||
(PVOID)((ULONG_PTR)Base +
|
||||
Section[i].PointerToRawData),
|
||||
Section[i].Misc.VirtualSize >
|
||||
Section[i].SizeOfRawData ?
|
||||
Section[i].SizeOfRawData :
|
||||
Section[i].Misc.VirtualSize);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the size of the mapped driver */
|
||||
return DriverSize;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
|
@ -646,32 +664,40 @@ FrLdrMapImage(IN FILE *Image,
|
|||
IN PCHAR Name,
|
||||
IN ULONG ImageType)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PVOID ImageBase, LoadBase;
|
||||
ULONG ImageSize;
|
||||
PVOID ImageBase, LoadBase, ReadBuffer;
|
||||
ULONG ImageId = LoaderBlock.ModsCount;
|
||||
ULONG ImageSize;
|
||||
|
||||
/* Set the virtual (image) and physical (load) addresses */
|
||||
LoadBase = (PVOID)NextModuleBase;
|
||||
ImageBase = RVA(LoadBase , -KERNEL_BASE_PHYS + KSEG0_BASE);
|
||||
|
||||
/* Load the first 1024 bytes of the HAL image so we can read the PE header */
|
||||
if (!FsReadFile(Image, 1024, NULL, LoadBase)) return FALSE;
|
||||
|
||||
/* Now read the MZ header to get the offset to the PE Header */
|
||||
NtHeader = RtlImageNtHeader(LoadBase);
|
||||
|
||||
/* Save the Image Size */
|
||||
ImageSize = NtHeader->OptionalHeader.SizeOfImage;
|
||||
ImageSize = FsGetFileSize(Image);
|
||||
|
||||
/* Set the file pointer to zero */
|
||||
FsSetFilePointer(Image, 0);
|
||||
|
||||
/* Load the file image */
|
||||
FsReadFile(Image, ImageSize, NULL, LoadBase);
|
||||
if (ImageType != 2)
|
||||
{
|
||||
/* Allocate a temporary buffer for the read */
|
||||
ReadBuffer = MmAllocateMemory(ImageSize);
|
||||
|
||||
/* Map it into virtual memory */
|
||||
if (ImageType != 2) FrLdrReMapImage(NtHeader, LoadBase);
|
||||
/* Load the file image */
|
||||
FsReadFile(Image, ImageSize, NULL, ReadBuffer);
|
||||
|
||||
/* Map it into virtual memory */
|
||||
ImageSize = FrLdrReMapImage(ReadBuffer, LoadBase);
|
||||
|
||||
/* Free the temporary buffer */
|
||||
MmFreeMemory(ReadBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Load the file image */
|
||||
FsReadFile(Image, ImageSize, NULL, LoadBase);
|
||||
ImageSize = RtlImageNtHeader(LoadBase)->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
|
||||
/* Calculate Difference between Real Base and Compiled Base*/
|
||||
if (ImageType != 2) LdrRelocateImageWithBias(LoadBase,
|
||||
|
@ -698,6 +724,8 @@ FrLdrMapImage(IN FILE *Image,
|
|||
/* Load HAL if this is the kernel */
|
||||
if (ImageType == 1)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
NtHeader = RtlImageNtHeader(LoadBase);
|
||||
KernelBase = NtHeader->OptionalHeader.ImageBase;
|
||||
KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
|
||||
FrLdrLoadImage("hal.dll", 10, FALSE);
|
||||
|
|
|
@ -839,7 +839,9 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
|
|||
PWCHAR FileNameWithoutPath;
|
||||
LPWSTR FileExtension;
|
||||
PUNICODE_STRING ModuleName = &LdrEntry->BaseDllName;
|
||||
#if 1 // Disable for FreeLDR 2.5
|
||||
PLDR_DATA_TABLE_ENTRY ModuleObject;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -873,9 +875,11 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
|
|||
}
|
||||
|
||||
/*
|
||||
* Load the module. Remove for FreeLDR 2.5.
|
||||
* Load the module.
|
||||
*/
|
||||
RtlCreateUnicodeString(&DeviceNode->ServiceName, FileNameWithoutPath);
|
||||
|
||||
#if 1 // Remove for FreeLDR 2.5.
|
||||
Status = LdrProcessDriverModule(LdrEntry, &DeviceNode->ServiceName, &ModuleObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -883,6 +887,7 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
|
|||
CPRINT("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
|
||||
return Status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Load symbols */
|
||||
KDB_SYMBOLFILE_HOOK(ModuleName);
|
||||
|
@ -900,7 +905,7 @@ IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
|
|||
/*
|
||||
* Initialize the driver
|
||||
*/
|
||||
Status = IopInitializeDriverModule(DeviceNode, ModuleObject,
|
||||
Status = IopInitializeDriverModule(DeviceNode, LdrEntry,
|
||||
&DeviceNode->ServiceName, FALSE, &DriverObject);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
|
|
@ -1063,8 +1063,10 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
PIMAGE_DATA_DIRECTORY DataDirectory;
|
||||
PVOID DllBase, NewImageAddress;
|
||||
NTSTATUS Status;
|
||||
#if 1 // Disable for FreeLDR 2.5
|
||||
ULONG DriverSize = 0, Size;
|
||||
PIMAGE_SECTION_HEADER Section;
|
||||
#endif
|
||||
|
||||
/* Loop driver list */
|
||||
for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
|
||||
|
@ -1157,7 +1159,7 @@ MiReloadBootLoadedDrivers(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|||
|
||||
#if 0 // Enable for FreeLDR 2.5
|
||||
/* Now copy the entire driver over */
|
||||
RtlCopyMemory(NewImageAddress, DllBase, DriverSize);
|
||||
RtlCopyMemory(NewImageAddress, DllBase, LdrEntry->SizeOfImage);
|
||||
#else
|
||||
/* Copy headers over */
|
||||
RtlCopyMemory(NewImageAddress,
|
||||
|
|
Loading…
Reference in a new issue