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

📄 loader.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
            }
        }
        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 + -