⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
{
    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 + -