📄 loader.c
字号:
}
}
else if (res > 0)
{
maxn = mid - 1;
}
else
{
minn = mid + 1;
}
}
ExName = RVA(BaseAddress, ExNames[mid]);
DbgPrint("2: failed to find %s\n",SymbolName);
return (PVOID)NULL;
}
NTSTATUS
NTAPI
LdrPEProcessImportDirectoryEntry(PVOID DriverBase,
PLOADER_MODULE LoaderModule,
PIMAGE_IMPORT_DESCRIPTOR ImportModuleDirectory)
{
PVOID* ImportAddressList;
PULONG FunctionNameList;
if (ImportModuleDirectory == NULL || ImportModuleDirectory->Name == 0)
{
return STATUS_UNSUCCESSFUL;
}
/* Get the import address list. */
ImportAddressList = (PVOID*)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
/* Get the list of functions to import. */
if (ImportModuleDirectory->OriginalFirstThunk != 0)
{
FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->OriginalFirstThunk);
}
else
{
FunctionNameList = (PULONG)RVA(DriverBase, ImportModuleDirectory->FirstThunk);
}
/* Walk through function list and fixup addresses. */
while (*FunctionNameList != 0L)
{
if ((*FunctionNameList) & 0x80000000)
{
DbgPrint("Failed to import ordinal from %s\n", LoaderModule->String);
return STATUS_UNSUCCESSFUL;
}
else
{
IMAGE_IMPORT_BY_NAME *pe_name;
pe_name = RVA(DriverBase, *FunctionNameList);
*ImportAddressList = LdrPEGetExportByName((PVOID)LoaderModule->ModStart, pe_name->Name, pe_name->Hint);
/* Fixup the address to be virtual */
*ImportAddressList = (PVOID)((ULONG_PTR)*ImportAddressList + (KSEG0_BASE - 0x200000));
//DbgPrint("Looked for: %s and found: %p\n", pe_name->Name, *ImportAddressList);
if ((*ImportAddressList) == NULL)
{
DbgPrint("Failed to import %s from %s\n", pe_name->Name, LoaderModule->String);
return STATUS_UNSUCCESSFUL;
}
}
ImportAddressList++;
FunctionNameList++;
}
return STATUS_SUCCESS;
}
extern BOOLEAN FrLdrLoadDriver(PCHAR szFileName, INT nPos);
NTSTATUS
NTAPI
LdrPEGetOrLoadModule(IN PCHAR ModuleName,
IN PCHAR ImportedName,
IN PLOADER_MODULE* ImportedModule)
{
NTSTATUS Status = STATUS_SUCCESS;
*ImportedModule = LdrGetModuleObject(ImportedName);
if (*ImportedModule == NULL)
{
if (!FrLdrLoadDriver(ImportedName, 0))
{
return STATUS_UNSUCCESSFUL;
}
else
{
return LdrPEGetOrLoadModule
(ModuleName, ImportedName, ImportedModule);
}
}
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 && 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;
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;
}
ULONG
NTAPI
FrLdrReMapImage(IN PVOID Base,
IN PVOID LoadBase)
{
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_SECTION_HEADER Section;
ULONG i, Size, DriverSize = 0;
/* Get the first section */
NtHeader = RtlImageNtHeader(Base);
Section = IMAGE_FIRST_SECTION(NtHeader);
/* Allocate memory for the driver */
DriverSize = NtHeader->OptionalHeader.SizeOfImage;
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 */
Size = Section[i].VirtualAddress + Section[i].Misc.VirtualSize;
if (Size <= DriverSize)
{
if (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);
}
else
{
/* Clear the BSS area */
RtlZeroMemory((PVOID)((ULONG_PTR)LoadBase +
Section[i].VirtualAddress),
Section[i].Misc.VirtualSize);
}
}
}
/* Return the size of the mapped driver */
return DriverSize;
}
PVOID
NTAPI
FrLdrMapImage(IN FILE *Image,
IN PCHAR Name,
IN ULONG ImageType)
{
PVOID ImageBase, LoadBase, ReadBuffer;
ULONG ImageId = LoaderBlock.ModsCount;
ULONG ImageSize;
NTSTATUS Status = STATUS_SUCCESS;
/* Try to see, maybe it's loaded already */
if (LdrGetModuleObject(Name) != NULL)
{
/* It's loaded, return NULL. It would be wise to return
correct LoadBase, but it seems to be ignored almost everywhere */
return NULL;
}
/* Set the virtual (image) and physical (load) addresses */
LoadBase = (PVOID)NextModuleBase;
ImageBase = RVA(LoadBase , -KERNEL_BASE_PHYS + KSEG0_BASE);
/* Save the Image Size */
ImageSize = FsGetFileSize(Image);
/* Set the file pointer to zero */
FsSetFilePointer(Image, 0);
/* Allocate a temporary buffer for the read */
ReadBuffer = MmAllocateMemory(ImageSize);
/* Load the file image */
FsReadFile(Image, ImageSize, NULL, ReadBuffer);
/* Map it into virtual memory */
ImageSize = FrLdrReMapImage(ReadBuffer, LoadBase);
/* Free the temporary buffer */
MmFreeMemory(ReadBuffer);
/* Calculate Difference between Real Base and Compiled Base*/
Status = LdrRelocateImageWithBias(LoadBase,
(ULONG_PTR)ImageBase -
(ULONG_PTR)LoadBase,
"FreeLdr",
STATUS_SUCCESS,
STATUS_UNSUCCESSFUL,
STATUS_UNSUCCESSFUL);
if (!NT_SUCCESS(Status))
{
/* Fail */
DbgPrint("Failed to relocate image: %s\n", Name);
return NULL;
}
/* 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 */
if (!NT_SUCCESS(LdrPEFixupImports(LoadBase, Name)))
{
/* Fixup failed, just don't include it in the list */
// NextModuleBase = OldNextModuleBase;
LoaderBlock.ModsCount = ImageId;
return NULL;
}
/* Return the final mapped address */
return LoadBase;
}
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 + -