📄 mboot.c
字号:
PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable;
for (i=0; i<1536; i++) {
PageDir->Pde[i].Valid = 1;
PageDir->Pde[i].Write = 1;
PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE);
}
/* Set up APIC PTEs */
PageDir = (PPAGE_DIRECTORY_X86)&apic_pagetable;
PageDir->Pde[0].Valid = 1;
PageDir->Pde[0].Write = 1;
PageDir->Pde[0].CacheDisable = 1;
PageDir->Pde[0].WriteThrough = 1;
PageDir->Pde[0].PageFrameNumber = PaToPfn(APIC_BASE);
PageDir->Pde[0x200].Valid = 1;
PageDir->Pde[0x200].Write = 1;
PageDir->Pde[0x200].CacheDisable = 1;
PageDir->Pde[0x200].WriteThrough = 1;
PageDir->Pde[0x200].PageFrameNumber = PaToPfn(APIC_BASE + KERNEL_BASE_PHYS);
/* Set up KPCR PTEs */
PageDir = (PPAGE_DIRECTORY_X86)&kpcr_pagetable;
PageDir->Pde[0].Valid = 1;
PageDir->Pde[0].Write = 1;
PageDir->Pde[0].PageFrameNumber = 1;
}
return;
#endif
}
/*++
* 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)
{
#if 0
PIMAGE_DOS_HEADER ImageHeader;
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_SECTION_HEADER Section;
ULONG SectionCount;
ULONG ImageSize;
ULONG_PTR SourceSection;
ULONG_PTR TargetSection;
ULONG SectionSize;
LONG i;
PIMAGE_DATA_DIRECTORY RelocationDDir;
PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
ULONG Count;
ULONG_PTR Address, MaxAddress;
PUSHORT TypeOffset;
ULONG_PTR Delta;
PUSHORT ShortPtr;
PULONG LongPtr;
/* Allocate 1024 bytes for PE Header */
ImageHeader = (PIMAGE_DOS_HEADER)MmAllocateMemory(1024);
/* Make sure it was succesful */
if (ImageHeader == NULL) {
return FALSE;
}
/* Load the first 1024 bytes of the kernel image so we can read the PE header */
if (!FsReadFile(KernelImage, 1024, NULL, ImageHeader)) {
/* Fail if we couldn't read */
MmFreeMemory(ImageHeader);
return FALSE;
}
/* Now read the MZ header to get the offset to the PE Header */
NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)ImageHeader + ImageHeader->e_lfanew);
/* Get Kernel Base */
KernelBase = NtHeader->OptionalHeader.ImageBase;
FrLdrGetKernelBase();
/* Save Entrypoint */
KernelEntry = RaToPa(NtHeader->OptionalHeader.AddressOfEntryPoint);
/* Save the Image Size */
ImageSize = NtHeader->OptionalHeader.SizeOfImage;
/* Free the Header */
MmFreeMemory(ImageHeader);
/* Set the file pointer to zero */
FsSetFilePointer(KernelImage, 0);
/* Load the file image */
FsReadFile(KernelImage, ImageSize, NULL, (PVOID)KERNEL_BASE_PHYS);
/* Reload the NT Header */
NtHeader = (PIMAGE_NT_HEADERS)((PCHAR)KERNEL_BASE_PHYS + ImageHeader->e_lfanew);
/* 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 = RaToPa(Section->PointerToRawData);
TargetSection = RaToPa(Section->VirtualAddress);
SectionSize = Section->SizeOfRawData;
/* If the section is already mapped correctly, go to the next */
if (SourceSection == TargetSection) continue;
/* Load it into memory */
memmove((PVOID)TargetSection, (PVOID)SourceSection, SectionSize);
/* Check for unitilizated data */
if (Section->SizeOfRawData < Section->Misc.VirtualSize) {
/* Zero it out */
memset((PVOID)RaToPa(Section->VirtualAddress + Section->SizeOfRawData),
0,
Section->Misc.VirtualSize - Section->SizeOfRawData);
}
}
/* Get the Relocation Data Directory */
RelocationDDir = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
/* Get the Relocation Section Start and End*/
RelocationDir = (PIMAGE_BASE_RELOCATION)(KERNEL_BASE_PHYS + RelocationDDir->VirtualAddress);
RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDDir->Size);
/* Calculate Difference between Real Base and Compiled Base*/
Delta = KernelBase - NtHeader->OptionalHeader.ImageBase;;
/* Determine how far we shoudl relocate */
MaxAddress = KERNEL_BASE_PHYS + ImageSize;
/* Relocate until we've processed all the blocks */
while (RelocationDir < RelocationEnd && RelocationDir->SizeOfBlock > 0) {
/* See how many Relocation Blocks we have */
Count = (RelocationDir->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
/* Calculate the Address of this Directory */
Address = KERNEL_BASE_PHYS + RelocationDir->VirtualAddress;
/* Calculate the Offset of the Type */
TypeOffset = (PUSHORT)(RelocationDir + 1);
for (i = 0; i < Count; i++) {
ShortPtr = (PUSHORT)(Address + (*TypeOffset & 0xFFF));
/* Don't relocate after the end of the loaded driver */
if ((ULONG_PTR)ShortPtr >= MaxAddress) break;
switch (*TypeOffset >> 12) {
case IMAGE_REL_BASED_ABSOLUTE:
break;
case IMAGE_REL_BASED_HIGH:
*ShortPtr += HIWORD(Delta);
break;
case IMAGE_REL_BASED_LOW:
*ShortPtr += LOWORD(Delta);
break;
case IMAGE_REL_BASED_HIGHLOW:
LongPtr = (PULONG)ShortPtr;
*LongPtr += Delta;
break;
}
TypeOffset++;
}
/* Move to the next Relocation Table */
RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + RelocationDir->SizeOfBlock);
}
/* Increase the next Load Base */
NextModuleBase = ROUND_UP(KERNEL_BASE_PHYS + ImageSize, PAGE_SIZE);
/* Return Success */
#endif
return TRUE;
}
ULONG_PTR
NTAPI
FrLdrLoadModule(FILE *ModuleImage,
LPCSTR ModuleName,
PULONG ModuleSize)
{
#if 0
ULONG LocalModuleSize;
PFRLDR_MODULE ModuleData;
LPSTR NameBuffer;
LPSTR TempName;
/* Get current module data structure and module name string array */
ModuleData = &multiboot_modules[LoaderBlock.ModsCount];
/* Get only the Module Name */
do {
TempName = strchr(ModuleName, '\\');
if(TempName) {
ModuleName = TempName + 1;
}
} while(TempName);
NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount];
/* Get Module Size */
LocalModuleSize = FsGetFileSize(ModuleImage);
/* Fill out Module Data Structure */
ModuleData->ModuleStart = NextModuleBase;
ModuleData->ModuleEnd = NextModuleBase + LocalModuleSize;
/* Save name */
strcpy(NameBuffer, ModuleName);
ModuleData->ModuleName = NameBuffer;
/* Load the file image */
FsReadFile(ModuleImage, LocalModuleSize, NULL, (PVOID)NextModuleBase);
/* Move to next memory block and increase Module Count */
NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE);
LoaderBlock.ModsCount++;
/* Return Module Size if required */
if (ModuleSize != NULL) {
*ModuleSize = LocalModuleSize;
}
return(ModuleData->ModuleStart);
#else
return 0;
#endif
}
ULONG_PTR
NTAPI
FrLdrCreateModule(LPCSTR ModuleName)
{
#if 0
PFRLDR_MODULE ModuleData;
LPSTR NameBuffer;
/* Get current module data structure and module name string array */
ModuleData = &multiboot_modules[LoaderBlock.ModsCount];
NameBuffer = multiboot_module_strings[LoaderBlock.ModsCount];
/* Set up the structure */
ModuleData->ModuleStart = NextModuleBase;
ModuleData->ModuleEnd = -1;
/* Copy the name */
strcpy(NameBuffer, ModuleName);
ModuleData->ModuleName = NameBuffer;
/* Set the current Module */
CurrentModule = ModuleData;
/* Return Module Base Address */
return(ModuleData->ModuleStart);
#else
return 0;
#endif
}
BOOLEAN
NTAPI
FrLdrCloseModule(ULONG_PTR ModuleBase,
ULONG ModuleSize)
{
#if 0
PFRLDR_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->ModuleStart) && (ModuleData->ModuleEnd == -1)) {
/* Close the Module */
ModuleData->ModuleEnd = ModuleData->ModuleStart + ModuleSize;
/* Set the next Module Base and increase the number of modules */
NextModuleBase = ROUND_UP(ModuleData->ModuleEnd, PAGE_SIZE);
LoaderBlock.ModsCount++;
/* Close the currently opened module */
CurrentModule = NULL;
/* Success */
return(TRUE);
}
}
/* Failure path */
#endif
return(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -