📄 loader.c
字号:
{
NTSTATUS Status = STATUS_SUCCESS;
*ImportedModule = LdrGetModuleObject(ImportedName);
if (*ImportedModule == NULL)
{
/*
* For now, we only support import-loading the HAL.
* Later, FrLdrLoadDriver should be made to share the same
* code, and we'll just call it instead.
*/
if (!_stricmp(ImportedName, "hal.dll") ||
!_stricmp(ImportedName, "kdcom.dll"))
{
/* Load the HAL */
FrLdrLoadImage(ImportedName, 10);
/* Return the new module */
*ImportedModule = LdrGetModuleObject(ImportedName);
if (*ImportedModule == NULL)
{
DbgPrint("Error loading import: %s\n", ImportedName);
return STATUS_UNSUCCESSFUL;
}
}
else
{
DbgPrint("Don't yet support loading new modules from imports\n");
Status = STATUS_NOT_IMPLEMENTED;
}
}
return Status;
}
NTSTATUS
NTAPI
LdrPEFixupImports(IN PVOID DllBase,
IN PCHAR DllName)
{
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory;
PCHAR ImportedName;
NTSTATUS Status;
PLOADER_MODULE ImportedModule;
ULONG Size;
/* Process each import module */
ImportModuleDirectory = (PIMAGE_IMPORT_DESCRIPTOR)
RtlImageDirectoryEntryToData(DllBase,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&Size);
while (ImportModuleDirectory->Name)
{
/* Check to make sure that import lib is kernel */
ImportedName = (PCHAR) DllBase + ImportModuleDirectory->Name;
//DbgPrint("Processing imports for file: %s into file: %s\n", DllName, ImportedName);
Status = LdrPEGetOrLoadModule(DllName, ImportedName, &ImportedModule);
if (!NT_SUCCESS(Status)) return Status;
//DbgPrint("Import Base: %p\n", ImportedModule->ModStart);
Status = LdrPEProcessImportDirectoryEntry(DllBase, ImportedModule, ImportModuleDirectory);
if (!NT_SUCCESS(Status)) return Status;
//DbgPrint("Imports for file: %s into file: %s complete\n", DllName, ImportedName);
ImportModuleDirectory++;
}
return STATUS_SUCCESS;
}
VOID
NTAPI
FrLdrReMapImage(IN PIMAGE_NT_HEADERS NtHeader,
IN PVOID Base)
{
PIMAGE_SECTION_HEADER Section;
ULONG SectionCount, SectionSize;
PVOID SourceSection, TargetSection;
INT i;
/* Load the first section */
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--)
{
/* 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)
{
/* Zero it out */
RtlZeroMemory(RVA(Base, Section->VirtualAddress +
Section->SizeOfRawData),
Section->Misc.VirtualSize - Section->SizeOfRawData);
}
}
}
/*++
* FrLdrMapKernel
* INTERNAL
*
* Maps the Kernel into memory, does PE Section Mapping, initalizes the
* uninitialized data sections, and relocates the image.
*
* Params:
* KernelImage - FILE Structure representing the ntoskrnl image file.
*
* Returns:
* TRUE if the Kernel was mapped.
*
* Remarks:
* None.
*
*--*/
BOOLEAN
NTAPI
FrLdrMapKernel(FILE *KernelImage)
{
PIMAGE_NT_HEADERS NtHeader;
ULONG ImageSize;
PVOID LoadBase;
/* Set the virtual (image) and physical (load) addresses */
LoadBase = (PVOID)KERNEL_BASE_PHYS;
/* Load the first 1024 bytes of the kernel image so we can read the PE header */
if (!FsReadFile(KernelImage, 1024, NULL, LoadBase)) return FALSE;
/* Now read the MZ header to get the offset to the PE Header */
NtHeader = RtlImageNtHeader(LoadBase);
/* Get Kernel Base */
KernelBase = NtHeader->OptionalHeader.ImageBase;
FrLdrGetKernelBase();
/* Save Entrypoint */
KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
/* Save the Image Size */
ImageSize = NtHeader->OptionalHeader.SizeOfImage;
/* Set the file pointer to zero */
FsSetFilePointer(KernelImage, 0);
/* Load the file image */
FsReadFile(KernelImage, ImageSize, NULL, LoadBase);
/* Map it */
FrLdrReMapImage(NtHeader, LoadBase);
/* Calculate Difference between Real Base and Compiled Base*/
LdrRelocateImageWithBias(LoadBase,
KernelBase - (ULONG_PTR)LoadBase,
"FreeLdr",
STATUS_SUCCESS,
STATUS_UNSUCCESSFUL,
STATUS_UNSUCCESSFUL);
/* Fill out Module Data Structure */
reactos_modules[0].ModStart = KernelBase;
reactos_modules[0].ModEnd = KernelBase + ImageSize;
strcpy(reactos_module_strings[0], "ntoskrnl.exe");
reactos_modules[0].String = (ULONG_PTR)reactos_module_strings[0];
LoaderBlock.ModsCount++;
/* Increase the next Load Base */
NextModuleBase = ROUND_UP(LoadBase + ImageSize, PAGE_SIZE);
/* Load the HAL now (name will be changed internally if needed) */
FrLdrLoadImage("hal.dll", 10);
/* Perform import fixups */
LdrPEFixupImports(LoadBase, "ntoskrnl.exe");
/* Return Success */
return TRUE;
}
BOOLEAN
NTAPI
FrLdrMapImage(IN FILE *HalImage,
IN PCHAR Name)
{
PIMAGE_NT_HEADERS NtHeader;
PVOID ImageBase, LoadBase;
ULONG ImageSize;
ULONG ImageId = LoaderBlock.ModsCount;
/* 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(HalImage, 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;
/* Set the file pointer to zero */
FsSetFilePointer(HalImage, 0);
/* Load the file image */
FsReadFile(HalImage, ImageSize, NULL, LoadBase);
/* Map it into virtual memory */
FrLdrReMapImage(NtHeader, LoadBase);
/* Calculate Difference between Real Base and Compiled Base*/
LdrRelocateImageWithBias(LoadBase,
(ULONG_PTR)ImageBase - (ULONG_PTR)LoadBase,
"FreeLdr",
STATUS_SUCCESS,
STATUS_UNSUCCESSFUL,
STATUS_UNSUCCESSFUL);
/* Fill out Module Data Structure */
reactos_modules[ImageId].ModStart = (ULONG_PTR)ImageBase;
reactos_modules[ImageId].ModEnd = (ULONG_PTR)ImageBase + ImageSize;
strcpy(reactos_module_strings[ImageId], Name);
reactos_modules[ImageId].String = (ULONG_PTR)reactos_module_strings[ImageId];
LoaderBlock.ModsCount++;
/* Increase the next Load Base */
NextModuleBase = ROUND_UP(NextModuleBase + ImageSize, PAGE_SIZE);
/* Perform import fixups */
//DbgPrint("Fixing up: %s loaded at: %p\n", Name, ImageBase);
LdrPEFixupImports(LoadBase, Name);
/* Return Success */
return TRUE;
}
ULONG_PTR
NTAPI
FrLdrLoadModule(FILE *ModuleImage,
LPCSTR ModuleName,
PULONG ModuleSize)
{
ULONG LocalModuleSize;
PLOADER_MODULE ModuleData;
LPSTR NameBuffer;
LPSTR TempName;
/* Get current module data structure and module name string array */
ModuleData = &reactos_modules[LoaderBlock.ModsCount];
/* Get only the Module Name */
do {
TempName = strchr(ModuleName, '\\');
if(TempName) {
ModuleName = TempName + 1;
}
} while(TempName);
NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
/* Get Module Size */
LocalModuleSize = FsGetFileSize(ModuleImage);
/* Fill out Module Data Structure */
ModuleData->ModStart = NextModuleBase;
ModuleData->ModEnd = NextModuleBase + LocalModuleSize;
/* Save name */
strcpy(NameBuffer, ModuleName);
ModuleData->String = (ULONG_PTR)NameBuffer;
/* Load the file image */
FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
/* Move to next memory block and increase Module Count */
NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
LoaderBlock.ModsCount++;
// DbgPrint("NextBase, ImageSize, ModStart, ModEnd %p %p %p %p\n",
// NextModuleBase, LocalModuleSize, ModuleData->ModStart, ModuleData->ModEnd);
/* Return Module Size if required */
if (ModuleSize != NULL) {
*ModuleSize = LocalModuleSize;
}
return(ModuleData->ModStart);
}
ULONG_PTR
NTAPI
FrLdrCreateModule(LPCSTR ModuleName)
{
PLOADER_MODULE ModuleData;
LPSTR NameBuffer;
/* Get current module data structure and module name string array */
ModuleData = &reactos_modules[LoaderBlock.ModsCount];
NameBuffer = reactos_module_strings[LoaderBlock.ModsCount];
/* Set up the structure */
ModuleData->ModStart = NextModuleBase;
ModuleData->ModEnd = -1;
/* Copy the name */
strcpy(NameBuffer, ModuleName);
ModuleData->String = (ULONG_PTR)NameBuffer;
/* Set the current Module */
CurrentModule = ModuleData;
/* Return Module Base Address */
return(ModuleData->ModStart);
}
BOOLEAN
NTAPI
FrLdrCloseModule(ULONG_PTR ModuleBase,
ULONG ModuleSize)
{
PLOADER_MODULE ModuleData = CurrentModule;
/* Make sure a module is opened */
if (ModuleData) {
/* Make sure this is the right module and that it hasn't been closed */
if ((ModuleBase == ModuleData->ModStart) && (ModuleData->ModEnd == (ULONG_PTR)-1)) {
/* Close the Module */
ModuleData->ModEnd = ModuleData->ModStart + ModuleSize;
/* Set the next Module Base and increase the number of modules */
NextModuleBase = ROUND_UP(ModuleData->ModEnd, PAGE_SIZE);
LoaderBlock.ModsCount++;
/* Close the currently opened module */
CurrentModule = NULL;
/* Success */
return(TRUE);
}
}
/* Failure path */
return(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -