ReactOS 0.4.15-dev-6056-gb29b268
sysldr.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for sysldr.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 
#define DEFAULT_SECURITY_COOKIE   0xBB40E64E
 

Functions

PVOID NTAPI MiCacheImageSymbols (IN PVOID BaseAddress)
 
NTSTATUS NTAPI MiLoadImageSection (_Inout_ PSECTION *SectionPtr, _Out_ PVOID *ImageBase, _In_ PUNICODE_STRING FileName, _In_ BOOLEAN SessionLoad, _In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
 
PVOID NTAPI MiLocateExportName (IN PVOID DllBase, IN PCHAR ExportName)
 
NTSTATUS NTAPI MmCallDllInitialize (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
 
BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI MiDereferenceImports (IN PLOAD_IMPORTS ImportList)
 
VOID NTAPI MiClearImports (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
PVOID NTAPI MiFindExportedRoutineByName (IN PVOID DllBase, IN PANSI_STRING ExportName)
 
VOID NTAPI MiProcessLoaderEntry (IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Insert)
 
VOID NTAPI MiUpdateThunks (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
 
NTSTATUS NTAPI MiSnapThunk (IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA Name, IN PIMAGE_THUNK_DATA Address, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN SnapForwarder, OUT PCHAR *MissingApi)
 
NTSTATUS NTAPI MmUnloadSystemImage (IN PVOID ImageHandle)
 
NTSTATUS NTAPI MiResolveImageReferences (IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
 
VOID NTAPI MiFreeInitializationCode (IN PVOID InitStart, IN PVOID InitEnd)
 
VOID NTAPI MiFindInitializationCode (OUT PVOID *StartVa, OUT PVOID *EndVa)
 
VOID NTAPI MmFreeDriverInitialization (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
VOID NTAPI MiReloadBootLoadedDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
NTSTATUS NTAPI MiBuildImportsForBootDrivers (VOID)
 
VOID NTAPI MiLocateKernelSections (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
BOOLEAN NTAPI MiInitializeLoadedModuleList (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection (IN ULONG_PTR ProtectionMask)
 
VOID NTAPI MmMakeKernelResourceSectionWritable (VOID)
 
LOGICAL NTAPI MiUseLargeDriverPage (IN ULONG NumberOfPtes, IN OUT PVOID *ImageBaseAddress, IN PUNICODE_STRING BaseImageName, IN BOOLEAN BootDriver)
 
VOID NTAPI MiSetSystemCodeProtection (_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
 
VOID NTAPI MiWriteProtectSystemImage (_In_ PVOID ImageBase)
 
VOID NTAPI MiSetPagingOfDriver (IN PMMPTE PointerPte, IN PMMPTE LastPte)
 
VOID NTAPI MiEnablePagingOfDriver (IN PLDR_DATA_TABLE_ENTRY LdrEntry)
 
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse (IN PVOID BaseAddress)
 
NTSTATUS NTAPI MmCheckSystemImage (IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
 
PVOID NTAPI LdrpFetchAddressOfSecurityCookie (PVOID BaseAddress, ULONG SizeOfImage)
 
PVOID NTAPI LdrpInitSecurityCookie (PLDR_DATA_TABLE_ENTRY LdrEntry)
 
NTSTATUS NTAPI MmLoadSystemImage (IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
 
PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry (IN PVOID Address)
 
PVOID NTAPI MmPageEntireDriver (IN PVOID AddressWithinSection)
 
VOID NTAPI MmResetDriverPaging (IN PVOID AddressWithinSection)
 
PVOID NTAPI MmGetSystemRoutineAddress (IN PUNICODE_STRING SystemRoutineName)
 

Variables

LIST_ENTRY PsLoadedModuleList
 
LIST_ENTRY MmLoadedUserImageList
 
KSPIN_LOCK PsLoadedModuleSpinLock
 
ERESOURCE PsLoadedModuleResource
 
ULONG_PTR PsNtosImageBase
 
KMUTANT MmSystemLoadLock
 
PFN_NUMBER MmTotalSystemDriverPages
 
PVOID MmUnloadedDrivers
 
PVOID MmLastUnloadedDrivers
 
BOOLEAN MmMakeLowMemory
 
BOOLEAN MmEnforceWriteProtection = TRUE
 
PMMPTE MiKernelResourceStartPte
 
PMMPTE MiKernelResourceEndPte
 
ULONG_PTR ExPoolCodeStart
 
ULONG_PTR ExPoolCodeEnd
 
ULONG_PTR MmPoolCodeStart
 
ULONG_PTR MmPoolCodeEnd
 
ULONG_PTR MmPteCodeStart
 
ULONG_PTR MmPteCodeEnd
 

Macro Definition Documentation

◆ DEFAULT_SECURITY_COOKIE

#define DEFAULT_SECURITY_COOKIE   0xBB40E64E

Definition at line 43 of file sysldr.c.

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 16 of file sysldr.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file sysldr.c.

Function Documentation

◆ LdrpFetchAddressOfSecurityCookie()

PVOID NTAPI LdrpFetchAddressOfSecurityCookie ( PVOID  BaseAddress,
ULONG  SizeOfImage 
)

Definition at line 2808 of file sysldr.c.

2809{
2811 ULONG DirSize;
2812 PVOID Cookie = NULL;
2813
2814 /* Check NT header first */
2815 if (!RtlImageNtHeader(BaseAddress)) return NULL;
2816
2817 /* Get the pointer to the config directory */
2819 TRUE,
2821 &DirSize);
2822
2823 /* Check for sanity */
2824 if (!ConfigDir ||
2825 DirSize < FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, SEHandlerTable) || /* SEHandlerTable is after SecurityCookie */
2826 (ConfigDir->Size != DirSize))
2827 {
2828 /* Invalid directory*/
2829 return NULL;
2830 }
2831
2832 /* Now get the cookie */
2833 Cookie = (PVOID)ConfigDir->SecurityCookie;
2834
2835 /* Check this cookie */
2837 (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
2838 {
2839 Cookie = NULL;
2840 }
2841
2842 /* Return validated security cookie */
2843 return Cookie;
2844}
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
#define RtlImageNtHeader
Definition: compat.h:806
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:14

Referenced by LdrpInitSecurityCookie().

◆ LdrpInitSecurityCookie()

PVOID NTAPI LdrpInitSecurityCookie ( PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2848 of file sysldr.c.

2849{
2851 ULONG_PTR NewCookie;
2852
2853 /* Fetch address of the cookie */
2855
2856 if (Cookie)
2857 {
2858 /* Check if it's a default one */
2859 if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
2860 (*Cookie == 0))
2861 {
2863 /* The address should be unique */
2864 NewCookie = (ULONG_PTR)Cookie;
2865
2866 /* We just need a simple tick, don't care about precision and whatnot */
2867 NewCookie ^= (ULONG_PTR)Counter.LowPart;
2868
2869 /* If the result is 0 or the same as we got, just add one to the default value */
2870 if ((NewCookie == 0) || (NewCookie == *Cookie))
2871 {
2872 NewCookie = DEFAULT_SECURITY_COOKIE + 1;
2873 }
2874
2875 /* Set the new cookie value */
2876 *Cookie = NewCookie;
2877 }
2878 }
2879
2880 return Cookie;
2881}
#define ULONG_PTR
Definition: config.h:101
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
ULONG SizeOfImage
Definition: ldrtypes.h:143
PVOID DllBase
Definition: btrfs_drv.h:1880
static LARGE_INTEGER Counter
Definition: clock.c:43
#define DEFAULT_SECURITY_COOKIE
Definition: sysldr.c:43
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: sysldr.c:2808
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG LowPart
Definition: typedefs.h:106

Referenced by MmLoadSystemImage().

◆ MiBuildImportsForBootDrivers()

NTSTATUS NTAPI MiBuildImportsForBootDrivers ( VOID  )

Definition at line 1869 of file sysldr.c.

1870{
1871 PLIST_ENTRY NextEntry, NextEntry2;
1872 PLDR_DATA_TABLE_ENTRY LdrEntry, KernelEntry, HalEntry, LdrEntry2, LastEntry;
1873 PLDR_DATA_TABLE_ENTRY* EntryArray;
1874 UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
1876 PLOAD_IMPORTS LoadedImports;
1877 ULONG LoadedImportsSize, ImportSize;
1878 PULONG_PTR ImageThunk;
1879 ULONG_PTR DllBase, DllEnd;
1880 ULONG Modules = 0, i, j = 0;
1881 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
1882
1883 /* Initialize variables */
1884 KernelEntry = HalEntry = LastEntry = NULL;
1885
1886 /* Loop the loaded module list... we are early enough that no lock is needed */
1887 NextEntry = PsLoadedModuleList.Flink;
1888 while (NextEntry != &PsLoadedModuleList)
1889 {
1890 /* Get the entry */
1891 LdrEntry = CONTAINING_RECORD(NextEntry,
1893 InLoadOrderLinks);
1894
1895 /* Check if it's the kernel or HAL */
1896 if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
1897 {
1898 /* Found it */
1899 KernelEntry = LdrEntry;
1900 }
1901 else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
1902 {
1903 /* Found it */
1904 HalEntry = LdrEntry;
1905 }
1906
1907 /* Check if this is a driver DLL */
1908 if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1909 {
1910 /* Check if this is the HAL or kernel */
1911 if ((LdrEntry == HalEntry) || (LdrEntry == KernelEntry))
1912 {
1913 /* Add a reference */
1914 LdrEntry->LoadCount = 1;
1915 }
1916 else
1917 {
1918 /* No referencing needed */
1919 LdrEntry->LoadCount = 0;
1920 }
1921 }
1922 else
1923 {
1924 /* Add a reference for all other modules as well */
1925 LdrEntry->LoadCount = 1;
1926 }
1927
1928 /* Remember this came from the loader */
1930
1931 /* Keep looping */
1932 NextEntry = NextEntry->Flink;
1933 Modules++;
1934 }
1935
1936 /* We must have at least found the kernel and HAL */
1937 if (!(HalEntry) || (!KernelEntry)) return STATUS_NOT_FOUND;
1938
1939 /* Allocate the list */
1940 EntryArray = ExAllocatePoolWithTag(PagedPool, Modules * sizeof(PVOID), TAG_LDR_IMPORTS);
1941 if (!EntryArray) return STATUS_INSUFFICIENT_RESOURCES;
1942
1943 /* Loop the loaded module list again */
1944 NextEntry = PsLoadedModuleList.Flink;
1945 while (NextEntry != &PsLoadedModuleList)
1946 {
1947 /* Get the entry */
1948 LdrEntry = CONTAINING_RECORD(NextEntry,
1950 InLoadOrderLinks);
1951#ifdef _WORKING_LOADER_
1952 /* Get its imports */
1953 ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1954 TRUE,
1956 &ImportSize);
1957 if (!ImageThunk)
1958#else
1959 /* Get its imports */
1960 ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
1961 TRUE,
1963 &ImportSize);
1964 if (!ImportDescriptor)
1965#endif
1966 {
1967 /* None present */
1969 NextEntry = NextEntry->Flink;
1970 continue;
1971 }
1972
1973 /* Clear the list and count the number of IAT thunks */
1974 RtlZeroMemory(EntryArray, Modules * sizeof(PVOID));
1975#ifdef _WORKING_LOADER_
1976 ImportSize /= sizeof(ULONG_PTR);
1977
1978 /* Scan the thunks */
1979 for (i = 0, DllBase = 0, DllEnd = 0; i < ImportSize; i++, ImageThunk++)
1980#else
1981 DllBase = DllEnd = i = 0;
1982 while ((ImportDescriptor->Name) &&
1983 (ImportDescriptor->OriginalFirstThunk))
1984 {
1985 /* Get the image thunk */
1986 ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
1987 ImportDescriptor->FirstThunk);
1988 while (*ImageThunk)
1989#endif
1990 {
1991 /* Do we already have an address? */
1992 if (DllBase)
1993 {
1994 /* Is the thunk in the same address? */
1995 if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
1996 {
1997 /* Skip it, we already have a reference for it */
1998 ASSERT(EntryArray[j]);
1999 ImageThunk++;
2000 continue;
2001 }
2002 }
2003
2004 /* Loop the loaded module list to locate this address owner */
2005 j = 0;
2006 NextEntry2 = PsLoadedModuleList.Flink;
2007 while (NextEntry2 != &PsLoadedModuleList)
2008 {
2009 /* Get the entry */
2010 LdrEntry2 = CONTAINING_RECORD(NextEntry2,
2012 InLoadOrderLinks);
2013
2014 /* Get the address range for this module */
2015 DllBase = (ULONG_PTR)LdrEntry2->DllBase;
2016 DllEnd = DllBase + LdrEntry2->SizeOfImage;
2017
2018 /* Check if this IAT entry matches it */
2019 if ((*ImageThunk >= DllBase) && (*ImageThunk < DllEnd))
2020 {
2021 /* Save it */
2022 //DPRINT1("Found imported dll: %wZ\n", &LdrEntry2->BaseDllName);
2023 EntryArray[j] = LdrEntry2;
2024 break;
2025 }
2026
2027 /* Keep searching */
2028 NextEntry2 = NextEntry2->Flink;
2029 j++;
2030 }
2031
2032 /* Do we have a thunk outside the range? */
2033 if ((*ImageThunk < DllBase) || (*ImageThunk >= DllEnd))
2034 {
2035 /* Could be 0... */
2036 if (*ImageThunk)
2037 {
2038 /* Should not be happening */
2039 ERROR_FATAL("Broken IAT entry for %p at %p (%lx)\n",
2040 LdrEntry, ImageThunk, *ImageThunk);
2041 }
2042
2043 /* Reset if we hit this */
2044 DllBase = 0;
2045 }
2046#ifndef _WORKING_LOADER_
2047 ImageThunk++;
2048 }
2049
2050 i++;
2051 ImportDescriptor++;
2052#endif
2053 }
2054
2055 /* Now scan how many imports we really have */
2056 for (i = 0, ImportSize = 0; i < Modules; i++)
2057 {
2058 /* Skip HAL and kernel */
2059 if ((EntryArray[i]) &&
2060 (EntryArray[i] != HalEntry) &&
2061 (EntryArray[i] != KernelEntry))
2062 {
2063 /* A valid reference */
2064 LastEntry = EntryArray[i];
2065 ImportSize++;
2066 }
2067 }
2068
2069 /* Do we have any imports after all? */
2070 if (!ImportSize)
2071 {
2072 /* No */
2074 }
2075 else if (ImportSize == 1)
2076 {
2077 /* A single entry import */
2078 LdrEntry->LoadedImports = (PVOID)((ULONG_PTR)LastEntry | MM_SYSLDR_SINGLE_ENTRY);
2079 LastEntry->LoadCount++;
2080 }
2081 else
2082 {
2083 /* We need an import table */
2084 LoadedImportsSize = ImportSize * sizeof(PVOID) + sizeof(SIZE_T);
2085 LoadedImports = ExAllocatePoolWithTag(PagedPool,
2086 LoadedImportsSize,
2088 ASSERT(LoadedImports);
2089
2090 /* Save the count */
2091 LoadedImports->Count = ImportSize;
2092
2093 /* Now copy all imports */
2094 for (i = 0, j = 0; i < Modules; i++)
2095 {
2096 /* Skip HAL and kernel */
2097 if ((EntryArray[i]) &&
2098 (EntryArray[i] != HalEntry) &&
2099 (EntryArray[i] != KernelEntry))
2100 {
2101 /* A valid reference */
2102 //DPRINT1("Found valid entry: %p\n", EntryArray[i]);
2103 LoadedImports->Entry[j] = EntryArray[i];
2104 EntryArray[i]->LoadCount++;
2105 j++;
2106 }
2107 }
2108
2109 /* Should had as many entries as we expected */
2110 ASSERT(j == ImportSize);
2111 LdrEntry->LoadedImports = LoadedImports;
2112 }
2113
2114 /* Next */
2115 NextEntry = NextEntry->Flink;
2116 }
2117
2118 /* Free the initial array */
2120
2121 /* FIXME: Might not need to keep the HAL/Kernel imports around */
2122
2123 /* Kernel and HAL are loaded at boot */
2124 KernelEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
2126
2127 /* All worked well */
2128 return STATUS_SUCCESS;
2129}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
PWCHAR HalName
Definition: halacpi.c:45
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:56
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:200
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:201
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:202
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define L(x)
Definition: ntvdm.h:50
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
#define IMAGE_DIRECTORY_ENTRY_IAT
Definition: pedump.c:271
#define ERROR_FATAL(...)
Definition: debug.h:238
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
Definition: btrfs_drv.h:1876
USHORT LoadCount
Definition: ntddk_ex.h:208
PVOID LoadedImports
Definition: ldrtypes.h:161
ULONG Flags
Definition: ntddk_ex.h:207
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
SIZE_T Count
Definition: ldrtypes.h:172
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:173
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
#define TAG_LDR_IMPORTS
Definition: tag.h:103
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by MiInitializeLoadedModuleList().

◆ MiCacheImageSymbols()

PVOID NTAPI MiCacheImageSymbols ( IN PVOID  BaseAddress)

Definition at line 50 of file sysldr.c.

51{
52 ULONG DebugSize;
53 PVOID DebugDirectory = NULL;
54 PAGED_CODE();
55
56 /* Make sure it's safe to access the image */
58 {
59 /* Get the debug directory */
61 TRUE,
63 &DebugSize);
64 }
66 {
67 /* Nothing */
68 }
70
71 /* Return the directory */
72 return DebugDirectory;
73}
#define PAGED_CODE()
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:152
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34

Referenced by MmLoadSystemImage().

◆ MiCallDllUnloadAndUnloadDll()

BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 357 of file sysldr.c.

358{
361 PAGED_CODE();
362
363 /* Get the unload routine */
364 Func = (PMM_DLL_UNLOAD)MiLocateExportName(LdrEntry->DllBase, "DllUnload");
365 if (!Func) return FALSE;
366
367 /* Call it and check for success */
368 Status = Func();
369 if (!NT_SUCCESS(Status)) return FALSE;
370
371 /* Lie about the load count so we can unload the image */
372 ASSERT(LdrEntry->LoadCount == 0);
373 LdrEntry->LoadCount = 1;
374
375 /* Unload it and return true */
376 MmUnloadSystemImage(LdrEntry);
377 return TRUE;
378}
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
void(* Func)(int)
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:898
PVOID NTAPI MiLocateExportName(IN PVOID DllBase, IN PCHAR ExportName)
Definition: sysldr.c:218
NTSTATUS(NTAPI * PMM_DLL_UNLOAD)(VOID)
Definition: iotypes.h:2854

Referenced by MiDereferenceImports().

◆ MiClearImports()

VOID NTAPI MiClearImports ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 457 of file sysldr.c.

458{
459 PAGED_CODE();
460
461 /* Check if there's no imports or we're a boot driver or only one entry */
462 if ((LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) ||
463 (LdrEntry->LoadedImports == MM_SYSLDR_NO_IMPORTS) ||
464 ((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
465 {
466 /* Nothing to do */
467 return;
468 }
469
470 /* Otherwise, free the import list */
471 ExFreePoolWithTag(LdrEntry->LoadedImports, TAG_LDR_IMPORTS);
472 LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
473}

Referenced by MmUnloadSystemImage().

◆ MiDereferenceImports()

NTSTATUS NTAPI MiDereferenceImports ( IN PLOAD_IMPORTS  ImportList)

Definition at line 382 of file sysldr.c.

383{
384 SIZE_T i;
385 LOAD_IMPORTS SingleEntry;
386 PLDR_DATA_TABLE_ENTRY LdrEntry;
387 PVOID CurrentImports;
388 PAGED_CODE();
389
390 /* Check if there's no imports or if we're a boot driver */
391 if ((ImportList == MM_SYSLDR_NO_IMPORTS) ||
392 (ImportList == MM_SYSLDR_BOOT_LOADED) ||
393 (ImportList->Count == 0))
394 {
395 /* Then there's nothing to do */
396 return STATUS_SUCCESS;
397 }
398
399 /* Check for single-entry */
400 if ((ULONG_PTR)ImportList & MM_SYSLDR_SINGLE_ENTRY)
401 {
402 /* Set it up */
403 SingleEntry.Count = 1;
404 SingleEntry.Entry[0] = (PVOID)((ULONG_PTR)ImportList &~ MM_SYSLDR_SINGLE_ENTRY);
405
406 /* Use this as the import list */
407 ImportList = &SingleEntry;
408 }
409
410 /* Loop the import list */
411 for (i = 0; (i < ImportList->Count) && (ImportList->Entry[i]); i++)
412 {
413 /* Get the entry */
414 LdrEntry = ImportList->Entry[i];
415 DPRINT1("%wZ <%wZ>\n", &LdrEntry->FullDllName, &LdrEntry->BaseDllName);
416
417 /* Skip boot loaded images */
418 if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) continue;
419
420 /* Dereference the entry */
421 ASSERT(LdrEntry->LoadCount >= 1);
422 if (!--LdrEntry->LoadCount)
423 {
424 /* Save the import data in case unload fails */
425 CurrentImports = LdrEntry->LoadedImports;
426
427 /* This is the last entry */
429 if (MiCallDllUnloadAndUnloadDll(LdrEntry))
430 {
431 /* Unloading worked, parse this DLL's imports too */
432 MiDereferenceImports(CurrentImports);
433
434 /* Check if we had valid imports */
435 if ((CurrentImports != MM_SYSLDR_BOOT_LOADED) &&
436 (CurrentImports != MM_SYSLDR_NO_IMPORTS) &&
437 !((ULONG_PTR)CurrentImports & MM_SYSLDR_SINGLE_ENTRY))
438 {
439 /* Free them */
440 ExFreePoolWithTag(CurrentImports, TAG_LDR_IMPORTS);
441 }
442 }
443 else
444 {
445 /* Unload failed, restore imports */
446 LdrEntry->LoadedImports = CurrentImports;
447 }
448 }
449 }
450
451 /* Done */
452 return STATUS_SUCCESS;
453}
#define DPRINT1
Definition: precomp.h:8
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:382
BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:357

Referenced by MiDereferenceImports(), MiResolveImageReferences(), and MmUnloadSystemImage().

◆ MiEnablePagingOfDriver()

VOID NTAPI MiEnablePagingOfDriver ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2606 of file sysldr.c.

2607{
2608 ULONG_PTR ImageBase;
2609 PIMAGE_NT_HEADERS NtHeaders;
2610 ULONG Sections, Alignment, Size;
2611 PIMAGE_SECTION_HEADER Section;
2612 PMMPTE PointerPte = NULL, LastPte = NULL;
2613 if (MmDisablePagingExecutive) return;
2614
2615 /* Get the driver base address and its NT header */
2616 ImageBase = (ULONG_PTR)LdrEntry->DllBase;
2617 NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
2618 if (!NtHeaders) return;
2619
2620 /* Get the sections and their alignment */
2621 Sections = NtHeaders->FileHeader.NumberOfSections;
2622 Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
2623
2624 /* Loop each section */
2625 Section = IMAGE_FIRST_SECTION(NtHeaders);
2626 while (Sections)
2627 {
2628 /* Find PAGE or .edata */
2629 if ((*(PULONG)Section->Name == 'EGAP') ||
2630 (*(PULONG)Section->Name == 'ade.'))
2631 {
2632 /* Had we already done some work? */
2633 if (!PointerPte)
2634 {
2635 /* Nope, setup the first PTE address */
2636 PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
2637 Section->VirtualAddress));
2638 }
2639
2640 /* Compute the size */
2641 Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2642
2643 /* Find the last PTE that maps this section */
2644 LastPte = MiAddressToPte(ImageBase +
2645 Section->VirtualAddress +
2647 }
2648 else
2649 {
2650 /* Had we found a section before? */
2651 if (PointerPte)
2652 {
2653 /* Mark it as pageable */
2654 MiSetPagingOfDriver(PointerPte, LastPte);
2655 PointerPte = NULL;
2656 }
2657 }
2658
2659 /* Keep searching */
2660 Sections--;
2661 Section++;
2662 }
2663
2664 /* Handle the straggler */
2665 if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
2666}
#define PAGE_SIZE
Definition: env_spec_w32.h:49
union Alignment_ Alignment
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
UCHAR MmDisablePagingExecutive
Definition: mminit.c:25
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
union _IMAGE_SECTION_HEADER::@1538 Misc
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define max(a, b)
Definition: svc.c:63
VOID NTAPI MiSetPagingOfDriver(IN PMMPTE PointerPte, IN PMMPTE LastPte)
Definition: sysldr.c:2547
uint32_t * PULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define ROUND_TO_PAGES(Size)

Referenced by MmLoadSystemImage().

◆ MiFindExportedRoutineByName()

PVOID NTAPI MiFindExportedRoutineByName ( IN PVOID  DllBase,
IN PANSI_STRING  ExportName 
)

Definition at line 477 of file sysldr.c.

479{
480 PULONG NameTable;
481 PUSHORT OrdinalTable;
482 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
483 LONG Low = 0, Mid = 0, High, Ret;
484 USHORT Ordinal;
486 ULONG ExportSize;
487 PULONG ExportTable;
488 PAGED_CODE();
489
490 /* Get the export directory */
491 ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
492 TRUE,
494 &ExportSize);
495 if (!ExportDirectory) return NULL;
496
497 /* Setup name tables */
498 NameTable = (PULONG)((ULONG_PTR)DllBase +
499 ExportDirectory->AddressOfNames);
500 OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
501 ExportDirectory->AddressOfNameOrdinals);
502
503 /* Do a binary search */
504 High = ExportDirectory->NumberOfNames - 1;
505 while (High >= Low)
506 {
507 /* Get new middle value */
508 Mid = (Low + High) >> 1;
509
510 /* Compare name */
511 Ret = strcmp(ExportName->Buffer, (PCHAR)DllBase + NameTable[Mid]);
512 if (Ret < 0)
513 {
514 /* Update high */
515 High = Mid - 1;
516 }
517 else if (Ret > 0)
518 {
519 /* Update low */
520 Low = Mid + 1;
521 }
522 else
523 {
524 /* We got it */
525 break;
526 }
527 }
528
529 /* Check if we couldn't find it */
530 if (High < Low) return NULL;
531
532 /* Otherwise, this is the ordinal */
533 Ordinal = OrdinalTable[Mid];
534
535 /* Validate the ordinal */
536 if (Ordinal >= ExportDirectory->NumberOfFunctions) return NULL;
537
538 /* Resolve the address and write it */
539 ExportTable = (PULONG)((ULONG_PTR)DllBase +
540 ExportDirectory->AddressOfFunctions);
541 Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
542
543 /* We found it! */
544 ASSERT((Function < (PVOID)ExportDirectory) ||
545 (Function > (PVOID)((ULONG_PTR)ExportDirectory + ExportSize)));
546
547 return Function;
548}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
DWORD AddressOfNameOrdinals
Definition: compat.h:167
uint16_t * PUSHORT
Definition: typedefs.h:56

Referenced by MmGetSystemRoutineAddress().

◆ MiFindInitializationCode()

VOID NTAPI MiFindInitializationCode ( OUT PVOID StartVa,
OUT PVOID EndVa 
)

Definition at line 1437 of file sysldr.c.

1439{
1440 ULONG Size, SectionCount, Alignment;
1441 PLDR_DATA_TABLE_ENTRY LdrEntry;
1442 ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1443 PLIST_ENTRY NextEntry;
1444 PIMAGE_NT_HEADERS NtHeader;
1445 PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1446 BOOLEAN InitFound;
1448
1449 /* So we don't free our own code yet */
1451
1452 /* Assume failure */
1453 *StartVa = NULL;
1454
1455 /* Acquire the necessary locks while we loop the list */
1459 KernelMode,
1460 FALSE,
1461 NULL);
1463
1464 /* Loop all loaded modules */
1465 NextEntry = PsLoadedModuleList.Flink;
1466 while (NextEntry != &PsLoadedModuleList)
1467 {
1468 /* Get the loader entry and its DLL base */
1469 LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1470 DllBase = (ULONG_PTR)LdrEntry->DllBase;
1471
1472 /* Only process boot loaded images. Other drivers are processed by
1473 MmFreeDriverInitialization */
1474 if (LdrEntry->Flags & LDRP_MM_LOADED)
1475 {
1476 /* Keep going */
1477 NextEntry = NextEntry->Flink;
1478 continue;
1479 }
1480
1481 /* Get the NT header */
1482 NtHeader = RtlImageNtHeader((PVOID)DllBase);
1483 if (!NtHeader)
1484 {
1485 /* Keep going */
1486 NextEntry = NextEntry->Flink;
1487 continue;
1488 }
1489
1490 /* Get the first section, the section count, and scan them all */
1491 Section = IMAGE_FIRST_SECTION(NtHeader);
1492 SectionCount = NtHeader->FileHeader.NumberOfSections;
1493 InitStart = 0;
1494 while (SectionCount > 0)
1495 {
1496 /* Assume failure */
1497 InitFound = FALSE;
1498
1499 /* Is this the INIT section or a discardable section? */
1500 if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1502 {
1503 /* Remember this */
1504 InitFound = TRUE;
1505 InitSection = Section;
1506 }
1507
1508 if (InitFound)
1509 {
1510 /* Pick the biggest size -- either raw or virtual */
1511 Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1512
1513 /* Read the section alignment */
1515
1516 /* Get the start and end addresses */
1517 InitStart = DllBase + Section->VirtualAddress;
1518 InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1519
1520 /* Align the addresses to PAGE_SIZE */
1521 InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1522 InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1523
1524 /* Have we reached the last section? */
1525 if (SectionCount == 1)
1526 {
1527 /* Remember this */
1528 LastSection = Section;
1529 }
1530 else
1531 {
1532 /* We have not, loop all the sections */
1533 LastSection = NULL;
1534 do
1535 {
1536 /* Keep going until we find a non-discardable section range */
1537 SectionCount--;
1538 Section++;
1540 {
1541 /* Discardable, so record it, then keep going */
1542 LastSection = Section;
1543 }
1544 else
1545 {
1546 /* Non-contigous discard flag, or no flag, break out */
1547 break;
1548 }
1549 }
1550 while (SectionCount > 1);
1551 }
1552
1553 /* Have we found a discardable or init section? */
1554 if (LastSection)
1555 {
1556 /* Pick the biggest size -- either raw or virtual */
1557 Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1558
1559 /* Use this as the end of the section address */
1560 InitEnd = DllBase + LastSection->VirtualAddress + Size;
1561
1562 /* Have we reached the last section yet? */
1563 if (SectionCount != 1)
1564 {
1565 /* Then align this accross the session boundary */
1566 InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1567 InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1568 }
1569 }
1570
1571 /* Make sure we don't let the init section go past the image */
1572 ImageEnd = DllBase + LdrEntry->SizeOfImage;
1573 if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1574
1575 /* Make sure we have a valid, non-zero init section */
1576 if (InitStart < InitEnd)
1577 {
1578 /* Make sure we are not within this code itself */
1579 if ((InitCode >= InitStart) && (InitCode < InitEnd))
1580 {
1581 /* Return it, we can't free ourselves now */
1582 ASSERT(*StartVa == 0);
1583 *StartVa = (PVOID)InitStart;
1584 *EndVa = (PVOID)InitEnd;
1585 }
1586 else
1587 {
1588 /* This isn't us -- go ahead and free it */
1589 ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1590 DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1591 (PVOID)InitStart,
1592 (PVOID)InitEnd,
1593 &LdrEntry->BaseDllName,
1594 LdrEntry->DllBase,
1595 InitSection->Name);
1596 MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1597 }
1598 }
1599 }
1600
1601 /* Move to the next section */
1602 SectionCount--;
1603 Section++;
1604 }
1605
1606 /* Move to the next module */
1607 NextEntry = NextEntry->Flink;
1608 }
1609
1610 /* Release the locks and return */
1614}
#define ALIGN_DOWN_BY(size, align)
#define ALIGN_UP_BY(size, align)
unsigned char BOOLEAN
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define LDRP_MM_LOADED
Definition: ldrtypes.h:60
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:945
#define KernelMode
Definition: asm.h:34
#define MUTANT_INCREMENT
Definition: extypes.h:84
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
CONST CHAR * PCCH
Definition: ntbasedef.h:392
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
#define DPRINT
Definition: sndvol32.h:71
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1437
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1414
KMUTANT MmSystemLoadLock
Definition: sysldr.c:26
@ WrVirtualMemory
Definition: ketypes.h:421

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiFreeInitializationCode()

VOID NTAPI MiFreeInitializationCode ( IN PVOID  InitStart,
IN PVOID  InitEnd 
)

Definition at line 1414 of file sysldr.c.

1416{
1417 PMMPTE PointerPte;
1418 PFN_NUMBER PagesFreed;
1419
1420 /* Get the start PTE */
1421 PointerPte = MiAddressToPte(InitStart);
1422 ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1423
1424 /* Compute the number of pages we expect to free */
1425 PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1426
1427 /* Try to actually free them */
1428 PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1429 PagesFreed,
1430 0,
1431 NULL);
1432}
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
ULONG PFN_NUMBER
Definition: ke.h:9

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiInitializeLoadedModuleList()

BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2191 of file sysldr.c.

2192{
2193 PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2194 PLIST_ENTRY ListHead, NextEntry;
2196
2197 /* Setup the loaded module list and locks */
2201
2202 /* Get loop variables and the kernel entry */
2203 ListHead = &LoaderBlock->LoadOrderListHead;
2204 NextEntry = ListHead->Flink;
2205 LdrEntry = CONTAINING_RECORD(NextEntry,
2207 InLoadOrderLinks);
2208 PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2209
2210 /* Locate resource section, pool code, and system pte code */
2211 MiLocateKernelSections(LdrEntry);
2212
2213 /* Loop the loader block */
2214 while (NextEntry != ListHead)
2215 {
2216 /* Get the loader entry */
2217 LdrEntry = CONTAINING_RECORD(NextEntry,
2219 InLoadOrderLinks);
2220
2221 /* FIXME: ROS HACK. Make sure this is a driver */
2222 if (!RtlImageNtHeader(LdrEntry->DllBase))
2223 {
2224 /* Skip this entry */
2225 NextEntry = NextEntry->Flink;
2226 continue;
2227 }
2228
2229 /* Calculate the size we'll need and allocate a copy */
2231 LdrEntry->BaseDllName.MaximumLength +
2232 sizeof(UNICODE_NULL);
2234 if (!NewEntry) return FALSE;
2235
2236 /* Copy the entry over */
2237 *NewEntry = *LdrEntry;
2238
2239 /* Allocate the name */
2240 NewEntry->FullDllName.Buffer =
2242 LdrEntry->FullDllName.MaximumLength +
2243 sizeof(UNICODE_NULL),
2244 TAG_LDR_WSTR);
2245 if (!NewEntry->FullDllName.Buffer)
2246 {
2248 return FALSE;
2249 }
2250
2251 /* Set the base name */
2252 NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2253
2254 /* Copy the full and base name */
2256 LdrEntry->FullDllName.Buffer,
2257 LdrEntry->FullDllName.MaximumLength);
2259 LdrEntry->BaseDllName.Buffer,
2260 LdrEntry->BaseDllName.MaximumLength);
2261
2262 /* Null-terminate the base name */
2263 NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2264 sizeof(WCHAR)] = UNICODE_NULL;
2265
2266 /* Insert the entry into the list */
2268 NextEntry = NextEntry->Flink;
2269 }
2270
2271 /* Build the import lists for the boot drivers */
2273
2274 /* We're done */
2275 return TRUE;
2276}
struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY
#define InsertTailList(ListHead, Entry)
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define UNICODE_NULL
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSTATUS NTAPI MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1869
VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2134
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:23
ULONG_PTR PsNtosImageBase
Definition: sysldr.c:25
#define TAG_MODULE_OBJECT
Definition: tag.h:101
#define TAG_LDR_WSTR
Definition: tag.h:102
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by MmArmInitSystem().

◆ MiLoadImageSection()

NTSTATUS NTAPI MiLoadImageSection ( _Inout_ PSECTION SectionPtr,
_Out_ PVOID ImageBase,
_In_ PUNICODE_STRING  FileName,
_In_ BOOLEAN  SessionLoad,
_In_ PLDR_DATA_TABLE_ENTRY  LdrEntry 
)

Definition at line 77 of file sysldr.c.

82{
83 PSECTION Section = *SectionPtr;
86 PVOID Base = NULL;
87 SIZE_T ViewSize = 0;
91 PFN_COUNT PteCount;
92 PMMPTE PointerPte, LastPte;
93 PVOID DriverBase;
96 PFN_NUMBER PageFrameIndex;
97 PAGED_CODE();
98
99 /* Detect session load */
100 if (SessionLoad)
101 {
102 /* Fail */
103 UNIMPLEMENTED_DBGBREAK("Session loading not yet supported!\n");
105 }
106
107 /* Not session load, shouldn't have an entry */
108 ASSERT(LdrEntry == NULL);
109
110 /* Attach to the system process */
112
113 /* Check if we need to load symbols */
115 {
116 /* Yes we do */
118 NtGlobalFlag &= ~FLG_ENABLE_KDEBUG_SYMBOL_LOAD;
119 }
120
121 /* Map the driver */
123 Status = MmMapViewOfSection(Section,
124 Process,
125 &Base,
126 0,
127 0,
129 &ViewSize,
130 ViewUnmap,
131 0,
133
134 /* Re-enable the flag */
136
137 /* Check if we failed with distinguished status code */
139 {
140 /* Change it to something more generic */
142 }
143
144 /* Now check if we failed */
145 if (!NT_SUCCESS(Status))
146 {
147 /* Detach and return */
148 DPRINT1("MmMapViewOfSection failed with status 0x%x\n", Status);
150 return Status;
151 }
152
153 /* Reserve system PTEs needed */
154 PteCount = ROUND_TO_PAGES(((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize) >> PAGE_SHIFT;
155 PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
156 if (!PointerPte)
157 {
158 DPRINT1("MiReserveSystemPtes failed\n");
161 }
162
163 /* New driver base */
164 LastPte = PointerPte + PteCount;
165 DriverBase = MiPteToAddress(PointerPte);
166
167 /* The driver is here */
168 *ImageBase = DriverBase;
169 DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
170
171 /* Lock the PFN database */
172 OldIrql = MiAcquirePfnLock();
173
174 /* Loop the new driver PTEs */
176 while (PointerPte < LastPte)
177 {
178 /* Make sure the PTE is not valid for whatever reason */
179 ASSERT(PointerPte->u.Hard.Valid == 0);
180
181 /* Some debug stuff */
183#if MI_TRACE_PFNS
184 MI_SET_PROCESS_USTR(FileName);
185#endif
186
187 /* Grab a page */
188 PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
189
190 /* Initialize its PFN entry */
191 MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
192
193 /* Write the PTE */
194 TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
195 MI_WRITE_VALID_PTE(PointerPte, TempPte);
196
197 /* Move on */
198 PointerPte++;
199 }
200
201 /* Release the PFN lock */
202 MiReleasePfnLock(OldIrql);
203
204 /* Copy the image */
205 RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);
206
207 /* Now unmap the view */
210
211 /* Detach and return status */
213 return Status;
214}
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3117
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD
Definition: pstypes.h:73
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:30
@ SystemPteSpace
Definition: miarm.h:403
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:232
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:959
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:962
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2427
#define PAGE_EXECUTE
Definition: nt_native.h:1306
@ ViewUnmap
Definition: nt_native.h:1279
ULONG NtGlobalFlag
Definition: init.c:54
#define MiPteToAddress(_Pte)
Definition: mm.h:116
@ MI_USAGE_DRIVER_PAGE
Definition: mm.h:337
#define MI_SET_USAGE(x)
Definition: mm.h:317
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1727
MMPTE ValidKernelPte
Definition: init.c:29
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH
Definition: ntstatus.h:128
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3968
KPROCESS Pcb
Definition: pstypes.h:1262
ULONG PageFrameNumber
Definition: mmtypes.h:109
ULONG64 Valid
Definition: mmtypes.h:150
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
union _MMPTE::@2307 u
PSEGMENT Segment
Definition: mmtypes.h:809
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
KAPC_STATE
Definition: ketypes.h:1285
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by MmLoadSystemImage().

◆ MiLocateExportName()

PVOID NTAPI MiLocateExportName ( IN PVOID  DllBase,
IN PCHAR  ExportName 
)

Definition at line 218 of file sysldr.c.

220{
221 PULONG NameTable;
222 PUSHORT OrdinalTable;
223 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
224 LONG Low = 0, Mid = 0, High, Ret;
225 USHORT Ordinal;
227 ULONG ExportSize;
228 PULONG ExportTable;
229 PAGED_CODE();
230
231 /* Get the export directory */
232 ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
233 TRUE,
235 &ExportSize);
236 if (!ExportDirectory) return NULL;
237
238 /* Setup name tables */
239 NameTable = (PULONG)((ULONG_PTR)DllBase +
240 ExportDirectory->AddressOfNames);
241 OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
242 ExportDirectory->AddressOfNameOrdinals);
243
244 /* Do a binary search */
245 High = ExportDirectory->NumberOfNames - 1;
246 while (High >= Low)
247 {
248 /* Get new middle value */
249 Mid = (Low + High) >> 1;
250
251 /* Compare name */
252 Ret = strcmp(ExportName, (PCHAR)DllBase + NameTable[Mid]);
253 if (Ret < 0)
254 {
255 /* Update high */
256 High = Mid - 1;
257 }
258 else if (Ret > 0)
259 {
260 /* Update low */
261 Low = Mid + 1;
262 }
263 else
264 {
265 /* We got it */
266 break;
267 }
268 }
269
270 /* Check if we couldn't find it */
271 if (High < Low) return NULL;
272
273 /* Otherwise, this is the ordinal */
274 Ordinal = OrdinalTable[Mid];
275
276 /* Resolve the address and write it */
277 ExportTable = (PULONG)((ULONG_PTR)DllBase +
278 ExportDirectory->AddressOfFunctions);
279 Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
280
281 /* Check if the function is actually a forwarder */
282 if (((ULONG_PTR)Function > (ULONG_PTR)ExportDirectory) &&
283 ((ULONG_PTR)Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
284 {
285 /* It is, fail */
286 return NULL;
287 }
288
289 /* We found it */
290 return Function;
291}

Referenced by MiCallDllUnloadAndUnloadDll(), and MmCallDllInitialize().

◆ MiLocateKernelSections()

VOID NTAPI MiLocateKernelSections ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2134 of file sysldr.c.

2135{
2136 ULONG_PTR DllBase;
2137 PIMAGE_NT_HEADERS NtHeaders;
2138 PIMAGE_SECTION_HEADER SectionHeader;
2139 ULONG Sections, Size;
2140
2141 /* Get the kernel section header */
2142 DllBase = (ULONG_PTR)LdrEntry->DllBase;
2143 NtHeaders = RtlImageNtHeader((PVOID)DllBase);
2144 SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
2145
2146 /* Loop all the sections */
2147 for (Sections = NtHeaders->FileHeader.NumberOfSections;
2148 Sections > 0; --Sections, ++SectionHeader)
2149 {
2150 /* Grab the size of the section */
2151 Size = max(SectionHeader->SizeOfRawData, SectionHeader->Misc.VirtualSize);
2152
2153 /* Check for .RSRC section */
2154 if (*(PULONG)SectionHeader->Name == 'rsr.')
2155 {
2156 /* Remember the PTEs so we can modify them later */
2158 SectionHeader->VirtualAddress);
2160 SectionHeader->VirtualAddress + Size));
2161 }
2162 else if (*(PULONG)SectionHeader->Name == 'LOOP')
2163 {
2164 /* POOLCODE vs. POOLMI */
2165 if (*(PULONG)&SectionHeader->Name[4] == 'EDOC')
2166 {
2167 /* Found Ex* Pool code */
2168 ExPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2170 }
2171 else if (*(PUSHORT)&SectionHeader->Name[4] == 'MI')
2172 {
2173 /* Found Mm* Pool code */
2174 MmPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2176 }
2177 }
2178 else if ((*(PULONG)SectionHeader->Name == 'YSIM') &&
2179 (*(PULONG)&SectionHeader->Name[4] == 'ETPS'))
2180 {
2181 /* Found MISYSPTE (Mm System PTE code) */
2182 MmPteCodeStart = DllBase + SectionHeader->VirtualAddress;
2184 }
2185 }
2186}
ULONG_PTR ExPoolCodeStart
Definition: sysldr.c:37
ULONG_PTR MmPoolCodeEnd
Definition: sysldr.c:37
ULONG_PTR ExPoolCodeEnd
Definition: sysldr.c:37
ULONG_PTR MmPteCodeEnd
Definition: sysldr.c:38
ULONG_PTR MmPoolCodeStart
Definition: sysldr.c:37
ULONG_PTR MmPteCodeStart
Definition: sysldr.c:38
PMMPTE MiKernelResourceEndPte
Definition: sysldr.c:36
PMMPTE MiKernelResourceStartPte
Definition: sysldr.c:36

Referenced by MiInitializeLoadedModuleList().

◆ MiLookupDataTableEntry()

PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry ( IN PVOID  Address)

Definition at line 3464 of file sysldr.c.

3465{
3466 PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
3467 PLIST_ENTRY NextEntry;
3468 PAGED_CODE();
3469
3470 /* Loop entries */
3471 NextEntry = PsLoadedModuleList.Flink;
3472 do
3473 {
3474 /* Get the loader entry */
3475 LdrEntry = CONTAINING_RECORD(NextEntry,
3477 InLoadOrderLinks);
3478
3479 /* Check if the address matches */
3480 if ((Address >= LdrEntry->DllBase) &&
3481 (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
3482 LdrEntry->SizeOfImage)))
3483 {
3484 /* Found a match */
3485 FoundEntry = LdrEntry;
3486 break;
3487 }
3488
3489 /* Move on */
3490 NextEntry = NextEntry->Flink;
3491 } while(NextEntry != &PsLoadedModuleList);
3492
3493 /* Return the entry */
3494 return FoundEntry;
3495}
static WCHAR Address[46]
Definition: ping.c:68

Referenced by ExAllocatePool(), MmAddVerifierThunks(), and MmPageEntireDriver().

◆ MiProcessLoaderEntry()

VOID NTAPI MiProcessLoaderEntry ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN BOOLEAN  Insert 
)

Definition at line 552 of file sysldr.c.

554{
556
557 /* Acquire module list lock */
560
561 /* Acquire the spinlock too as we will insert or remove the entry */
563
564 /* Insert or remove from the list */
565 if (Insert)
566 InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
567 else
568 RemoveEntryList(&LdrEntry->InLoadOrderLinks);
569
570 /* Release locks */
574}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
KIRQL FASTCALL KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
Definition: spinlock.c:62

Referenced by MmLoadSystemImage(), and MmUnloadSystemImage().

◆ MiReloadBootLoadedDrivers()

VOID NTAPI MiReloadBootLoadedDrivers ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 1680 of file sysldr.c.

1681{
1682 PLIST_ENTRY NextEntry;
1683 ULONG i = 0;
1684 PIMAGE_NT_HEADERS NtHeader;
1685 PLDR_DATA_TABLE_ENTRY LdrEntry;
1686 PIMAGE_FILE_HEADER FileHeader;
1687 BOOLEAN ValidRelocs;
1688 PIMAGE_DATA_DIRECTORY DataDirectory;
1689 PVOID DllBase, NewImageAddress;
1691 PMMPTE PointerPte, StartPte, LastPte;
1692 PFN_COUNT PteCount;
1693 PMMPFN Pfn1;
1694 MMPTE TempPte, OldPte;
1695
1696 /* Loop driver list */
1697 for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1698 NextEntry != &LoaderBlock->LoadOrderListHead;
1699 NextEntry = NextEntry->Flink)
1700 {
1701 /* Get the loader entry and NT header */
1702 LdrEntry = CONTAINING_RECORD(NextEntry,
1704 InLoadOrderLinks);
1705 NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1706
1707 /* Debug info */
1708 DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1709 LdrEntry->DllBase,
1710 (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1711 &LdrEntry->FullDllName);
1712
1713 /* Get the first PTE and the number of PTEs we'll need */
1714 PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1715 PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1716 LastPte = StartPte + PteCount;
1717
1718#if MI_TRACE_PFNS
1719 /* Loop the PTEs */
1720 while (PointerPte < LastPte)
1721 {
1722 ULONG len;
1723 ASSERT(PointerPte->u.Hard.Valid == 1);
1724 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1725 len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1726 snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1727 PointerPte++;
1728 }
1729#endif
1730 /* Skip kernel and HAL */
1731 /* ROS HACK: Skip BOOTVID/KDCOM too */
1732 i++;
1733 if (i <= 4) continue;
1734
1735 /* Skip non-drivers */
1736 if (!NtHeader) continue;
1737
1738 /* Get the file header and make sure we can relocate */
1739 FileHeader = &NtHeader->FileHeader;
1740 if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1741 if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1743
1744 /* Everything made sense until now, check the relocation section too */
1745 DataDirectory = &NtHeader->OptionalHeader.
1746 DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1747 if (!DataDirectory->VirtualAddress)
1748 {
1749 /* We don't really have relocations */
1750 ValidRelocs = FALSE;
1751 }
1752 else
1753 {
1754 /* Make sure the size is valid */
1755 if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1756 LdrEntry->SizeOfImage)
1757 {
1758 /* They're not, skip */
1759 continue;
1760 }
1761
1762 /* We have relocations */
1763 ValidRelocs = TRUE;
1764 }
1765
1766 /* Remember the original address */
1767 DllBase = LdrEntry->DllBase;
1768
1769 /* Loop the PTEs */
1770 PointerPte = StartPte;
1771 while (PointerPte < LastPte)
1772 {
1773 /* Mark the page modified in the PFN database */
1774 ASSERT(PointerPte->u.Hard.Valid == 1);
1775 Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1776 ASSERT(Pfn1->u3.e1.Rom == 0);
1777 Pfn1->u3.e1.Modified = TRUE;
1778
1779 /* Next */
1780 PointerPte++;
1781 }
1782
1783 /* Now reserve system PTEs for the image */
1784 PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1785 if (!PointerPte)
1786 {
1787 /* Shouldn't happen */
1788 ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1789 return;
1790 }
1791
1792 /* This is the new virtual address for the module */
1793 LastPte = PointerPte + PteCount;
1794 NewImageAddress = MiPteToAddress(PointerPte);
1795
1796 /* Sanity check */
1797 DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1799
1800 /* Loop the new driver PTEs */
1802 while (PointerPte < LastPte)
1803 {
1804 /* Copy the old data */
1805 OldPte = *StartPte;
1806 ASSERT(OldPte.u.Hard.Valid == 1);
1807
1808 /* Set page number from the loader's memory */
1810
1811 /* Write it */
1812 MI_WRITE_VALID_PTE(PointerPte, TempPte);
1813
1814 /* Move on */
1815 PointerPte++;
1816 StartPte++;
1817 }
1818
1819 /* Update position */
1820 PointerPte -= PteCount;
1821
1822 /* Sanity check */
1823 ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1824
1825 /* Set the image base to the address where the loader put it */
1826 NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1827
1828 /* Check if we had relocations */
1829 if (ValidRelocs)
1830 {
1831 /* Relocate the image */
1832 Status = LdrRelocateImageWithBias(NewImageAddress,
1833 0,
1834 "SYSLDR",
1838 if (!NT_SUCCESS(Status))
1839 {
1840 /* This shouldn't happen */
1841 ERROR_FATAL("Relocations failed!\n");
1842 return;
1843 }
1844 }
1845
1846 /* Update the loader entry */
1847 LdrEntry->DllBase = NewImageAddress;
1848
1849 /* Update the thunks */
1850 DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1851 MiUpdateThunks(LoaderBlock,
1852 DllBase,
1853 NewImageAddress,
1854 LdrEntry->SizeOfImage);
1855
1856 /* Update the loader entry */
1857 LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1858 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1860 LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1861
1862 /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1863 }
1864}
GLenum GLsizei len
Definition: glext.h:6722
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define LDRP_SYSTEM_MAPPED
Definition: ldrtypes.h:54
#define min(a, b)
Definition: monoChain.cc:55
NTSYSAPI ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
ULONG ExpInitializationPhase
Definition: init.c:68
#define PFN_FROM_PTE(v)
Definition: mm.h:92
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
PVOID EntryPoint
Definition: ntddk_ex.h:203
USHORT Modified
Definition: mm.h:360
USHORT Rom
Definition: mm.h:368
Definition: mm.h:374
union _MMPFN::@1772 u3
MMPFNENTRY e1
Definition: mm.h:397
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
VOID NTAPI MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
Definition: sysldr.c:579
#define snprintf
Definition: wintirpc.h:48

Referenced by MmArmInitSystem().

◆ MiResolveImageReferences()

NTSTATUS NTAPI MiResolveImageReferences ( IN PVOID  ImageBase,
IN PUNICODE_STRING  ImageFileDirectory,
IN PUNICODE_STRING NamePrefix  OPTIONAL,
OUT PCHAR MissingApi,
OUT PWCHAR MissingDriver,
OUT PLOAD_IMPORTS LoadImports 
)

Definition at line 987 of file sysldr.c.

993{
994 static UNICODE_STRING DriversFolderName = RTL_CONSTANT_STRING(L"drivers\\");
995 PCHAR MissingApiBuffer = *MissingApi, ImportName;
996 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
997 ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
998 PLOAD_IMPORTS LoadedImports, NewImports;
999 ULONG GdiLink, NormalLink, i;
1000 BOOLEAN ReferenceNeeded, Loaded;
1001 ANSI_STRING TempString;
1002 UNICODE_STRING NameString, DllName;
1003 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
1004 PVOID ImportBase, DllBase;
1005 PLIST_ENTRY NextEntry;
1006 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
1008 PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
1009 PAGED_CODE();
1010 DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
1011 __FUNCTION__, ImageBase, ImageFileDirectory);
1012
1013 /* No name string buffer yet */
1014 NameString.Buffer = NULL;
1015
1016 /* Assume no imports */
1017 *LoadImports = MM_SYSLDR_NO_IMPORTS;
1018
1019 /* Get the import descriptor */
1020 ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
1021 TRUE,
1023 &ImportSize);
1024 if (!ImportDescriptor) return STATUS_SUCCESS;
1025
1026 /* Loop all imports to count them */
1027 for (CurrentImport = ImportDescriptor;
1028 (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
1029 CurrentImport++)
1030 {
1031 /* One more */
1032 ImportCount++;
1033 }
1034
1035 /* Make sure we have non-zero imports */
1036 if (ImportCount)
1037 {
1038 /* Calculate and allocate the list we'll need */
1039 LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1040 LoadedImports = ExAllocatePoolWithTag(PagedPool,
1041 LoadedImportsSize,
1043 if (LoadedImports)
1044 {
1045 /* Zero it */
1046 RtlZeroMemory(LoadedImports, LoadedImportsSize);
1047 LoadedImports->Count = ImportCount;
1048 }
1049 }
1050 else
1051 {
1052 /* No table */
1053 LoadedImports = NULL;
1054 }
1055
1056 /* Reset the import count and loop descriptors again */
1057 ImportCount = GdiLink = NormalLink = 0;
1058 while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))
1059 {
1060 /* Get the name */
1061 ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
1062
1063 /* Check if this is a GDI driver */
1064 GdiLink = GdiLink |
1065 !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
1066
1067 /* We can also allow dxapi (for Windows compat, allow IRT and coverage) */
1068 NormalLink = NormalLink |
1069 ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
1070 (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)) &&
1071 (_strnicmp(ImportName, "coverage", sizeof("coverage") - 1)) &&
1072 (_strnicmp(ImportName, "irt", sizeof("irt") - 1)));
1073
1074 /* Check if this is a valid GDI driver */
1075 if ((GdiLink) && (NormalLink))
1076 {
1077 /* It's not, it's importing stuff it shouldn't be! */
1079 goto Failure;
1080 }
1081
1082 /* Check for user-mode printer or video card drivers, which don't belong */
1083 if (!(_strnicmp(ImportName, "ntdll", sizeof("ntdll") - 1)) ||
1084 !(_strnicmp(ImportName, "winsrv", sizeof("winsrv") - 1)) ||
1085 !(_strnicmp(ImportName, "advapi32", sizeof("advapi32") - 1)) ||
1086 !(_strnicmp(ImportName, "kernel32", sizeof("kernel32") - 1)) ||
1087 !(_strnicmp(ImportName, "user32", sizeof("user32") - 1)) ||
1088 !(_strnicmp(ImportName, "gdi32", sizeof("gdi32") - 1)))
1089 {
1090 /* This is not kernel code */
1092 goto Failure;
1093 }
1094
1095 /* Check if this is a "core" import, which doesn't get referenced */
1096 if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||
1097 !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||
1098 !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
1099 {
1100 /* Don't reference this */
1101 ReferenceNeeded = FALSE;
1102 }
1103 else
1104 {
1105 /* Reference these modules */
1106 ReferenceNeeded = TRUE;
1107 }
1108
1109 /* Now setup a unicode string for the import */
1110 RtlInitAnsiString(&TempString, ImportName);
1111 Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
1112 if (!NT_SUCCESS(Status))
1113 {
1114 /* Failed */
1115 goto Failure;
1116 }
1117
1118 /* We don't support name prefixes yet */
1119 if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
1120
1121 /* Remember that we haven't loaded the import at this point */
1122CheckDllState:
1123 Loaded = FALSE;
1124 ImportBase = NULL;
1125
1126 /* Loop the driver list */
1127 NextEntry = PsLoadedModuleList.Flink;
1128 while (NextEntry != &PsLoadedModuleList)
1129 {
1130 /* Get the loader entry and compare the name */
1131 LdrEntry = CONTAINING_RECORD(NextEntry,
1133 InLoadOrderLinks);
1134 if (RtlEqualUnicodeString(&NameString,
1135 &LdrEntry->BaseDllName,
1136 TRUE))
1137 {
1138 /* Get the base address */
1139 ImportBase = LdrEntry->DllBase;
1140
1141 /* Check if we haven't loaded yet, and we need references */
1142 if (!(Loaded) && (ReferenceNeeded))
1143 {
1144 /* Make sure we're not already loading */
1145 if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1146 {
1147 /* Increase the load count */
1148 LdrEntry->LoadCount++;
1149 }
1150 }
1151
1152 /* Done, break out */
1153 break;
1154 }
1155
1156 /* Go to the next entry */
1157 NextEntry = NextEntry->Flink;
1158 }
1159
1160 /* Check if we haven't loaded the import yet */
1161 if (!ImportBase)
1162 {
1163 /* Setup the import DLL name */
1164 DllName.MaximumLength = NameString.Length +
1165 ImageFileDirectory->Length +
1166 sizeof(UNICODE_NULL);
1168 DllName.MaximumLength,
1169 TAG_LDR_WSTR);
1170 if (!DllName.Buffer)
1171 {
1172 /* We're out of resources */
1174 goto Failure;
1175 }
1176
1177 /* Add the import name to the base directory */
1178 RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1180 &NameString);
1181
1182 /* Load the image */
1183 Status = MmLoadSystemImage(&DllName,
1184 NamePrefix,
1185 NULL,
1186 FALSE,
1187 (PVOID *)&DllEntry,
1188 &DllBase);
1189
1190 /* win32k / GDI drivers can also import from system32 folder */
1192 (MI_IS_SESSION_ADDRESS(ImageBase) || 1)) // HACK
1193 {
1194 /* Free the old name buffer */
1196
1197 /* Calculate size for a string the adds 'drivers\' */
1198 DllName.MaximumLength += DriversFolderName.Length;
1199
1200 /* Allocate the new buffer */
1202 DllName.MaximumLength,
1203 TAG_LDR_WSTR);
1204 if (!DllName.Buffer)
1205 {
1206 /* We're out of resources */
1208 goto Failure;
1209 }
1210
1211 /* Copy image directory and append 'drivers\' folder name */
1212 RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1213 RtlAppendUnicodeStringToString(&DllName, &DriversFolderName);
1214
1215 /* Now add the import name */
1216 RtlAppendUnicodeStringToString(&DllName, &NameString);
1217
1218 /* Try once again to load the image */
1219 Status = MmLoadSystemImage(&DllName,
1220 NamePrefix,
1221 NULL,
1222 FALSE,
1223 (PVOID *)&DllEntry,
1224 &DllBase);
1225 }
1226
1227 if (!NT_SUCCESS(Status))
1228 {
1229 /* Fill out the information for the error */
1230 *MissingDriver = DllName.Buffer;
1231 *(PULONG)MissingDriver |= 1;
1232 *MissingApi = NULL;
1233
1234 DPRINT1("Failed to load dependency: %wZ\n", &DllName);
1235
1236 /* Don't free the name */
1237 DllName.Buffer = NULL;
1238
1239 /* Cleanup and return */
1240 goto Failure;
1241 }
1242
1243 /* We can free the DLL Name */
1245 DllName.Buffer = NULL;
1246
1247 /* We're now loaded */
1248 Loaded = TRUE;
1249
1250 /* Sanity check */
1251 ASSERT(DllBase == DllEntry->DllBase);
1252
1253 /* Call the initialization routines */
1255 if (!NT_SUCCESS(Status))
1256 {
1257 /* We failed, unload the image */
1258 MmUnloadSystemImage(DllEntry);
1259 ERROR_DBGBREAK("MmCallDllInitialize failed with status 0x%x\n", Status);
1260 Loaded = FALSE;
1261 }
1262
1263 /* Loop again to make sure that everything is OK */
1264 goto CheckDllState;
1265 }
1266
1267 /* Check if we're support to reference this import */
1268 if ((ReferenceNeeded) && (LoadedImports))
1269 {
1270 /* Make sure we're not already loading */
1271 if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1272 {
1273 /* Add the entry */
1274 LoadedImports->Entry[ImportCount] = LdrEntry;
1275 ImportCount++;
1276 }
1277 }
1278
1279 /* Free the import name */
1280 RtlFreeUnicodeString(&NameString);
1281
1282 /* Set the missing driver name and get the export directory */
1283 *MissingDriver = LdrEntry->BaseDllName.Buffer;
1284 ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
1285 TRUE,
1287 &ExportSize);
1288 if (!ExportDirectory)
1289 {
1290 /* Cleanup and return */
1291 DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver);
1293 goto Failure;
1294 }
1295
1296 /* Make sure we have an IAT */
1297 if (ImportDescriptor->OriginalFirstThunk)
1298 {
1299 /* Get the first thunks */
1300 OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
1301 ImportDescriptor->OriginalFirstThunk);
1302 FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
1303 ImportDescriptor->FirstThunk);
1304
1305 /* Loop the IAT */
1306 while (OrigThunk->u1.AddressOfData)
1307 {
1308 /* Snap thunk */
1309 Status = MiSnapThunk(ImportBase,
1310 ImageBase,
1311 OrigThunk++,
1312 FirstThunk++,
1313 ExportDirectory,
1314 ExportSize,
1315 FALSE,
1316 MissingApi);
1317 if (!NT_SUCCESS(Status))
1318 {
1319 /* Cleanup and return */
1320 goto Failure;
1321 }
1322
1323 /* Reset the buffer */
1324 *MissingApi = MissingApiBuffer;
1325 }
1326 }
1327
1328 /* Go to the next import */
1329 ImportDescriptor++;
1330 }
1331
1332 /* Check if we have an import list */
1333 if (LoadedImports)
1334 {
1335 /* Reset the count again, and loop entries */
1336 ImportCount = 0;
1337 for (i = 0; i < LoadedImports->Count; i++)
1338 {
1339 if (LoadedImports->Entry[i])
1340 {
1341 /* Got an entry, OR it with 1 in case it's the single entry */
1342 ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] |
1344 ImportCount++;
1345 }
1346 }
1347
1348 /* Check if we had no imports */
1349 if (!ImportCount)
1350 {
1351 /* Free the list and set it to no imports */
1352 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1353 LoadedImports = MM_SYSLDR_NO_IMPORTS;
1354 }
1355 else if (ImportCount == 1)
1356 {
1357 /* Just one entry, we can free the table and only use our entry */
1358 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1359 LoadedImports = (PLOAD_IMPORTS)ImportEntry;
1360 }
1361 else if (ImportCount != LoadedImports->Count)
1362 {
1363 /* Allocate a new list */
1364 LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1365 NewImports = ExAllocatePoolWithTag(PagedPool,
1366 LoadedImportsSize,
1368 if (NewImports)
1369 {
1370 /* Set count */
1371 NewImports->Count = 0;
1372
1373 /* Loop all the imports */
1374 for (i = 0; i < LoadedImports->Count; i++)
1375 {
1376 /* Make sure it's valid */
1377 if (LoadedImports->Entry[i])
1378 {
1379 /* Copy it */
1380 NewImports->Entry[NewImports->Count] = LoadedImports->Entry[i];
1381 NewImports->Count++;
1382 }
1383 }
1384
1385 /* Free the old copy */
1386 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1387 LoadedImports = NewImports;
1388 }
1389 }
1390
1391 /* Return the list */
1392 *LoadImports = LoadedImports;
1393 }
1394
1395 /* Return success */
1396 return STATUS_SUCCESS;
1397
1398Failure:
1399
1400 /* Cleanup and return */
1401 RtlFreeUnicodeString(&NameString);
1402
1403 if (LoadedImports)
1404 {
1405 MiDereferenceImports(LoadedImports);
1406 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1407 }
1408
1409 return Status;
1410}
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define __FUNCTION__
Definition: types.h:116
@ Loaded
Definition: fs_rec.h:187
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:42
struct _LOAD_IMPORTS * PLOAD_IMPORTS
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:171
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:736
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:358
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
union _IMAGE_THUNK_DATA32::@2111 u1
NTSTATUS NTAPI MiSnapThunk(IN PVOID DllBase, IN PVOID ImageBase, IN PIMAGE_THUNK_DATA Name, IN PIMAGE_THUNK_DATA Address, IN PIMAGE_EXPORT_DIRECTORY ExportDirectory, IN ULONG ExportSize, IN BOOLEAN SnapForwarder, OUT PCHAR *MissingApi)
Definition: sysldr.c:678
NTSTATUS NTAPI MmLoadSystemImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
Definition: sysldr.c:2885
NTSTATUS NTAPI MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
Definition: sysldr.c:295
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

Referenced by LdrProcessDriverModule(), and MmLoadSystemImage().

◆ MiSetPagingOfDriver()

VOID NTAPI MiSetPagingOfDriver ( IN PMMPTE  PointerPte,
IN PMMPTE  LastPte 
)

Definition at line 2547 of file sysldr.c.

2549{
2550#ifdef ENABLE_MISETPAGINGOFDRIVER
2551 PVOID ImageBase;
2552 PETHREAD CurrentThread = PsGetCurrentThread();
2553 PFN_COUNT PageCount = 0;
2554 PFN_NUMBER PageFrameIndex;
2555 PMMPFN Pfn1;
2556#endif // ENABLE_MISETPAGINGOFDRIVER
2557
2558 PAGED_CODE();
2559
2560#ifndef ENABLE_MISETPAGINGOFDRIVER
2561 /* The page fault handler is broken and doesn't page back in! */
2562 DPRINT1("WARNING: MiSetPagingOfDriver() called, but paging is broken! ignoring!\n");
2563#else // ENABLE_MISETPAGINGOFDRIVER
2564 /* Get the driver's base address */
2565 ImageBase = MiPteToAddress(PointerPte);
2567
2568 /* If this is a large page, it's stuck in physical memory */
2569 if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
2570
2571 /* Lock the working set */
2572 MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
2573
2574 /* Loop the PTEs */
2575 while (PointerPte <= LastPte)
2576 {
2577 /* Check for valid PTE */
2578 if (PointerPte->u.Hard.Valid == 1)
2579 {
2580 PageFrameIndex = PFN_FROM_PTE(PointerPte);
2581 Pfn1 = MiGetPfnEntry(PageFrameIndex);
2582 ASSERT(Pfn1->u2.ShareCount == 1);
2583
2584 /* No working sets in ReactOS yet */
2585 PageCount++;
2586 }
2587
2588 ImageBase = (PVOID)((ULONG_PTR)ImageBase + PAGE_SIZE);
2589 PointerPte++;
2590 }
2591
2592 /* Release the working set */
2593 MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
2594
2595 /* Do we have any driver pages? */
2596 if (PageCount)
2597 {
2598 /* Update counters */
2600 }
2601#endif // ENABLE_MISETPAGINGOFDRIVER
2602}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define InterlockedExchangeAdd
Definition: interlocked.h:181
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1265
#define MI_IS_SESSION_IMAGE_ADDRESS(Address)
Definition: miarm.h:168
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1351
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
ULONG_PTR ShareCount
Definition: mm.h:390
union _MMPFN::@1771 u2
PFN_NUMBER MmTotalSystemDriverPages
Definition: sysldr.c:28
int32_t * PLONG
Definition: typedefs.h:58

Referenced by MiEnablePagingOfDriver(), and MmPageEntireDriver().

◆ MiSetSystemCodeProtection()

VOID NTAPI MiSetSystemCodeProtection ( _In_ PMMPTE  FirstPte,
_In_ PMMPTE  LastPte,
_In_ ULONG  Protection 
)

Definition at line 2391 of file sysldr.c.

2395{
2396 PMMPTE PointerPte;
2397 MMPTE TempPte;
2398
2399 /* Loop the PTEs */
2400 for (PointerPte = FirstPte; PointerPte <= LastPte; PointerPte++)
2401 {
2402 /* Read the PTE */
2403 TempPte = *PointerPte;
2404
2405 /* Make sure it's valid */
2406 if (TempPte.u.Hard.Valid != 1)
2407 {
2408 DPRINT1("CORE-16449: FirstPte=%p, LastPte=%p, Protection=%lx\n", FirstPte, LastPte, Protection);
2409 DPRINT1("CORE-16449: PointerPte=%p, TempPte=%lx\n", PointerPte, TempPte.u.Long);
2410 DPRINT1("CORE-16449: Please issue the 'mod' and 'bt' (KDBG) or 'lm' and 'kp' (WinDbg) commands. Then report this in Jira.\n");
2411 ASSERT(TempPte.u.Hard.Valid == 1);
2412 break;
2413 }
2414
2415 /* Update the protection */
2416 TempPte.u.Hard.Write = BooleanFlagOn(Protection, IMAGE_SCN_MEM_WRITE);
2417#if _MI_HAS_NO_EXECUTE
2419#endif
2420
2421 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2422 }
2423
2424 /* Flush it all */
2426}
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:977
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:438

Referenced by MiWriteProtectSystemImage().

◆ MiSnapThunk()

NTSTATUS NTAPI MiSnapThunk ( IN PVOID  DllBase,
IN PVOID  ImageBase,
IN PIMAGE_THUNK_DATA  Name,
IN PIMAGE_THUNK_DATA  Address,
IN PIMAGE_EXPORT_DIRECTORY  ExportDirectory,
IN ULONG  ExportSize,
IN BOOLEAN  SnapForwarder,
OUT PCHAR MissingApi 
)

Definition at line 678 of file sysldr.c.

686{
687 BOOLEAN IsOrdinal;
688 USHORT Ordinal;
689 PULONG NameTable;
690 PUSHORT OrdinalTable;
691 PIMAGE_IMPORT_BY_NAME NameImport;
692 USHORT Hint;
693 ULONG Low = 0, Mid = 0, High;
694 LONG Ret;
696 PCHAR MissingForwarder;
697 CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
698 PULONG ExportTable;
699 ANSI_STRING DllName;
700 UNICODE_STRING ForwarderName;
701 PLIST_ENTRY NextEntry;
702 PLDR_DATA_TABLE_ENTRY LdrEntry;
703 ULONG ForwardExportSize;
704 PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
705 PIMAGE_IMPORT_BY_NAME ForwardName;
706 SIZE_T ForwardLength;
707 IMAGE_THUNK_DATA ForwardThunk;
708 PAGED_CODE();
709
710 /* Check if this is an ordinal */
711 IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
712 if ((IsOrdinal) && !(SnapForwarder))
713 {
714 /* Get the ordinal number and set it as missing */
715 Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
716 ExportDirectory->Base);
717 *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
718 }
719 else
720 {
721 /* Get the VA if we don't have to snap */
722 if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
723 NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
724
725 /* Copy the procedure name */
726 RtlStringCbCopyA(*MissingApi,
728 (PCHAR)&NameImport->Name[0]);
729
730 /* Setup name tables */
731 DPRINT("Import name: %s\n", NameImport->Name);
732 NameTable = (PULONG)((ULONG_PTR)DllBase +
733 ExportDirectory->AddressOfNames);
734 OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
735 ExportDirectory->AddressOfNameOrdinals);
736
737 /* Get the hint and check if it's valid */
738 Hint = NameImport->Hint;
739 if ((Hint < ExportDirectory->NumberOfNames) &&
740 !(strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
741 {
742 /* We have a match, get the ordinal number from here */
743 Ordinal = OrdinalTable[Hint];
744 }
745 else
746 {
747 /* Do a binary search */
748 High = ExportDirectory->NumberOfNames - 1;
749 while (High >= Low)
750 {
751 /* Get new middle value */
752 Mid = (Low + High) >> 1;
753
754 /* Compare name */
755 Ret = strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Mid]);
756 if (Ret < 0)
757 {
758 /* Update high */
759 High = Mid - 1;
760 }
761 else if (Ret > 0)
762 {
763 /* Update low */
764 Low = Mid + 1;
765 }
766 else
767 {
768 /* We got it */
769 break;
770 }
771 }
772
773 /* Check if we couldn't find it */
774 if (High < Low)
775 {
776 DPRINT1("Warning: Driver failed to load, %s not found\n", NameImport->Name);
778 }
779
780 /* Otherwise, this is the ordinal */
781 Ordinal = OrdinalTable[Mid];
782 }
783 }
784
785 /* Check if the ordinal is invalid */
786 if (Ordinal >= ExportDirectory->NumberOfFunctions)
787 {
788 /* Fail */
790 }
791 else
792 {
793 /* In case the forwarder is missing */
794 MissingForwarder = NameBuffer;
795
796 /* Resolve the address and write it */
797 ExportTable = (PULONG)((ULONG_PTR)DllBase +
798 ExportDirectory->AddressOfFunctions);
799 Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
800
801 /* Assume success from now on */
803
804 /* Check if the function is actually a forwarder */
805 if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
806 (Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
807 {
808 /* Now assume failure in case the forwarder doesn't exist */
810
811 /* Build the forwarder name */
812 DllName.Buffer = (PCHAR)Address->u1.Function;
813 DllName.Length = (USHORT)(strchr(DllName.Buffer, '.') -
814 DllName.Buffer) +
815 sizeof(ANSI_NULL);
816 DllName.MaximumLength = DllName.Length;
817
818 /* Convert it */
819 if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
820 &DllName,
821 TRUE)))
822 {
823 /* We failed, just return an error */
824 return Status;
825 }
826
827 /* Loop the module list */
828 NextEntry = PsLoadedModuleList.Flink;
829 while (NextEntry != &PsLoadedModuleList)
830 {
831 /* Get the loader entry */
832 LdrEntry = CONTAINING_RECORD(NextEntry,
834 InLoadOrderLinks);
835
836 /* Check if it matches */
837 if (RtlPrefixUnicodeString(&ForwarderName,
838 &LdrEntry->BaseDllName,
839 TRUE))
840 {
841 /* Get the forwarder export directory */
842 ForwardExportDirectory =
844 TRUE,
846 &ForwardExportSize);
847 if (!ForwardExportDirectory) break;
848
849 /* Allocate a name entry */
850 ForwardLength = strlen(DllName.Buffer + DllName.Length) +
851 sizeof(ANSI_NULL);
852 ForwardName = ExAllocatePoolWithTag(PagedPool,
853 sizeof(*ForwardName) +
854 ForwardLength,
856 if (!ForwardName) break;
857
858 /* Copy the data */
859 RtlCopyMemory(&ForwardName->Name[0],
860 DllName.Buffer + DllName.Length,
861 ForwardLength);
862 ForwardName->Hint = 0;
863
864 /* Set the new address */
865 ForwardThunk.u1.AddressOfData = (ULONG_PTR)ForwardName;
866
867 /* Snap the forwarder */
868 Status = MiSnapThunk(LdrEntry->DllBase,
869 ImageBase,
870 &ForwardThunk,
871 &ForwardThunk,
872 ForwardExportDirectory,
873 ForwardExportSize,
874 TRUE,
875 &MissingForwarder);
876
877 /* Free the forwarder name and set the thunk */
878 ExFreePoolWithTag(ForwardName, TAG_LDR_WSTR);
879 Address->u1 = ForwardThunk.u1;
880 break;
881 }
882
883 /* Go to the next entry */
884 NextEntry = NextEntry->Flink;
885 }
886
887 /* Free the name */
888 RtlFreeUnicodeString(&ForwarderName);
889 }
890 }
891
892 /* Return status */
893 return Status;
894}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define ANSI_NULL
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
#define STATUS_DRIVER_ORDINAL_NOT_FOUND
Definition: ntstatus.h:735
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
USHORT MaximumLength
Definition: env_spec_w32.h:377
char CHAR
Definition: xmlstorage.h:175

Referenced by MiResolveImageReferences(), and MiSnapThunk().

◆ MiUpdateThunks()

VOID NTAPI MiUpdateThunks ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
IN PVOID  OldBase,
IN PVOID  NewBase,
IN ULONG  Size 
)

Definition at line 579 of file sysldr.c.

583{
584 ULONG_PTR OldBaseTop, Delta;
585 PLDR_DATA_TABLE_ENTRY LdrEntry;
586 PLIST_ENTRY NextEntry;
587 ULONG ImportSize;
588 //
589 // FIXME: MINGW-W64 must fix LD to generate drivers that Windows can load,
590 // since a real version of Windows would fail at this point, but they seem
591 // busy implementing features such as "HotPatch" support in GCC 4.6 instead,
592 // a feature which isn't even used by Windows. Priorities, priorities...
593 // Please note that Microsoft WDK EULA and license prohibits using
594 // the information contained within it for the generation of "non-Windows"
595 // drivers, which is precisely what LD will generate, since an LD driver
596 // will not load on Windows.
597 //
598#ifdef _WORKING_LINKER_
599 ULONG i;
600#endif
601 PULONG_PTR ImageThunk;
602 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
603
604 /* Calculate the top and delta */
605 OldBaseTop = (ULONG_PTR)OldBase + Size - 1;
606 Delta = (ULONG_PTR)NewBase - (ULONG_PTR)OldBase;
607
608 /* Loop the loader block */
609 for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
610 NextEntry != &LoaderBlock->LoadOrderListHead;
611 NextEntry = NextEntry->Flink)
612 {
613 /* Get the loader entry */
614 LdrEntry = CONTAINING_RECORD(NextEntry,
616 InLoadOrderLinks);
617#ifdef _WORKING_LINKER_
618 /* Get the IAT */
619 ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
620 TRUE,
622 &ImportSize);
623 if (!ImageThunk) continue;
624
625 /* Make sure we have an IAT */
626 DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
627 for (i = 0; i < ImportSize; i++, ImageThunk++)
628 {
629 /* Check if it's within this module */
630 if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
631 {
632 /* Relocate it */
633 DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
634 ImageThunk, *ImageThunk, *ImageThunk + Delta);
635 *ImageThunk += Delta;
636 }
637 }
638#else
639 /* Get the import table */
640 ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
641 TRUE,
643 &ImportSize);
644 if (!ImportDescriptor) continue;
645
646 /* Make sure we have an IAT */
647 DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
648 while ((ImportDescriptor->Name) &&
649 (ImportDescriptor->OriginalFirstThunk))
650 {
651 /* Get the image thunk */
652 ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
653 ImportDescriptor->FirstThunk);
654 while (*ImageThunk)
655 {
656 /* Check if it's within this module */
657 if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
658 {
659 /* Relocate it */
660 DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
661 ImageThunk, *ImageThunk, *ImageThunk + Delta);
662 *ImageThunk += Delta;
663 }
664
665 /* Go to the next thunk */
666 ImageThunk++;
667 }
668
669 /* Go to the next import */
670 ImportDescriptor++;
671 }
672#endif
673 }
674}
static ULONG Delta
Definition: xboxvideo.c:33

Referenced by MiReloadBootLoadedDrivers().

◆ MiUseLargeDriverPage()

LOGICAL NTAPI MiUseLargeDriverPage ( IN ULONG  NumberOfPtes,
IN OUT PVOID ImageBaseAddress,
IN PUNICODE_STRING  BaseImageName,
IN BOOLEAN  BootDriver 
)

Definition at line 2334 of file sysldr.c.

2338{
2339 PLIST_ENTRY NextEntry;
2340 BOOLEAN DriverFound = FALSE;
2341 PMI_LARGE_PAGE_DRIVER_ENTRY LargePageDriverEntry;
2343 ASSERT(*ImageBaseAddress >= MmSystemRangeStart);
2344
2345#ifdef _X86_
2346 if (!(KeFeatureBits & KF_LARGE_PAGE)) return FALSE;
2347 if (!(__readcr4() & CR4_PSE)) return FALSE;
2348#endif
2349
2350 /* Make sure there's enough system PTEs for a large page driver */
2352 {
2353 return FALSE;
2354 }
2355
2356 /* This happens if the registry key had a "*" (wildcard) in it */
2357 if (MiLargePageAllDrivers == 0)
2358 {
2359 /* It didn't, so scan the list */
2360 NextEntry = MiLargePageDriverList.Flink;
2361 while (NextEntry != &MiLargePageDriverList)
2362 {
2363 /* Check if the driver name matches */
2364 LargePageDriverEntry = CONTAINING_RECORD(NextEntry,
2366 Links);
2367 if (RtlEqualUnicodeString(BaseImageName,
2368 &LargePageDriverEntry->BaseName,
2369 TRUE))
2370 {
2371 /* Enable large pages for this driver */
2372 DriverFound = TRUE;
2373 break;
2374 }
2375
2376 /* Keep trying */
2377 NextEntry = NextEntry->Flink;
2378 }
2379
2380 /* If we didn't find the driver, it doesn't need large pages */
2381 if (DriverFound == FALSE) return FALSE;
2382 }
2383
2384 /* Nothing to do yet */
2385 DPRINT1("Large pages not supported!\n");
2386 return FALSE;
2387}
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1825
BOOLEAN MiLargePageAllDrivers
Definition: largepag.c:27
LIST_ENTRY MiLargePageDriverList
Definition: largepag.c:26
ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes]
Definition: syspte.c:25
#define CR4_PSE
Definition: ketypes.h:88
#define KF_LARGE_PAGE
Definition: ketypes.h:148
#define MmSystemRangeStart
Definition: mm.h:32
#define PDE_MAPPED_VA
Definition: mm.h:39
ULONG KeFeatureBits
Definition: krnlinit.c:22
Definition: miarm.h:396
UNICODE_STRING BaseName
Definition: miarm.h:398

Referenced by MmLoadSystemImage().

◆ MiWriteProtectSystemImage()

VOID NTAPI MiWriteProtectSystemImage ( _In_ PVOID  ImageBase)

Definition at line 2430 of file sysldr.c.

2432{
2433 PIMAGE_NT_HEADERS NtHeaders;
2434 PIMAGE_SECTION_HEADER SectionHeaders, Section;
2435 ULONG i;
2436 PVOID SectionBase, SectionEnd;
2437 ULONG SectionSize;
2438 ULONG Protection;
2439 PMMPTE FirstPte, LastPte;
2440
2441 /* Check if the registry setting is on or not */
2443 {
2444 /* Ignore section protection */
2445 return;
2446 }
2447
2448 /* Large page mapped images are not supported */
2449 NT_ASSERT(!MI_IS_PHYSICAL_ADDRESS(ImageBase));
2450
2451 /* Session images are not yet supported */
2452 NT_ASSERT(!MI_IS_SESSION_ADDRESS(ImageBase));
2453
2454 /* Get the NT headers */
2455 NtHeaders = RtlImageNtHeader(ImageBase);
2456 if (NtHeaders == NULL)
2457 {
2458 DPRINT1("Failed to get NT headers for image @ %p\n", ImageBase);
2459 return;
2460 }
2461
2462 /* Don't touch NT4 drivers */
2463 if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion < 5) ||
2464 (NtHeaders->OptionalHeader.MajorSubsystemVersion < 5))
2465 {
2466 DPRINT1("Skipping NT 4 driver @ %p\n", ImageBase);
2467 return;
2468 }
2469
2470 /* Get the section headers */
2471 SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
2472
2473 /* Get the base address of the first section */
2474 SectionBase = Add2Ptr(ImageBase, SectionHeaders[0].VirtualAddress);
2475
2476 /* Start protecting the image header as R/W */
2477 FirstPte = MiAddressToPte(ImageBase);
2478 LastPte = MiAddressToPte(SectionBase) - 1;
2480 if (LastPte >= FirstPte)
2481 {
2482 MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2483 }
2484
2485 /* Loop the sections */
2486 for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
2487 {
2488 /* Get the section base address and size */
2489 Section = &SectionHeaders[i];
2490 SectionBase = Add2Ptr(ImageBase, Section->VirtualAddress);
2491 SectionSize = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2492
2493 /* Get the first PTE of this section */
2494 FirstPte = MiAddressToPte(SectionBase);
2495
2496 /* Check for overlap with the previous range */
2497 if (FirstPte == LastPte)
2498 {
2499 /* Combine the old and new protection by ORing them */
2500 Protection |= (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2501
2502 /* Update the protection for this PTE */
2503 MiSetSystemCodeProtection(FirstPte, FirstPte, Protection);
2504
2505 /* Skip this PTE */
2506 FirstPte++;
2507 }
2508
2509 /* There can not be gaps! */
2510 NT_ASSERT(FirstPte == (LastPte + 1));
2511
2512 /* Get the end of the section and the last PTE */
2513 SectionEnd = Add2Ptr(SectionBase, SectionSize - 1);
2514 NT_ASSERT(SectionEnd < Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage));
2515 LastPte = MiAddressToPte(SectionEnd);
2516
2517 /* If there are no more pages (after an overlap), skip this section */
2518 if (LastPte < FirstPte)
2519 {
2520 NT_ASSERT(FirstPte == (LastPte + 1));
2521 continue;
2522 }
2523
2524 /* Get the section protection */
2525 Protection = (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2526
2527 /* Update the protection for this section */
2528 MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2529 }
2530
2531 /* Image should end with the last section */
2532 if (ALIGN_UP_POINTER_BY(SectionEnd, PAGE_SIZE) !=
2533 Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage))
2534 {
2535 DPRINT1("ImageBase 0x%p ImageSize 0x%lx Section %u VA 0x%lx Raw 0x%lx virt 0x%lx\n",
2536 ImageBase,
2537 NtHeaders->OptionalHeader.SizeOfImage,
2538 i,
2539 Section->VirtualAddress,
2540 Section->SizeOfRawData,
2541 Section->Misc.VirtualSize);
2542 }
2543}
#define Add2Ptr(PTR, INC)
#define IMAGE_SCN_PROTECTION_MASK
Definition: miarm.h:160
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
WORD MajorOperatingSystemVersion
Definition: ntddk_ex.h:160
BOOLEAN MmEnforceWriteProtection
Definition: sysldr.c:34
VOID NTAPI MiSetSystemCodeProtection(_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
Definition: sysldr.c:2391
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by MmInitSystem(), and MmLoadSystemImage().

◆ MmCallDllInitialize()

NTSTATUS NTAPI MmCallDllInitialize ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry,
IN PLIST_ENTRY  ListHead 
)

Definition at line 295 of file sysldr.c.

297{
299 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
300 PMM_DLL_INITIALIZE DllInit;
301 UNICODE_STRING RegPath, ImportName;
303
304 /* Try to see if the image exports a DllInitialize routine */
305 DllInit = (PMM_DLL_INITIALIZE)MiLocateExportName(LdrEntry->DllBase,
306 "DllInitialize");
307 if (!DllInit) return STATUS_SUCCESS;
308
309 /*
310 * Do a temporary copy of BaseDllName called ImportName
311 * because we'll alter the length of the string.
312 */
313 ImportName.Length = LdrEntry->BaseDllName.Length;
314 ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
315 ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
316
317 /* Obtain the path to this dll's service in the registry */
318 RegPath.MaximumLength = ServicesKeyName.Length +
319 ImportName.Length + sizeof(UNICODE_NULL);
321 RegPath.MaximumLength,
323
324 /* Check if this allocation was unsuccessful */
325 if (!RegPath.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
326
327 /* Build and append the service name itself */
328 RegPath.Length = ServicesKeyName.Length;
329 RtlCopyMemory(RegPath.Buffer,
330 ServicesKeyName.Buffer,
331 ServicesKeyName.Length);
332
333 /* Check if there is a dot in the filename */
334 if (wcschr(ImportName.Buffer, L'.'))
335 {
336 /* Remove the extension */
337 ImportName.Length = (USHORT)(wcschr(ImportName.Buffer, L'.') -
338 ImportName.Buffer) * sizeof(WCHAR);
339 }
340
341 /* Append service name (the basename without extension) */
342 RtlAppendUnicodeStringToString(&RegPath, &ImportName);
343
344 /* Now call the DllInit func */
345 DPRINT("Calling DllInit(%wZ)\n", &RegPath);
346 Status = DllInit(&RegPath);
347
348 /* Clean up */
350
351 /* Return status value which DllInitialize returned */
352 return Status;
353}
#define wcschr
Definition: compat.h:17
static const WCHAR ServicesKeyName[]
Definition: driver.c:32
NTSTATUS(NTAPI * PMM_DLL_INITIALIZE)(_In_ PUNICODE_STRING RegistryPath)
Definition: iotypes.h:2850

Referenced by IopInitializeBootDrivers(), and MiResolveImageReferences().

◆ MmChangeKernelResourceSectionProtection()

BOOLEAN NTAPI MmChangeKernelResourceSectionProtection ( IN ULONG_PTR  ProtectionMask)

Definition at line 2280 of file sysldr.c.

2281{
2282 PMMPTE PointerPte;
2283 MMPTE TempPte;
2284
2285 /* Don't do anything if the resource section is already writable */
2287 return FALSE;
2288
2289 /* If the resource section is physical, we cannot change its protection */
2291 return FALSE;
2292
2293 /* Loop the PTEs */
2294 for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2295 {
2296 /* Read the PTE */
2297 TempPte = *PointerPte;
2298
2299 /* Update the protection */
2300 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2301 MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2302 }
2303
2304 /* Only flush the current processor's TLB */
2306 return TRUE;
2307}
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:773
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:347

Referenced by DisplayBootBitmap(), and MmMakeKernelResourceSectionWritable().

◆ MmCheckSystemImage()

NTSTATUS NTAPI MmCheckSystemImage ( IN HANDLE  ImageHandle,
IN BOOLEAN  PurgeSection 
)

Definition at line 2694 of file sysldr.c.

2696{
2698 HANDLE SectionHandle;
2699 PVOID ViewBase = NULL;
2700 SIZE_T ViewSize = 0;
2702 FILE_STANDARD_INFORMATION FileStandardInfo;
2704 PIMAGE_NT_HEADERS NtHeaders;
2706 PAGED_CODE();
2707
2708 /* Setup the object attributes */
2710 NULL,
2712 NULL,
2713 NULL);
2714
2715 /* Create a section for the DLL */
2716 Status = ZwCreateSection(&SectionHandle,
2719 NULL,
2721 SEC_IMAGE,
2722 ImageHandle);
2723 if (!NT_SUCCESS(Status))
2724 {
2725 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2726 return Status;
2727 }
2728
2729 /* Make sure we're in the system process */
2731
2732 /* Map it */
2733 Status = ZwMapViewOfSection(SectionHandle,
2735 &ViewBase,
2736 0,
2737 0,
2738 NULL,
2739 &ViewSize,
2740 ViewShare,
2741 0,
2742 PAGE_EXECUTE);
2743 if (!NT_SUCCESS(Status))
2744 {
2745 /* We failed, close the handle and return */
2746 DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2748 ZwClose(SectionHandle);
2749 return Status;
2750 }
2751
2752 /* Now query image information */
2753 Status = ZwQueryInformationFile(ImageHandle,
2755 &FileStandardInfo,
2756 sizeof(FileStandardInfo),
2758 if (NT_SUCCESS(Status))
2759 {
2760 /* First, verify the checksum */
2762 ViewSize,
2763 FileStandardInfo.
2764 EndOfFile.LowPart))
2765 {
2766 /* Set checksum failure */
2768 goto Fail;
2769 }
2770
2771 /* Make sure it's a real image */
2772 NtHeaders = RtlImageNtHeader(ViewBase);
2773 if (!NtHeaders)
2774 {
2775 /* Set checksum failure */
2777 goto Fail;
2778 }
2779
2780 /* Make sure it's for the correct architecture */
2781 if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2783 {
2784 /* Set protection failure */
2786 goto Fail;
2787 }
2788
2789 /* Check that it's a valid SMP image if we have more then one CPU */
2790 if (!MmVerifyImageIsOkForMpUse(ViewBase))
2791 {
2792 /* Otherwise it's not the right image */
2794 }
2795 }
2796
2797 /* Unmap the section, close the handle, and return status */
2798Fail:
2799 ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2801 ZwClose(SectionHandle);
2802 return Status;
2803}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
int Fail
Definition: ehthrow.cxx:24
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define SEC_IMAGE
Definition: mmtypes.h:96
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewShare
Definition: nt_native.h:1278
#define IMAGE_NT_OPTIONAL_HDR_MAGIC
Definition: ntimage.h:387
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:677
#define STATUS_IMAGE_MP_UP_MISMATCH
Definition: ntstatus.h:717
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:540
#define FileStandardInformation
Definition: propsheet.cpp:61
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
Definition: sysldr.c:2670

Referenced by MmLoadSystemImage(), and PsLocateSystemDll().

◆ MmFreeDriverInitialization()

VOID NTAPI MmFreeDriverInitialization ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1622 of file sysldr.c.

1623{
1624 PMMPTE StartPte, EndPte;
1625 PFN_NUMBER PageCount;
1626 PVOID DllBase;
1627 ULONG i;
1628 PIMAGE_NT_HEADERS NtHeader;
1629 PIMAGE_SECTION_HEADER Section, DiscardSection;
1630
1631 /* Get the base address and the page count */
1632 DllBase = LdrEntry->DllBase;
1633 PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT;
1634
1635 /* Get the last PTE in this image */
1636 EndPte = MiAddressToPte(DllBase) + PageCount;
1637
1638 /* Get the NT header */
1639 NtHeader = RtlImageNtHeader(DllBase);
1640 if (!NtHeader) return;
1641
1642 /* Get the last section and loop each section backwards */
1643 Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections;
1644 DiscardSection = NULL;
1645 for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
1646 {
1647 /* Go back a section and check if it's discardable */
1648 Section--;
1650 {
1651 /* It is, select it for freeing */
1652 DiscardSection = Section;
1653 }
1654 else
1655 {
1656 /* No more discardable sections exist, bail out */
1657 break;
1658 }
1659 }
1660
1661 /* Bail out if there's nothing to free */
1662 if (!DiscardSection) return;
1663
1664 /* Push the DLL base to the first disacrable section, and get its PTE */
1665 DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress);
1666 ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE);
1667 StartPte = MiAddressToPte(DllBase);
1668
1669 /* Check how many pages to free total */
1670 PageCount = (PFN_NUMBER)(EndPte - StartPte);
1671 if (!PageCount) return;
1672
1673 /* Delete this many PTEs */
1674 MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL);
1675}

Referenced by IopInitializeDriverModule().

◆ MmGetSystemRoutineAddress()

PVOID NTAPI MmGetSystemRoutineAddress ( IN PUNICODE_STRING  SystemRoutineName)

Definition at line 3551 of file sysldr.c.

3552{
3553 PVOID ProcAddress = NULL;
3554 ANSI_STRING AnsiRoutineName;
3556 PLIST_ENTRY NextEntry;
3557 PLDR_DATA_TABLE_ENTRY LdrEntry;
3559 UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
3561 ULONG Modules = 0;
3562
3563 /* Convert routine to ANSI name */
3564 Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
3565 SystemRoutineName,
3566 TRUE);
3567 if (!NT_SUCCESS(Status)) return NULL;
3568
3569 /* Lock the list */
3572
3573 /* Loop the loaded module list */
3574 NextEntry = PsLoadedModuleList.Flink;
3575 while (NextEntry != &PsLoadedModuleList)
3576 {
3577 /* Get the entry */
3578 LdrEntry = CONTAINING_RECORD(NextEntry,
3580 InLoadOrderLinks);
3581
3582 /* Check if it's the kernel or HAL */
3583 if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
3584 {
3585 /* Found it */
3586 Found = TRUE;
3587 Modules++;
3588 }
3589 else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
3590 {
3591 /* Found it */
3592 Found = TRUE;
3593 Modules++;
3594 }
3595
3596 /* Check if we found a valid binary */
3597 if (Found)
3598 {
3599 /* Find the procedure name */
3600 ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,
3601 &AnsiRoutineName);
3602
3603 /* Break out if we found it or if we already tried both modules */
3604 if (ProcAddress) break;
3605 if (Modules == 2) break;
3606 }
3607
3608 /* Keep looping */
3609 NextEntry = NextEntry->Flink;
3610 }
3611
3612 /* Release the lock */
3615
3616 /* Free the string and return */
3617 RtlFreeAnsiString(&AnsiRoutineName);
3618 return ProcAddress;
3619}
return Found
Definition: dirsup.c:1270
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
PVOID NTAPI MiFindExportedRoutineByName(IN PVOID DllBase, IN PANSI_STRING ExportName)
Definition: sysldr.c:477

Referenced by _Function_class_(), AuxKlibInitialize(), FxInitializeBugCheckDriverInfo(), FxLibraryCommonCommission(), FxLibraryGlobalsCommission(), FxRegisterBugCheckCallback(), FxRegistrySettingsInitialize(), FxUninitializeBugCheckDriverInfo(), FxUnregisterBugCheckCallback(), KmtGetSystemRoutineAddress(), Mx::MxGetSystemRoutineAddress(), ParaNdis_DebugInitialize(), _FX_DRIVER_TRACKER_CACHE_AWARE::Register(), TestPrivateFunctions(), and WdmlibRtlIsNtDdiVersionAvailable().

◆ MmLoadSystemImage()

NTSTATUS NTAPI MmLoadSystemImage ( IN PUNICODE_STRING  FileName,
IN PUNICODE_STRING NamePrefix  OPTIONAL,
IN PUNICODE_STRING LoadedName  OPTIONAL,
IN ULONG  Flags,
OUT PVOID ModuleObject,
OUT PVOID ImageBaseAddress 
)

Definition at line 2885 of file sysldr.c.

2891{
2892 PVOID ModuleLoadBase = NULL;
2897 PIMAGE_NT_HEADERS NtHeader;
2898 UNICODE_STRING BaseName, BaseDirectory, PrefixName;
2899 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
2900 ULONG EntrySize, DriverSize;
2901 PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
2902 PCHAR MissingApiName, Buffer;
2903 PWCHAR MissingDriverName, PrefixedBuffer = NULL;
2904 HANDLE SectionHandle;
2906 PSECTION Section = NULL;
2907 BOOLEAN LockOwned = FALSE;
2908 PLIST_ENTRY NextEntry;
2909 IMAGE_INFO ImageInfo;
2910
2911 PAGED_CODE();
2912
2913 /* Detect session-load */
2914 if (Flags)
2915 {
2916 /* Sanity checks */
2917 ASSERT(NamePrefix == NULL);
2918 ASSERT(LoadedName == NULL);
2919
2920 /* Make sure the process is in session too */
2921 if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
2922 }
2923
2924 /* Allocate a buffer we'll use for names */
2927 TAG_LDR_WSTR);
2929
2930 /* Check for a separator */
2931 if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2932 {
2933 PWCHAR p;
2934 ULONG BaseLength;
2935
2936 /* Loop the path until we get to the base name */
2937 p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
2938 while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
2939
2940 /* Get the length */
2941 BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
2942 BaseLength *= sizeof(WCHAR);
2943
2944 /* Setup the string */
2945 BaseName.Length = (USHORT)BaseLength;
2946 BaseName.Buffer = p;
2947 }
2948 else
2949 {
2950 /* Otherwise, we already have a base name */
2951 BaseName.Length = FileName->Length;
2952 BaseName.Buffer = FileName->Buffer;
2953 }
2954
2955 /* Setup the maximum length */
2956 BaseName.MaximumLength = BaseName.Length;
2957
2958 /* Now compute the base directory */
2959 BaseDirectory = *FileName;
2960 BaseDirectory.Length -= BaseName.Length;
2961 BaseDirectory.MaximumLength = BaseDirectory.Length;
2962
2963 /* And the prefix, which for now is just the name itself */
2964 PrefixName = *FileName;
2965
2966 /* Check if we have a prefix */
2967 if (NamePrefix)
2968 {
2969 /* Check if "directory + prefix" is too long for the string */
2970 Status = RtlUShortAdd(BaseDirectory.Length,
2971 NamePrefix->Length,
2972 &PrefixName.MaximumLength);
2973 if (!NT_SUCCESS(Status))
2974 {
2976 goto Quickie;
2977 }
2978
2979 /* Check if "directory + prefix + basename" is too long for the string */
2980 Status = RtlUShortAdd(PrefixName.MaximumLength,
2981 BaseName.Length,
2982 &PrefixName.MaximumLength);
2983 if (!NT_SUCCESS(Status))
2984 {
2986 goto Quickie;
2987 }
2988
2989 /* Allocate the buffer exclusively used for prefixed name */
2990 PrefixedBuffer = ExAllocatePoolWithTag(PagedPool,
2991 PrefixName.MaximumLength,
2992 TAG_LDR_WSTR);
2993 if (!PrefixedBuffer)
2994 {
2996 goto Quickie;
2997 }
2998
2999 /* Clear out the prefixed name string */
3000 PrefixName.Buffer = PrefixedBuffer;
3001 PrefixName.Length = 0;
3002
3003 /* Concatenate the strings */
3004 RtlAppendUnicodeStringToString(&PrefixName, &BaseDirectory);
3005 RtlAppendUnicodeStringToString(&PrefixName, NamePrefix);
3006 RtlAppendUnicodeStringToString(&PrefixName, &BaseName);
3007
3008 /* Now the base name of the image becomes the prefixed version */
3009 BaseName.Buffer = &(PrefixName.Buffer[BaseDirectory.Length / sizeof(WCHAR)]);
3010 BaseName.Length += NamePrefix->Length;
3011 BaseName.MaximumLength = (PrefixName.MaximumLength - BaseDirectory.Length);
3012 }
3013
3014 /* Check if we already have a name, use it instead */
3015 if (LoadedName) BaseName = *LoadedName;
3016
3017 /* Check for loader snap debugging */
3019 {
3020 /* Print out standard string */
3021 DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
3022 &PrefixName, &BaseName, Flags ? "in session space" : "");
3023 }
3024
3025 /* Acquire the load lock */
3026LoaderScan:
3027 ASSERT(LockOwned == FALSE);
3028 LockOwned = TRUE;
3032 KernelMode,
3033 FALSE,
3034 NULL);
3035
3036 /* Scan the module list */
3037 NextEntry = PsLoadedModuleList.Flink;
3038 while (NextEntry != &PsLoadedModuleList)
3039 {
3040 /* Get the entry and compare the names */
3041 LdrEntry = CONTAINING_RECORD(NextEntry,
3043 InLoadOrderLinks);
3044 if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
3045 {
3046 /* Found it, break out */
3047 break;
3048 }
3049
3050 /* Keep scanning */
3051 NextEntry = NextEntry->Flink;
3052 }
3053
3054 /* Check if we found the image */
3055 if (NextEntry != &PsLoadedModuleList)
3056 {
3057 /* Check if we had already mapped a section */
3058 if (Section)
3059 {
3060 /* Dereference and clear */
3061 ObDereferenceObject(Section);
3062 Section = NULL;
3063 }
3064
3065 /* Check if this was supposed to be a session load */
3066 if (!Flags)
3067 {
3068 /* It wasn't, so just return the data */
3069 *ModuleObject = LdrEntry;
3070 *ImageBaseAddress = LdrEntry->DllBase;
3072 }
3073 else
3074 {
3075 /* We don't support session loading yet */
3076 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3078 }
3079
3080 /* Do cleanup */
3081 goto Quickie;
3082 }
3083 else if (!Section)
3084 {
3085 /* It wasn't loaded, and we didn't have a previous attempt */
3088 LockOwned = FALSE;
3089
3090 /* Check if KD is enabled */
3092 {
3093 /* FIXME: Attempt to get image from KD */
3094 }
3095
3096 /* We don't have a valid entry */
3097 LdrEntry = NULL;
3098
3099 /* Setup image attributes */
3101 FileName,
3103 NULL,
3104 NULL);
3105
3106 /* Open the image */
3112 0);
3113 if (!NT_SUCCESS(Status))
3114 {
3115 DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
3116 FileName, Status);
3117 goto Quickie;
3118 }
3119
3120 /* Validate it */
3125 {
3126 /* Fail loading */
3127 goto Quickie;
3128 }
3129
3130 /* Check if this is a session-load */
3131 if (Flags)
3132 {
3133 /* Then we only need read and execute */
3135 }
3136 else
3137 {
3138 /* Otherwise, we can allow write access */
3140 }
3141
3142 /* Initialize the attributes for the section */
3144 NULL,
3146 NULL,
3147 NULL);
3148
3149 /* Create the section */
3150 Status = ZwCreateSection(&SectionHandle,
3153 NULL,
3155 SEC_IMAGE,
3156 FileHandle);
3157 if (!NT_SUCCESS(Status))
3158 {
3159 DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
3160 goto Quickie;
3161 }
3162
3163 /* Now get the section pointer */
3164 Status = ObReferenceObjectByHandle(SectionHandle,
3167 KernelMode,
3168 (PVOID*)&Section,
3169 NULL);
3170 ZwClose(SectionHandle);
3171 if (!NT_SUCCESS(Status)) goto Quickie;
3172
3173 /* Check if this was supposed to be a session-load */
3174 if (Flags)
3175 {
3176 /* We don't support session loading yet */
3177 UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3178 goto Quickie;
3179 }
3180
3181 /* Check the loader list again, we should end up in the path below */
3182 goto LoaderScan;
3183 }
3184 else
3185 {
3186 /* We don't have a valid entry */
3187 LdrEntry = NULL;
3188 }
3189
3190 /* Load the image */
3191 Status = MiLoadImageSection(&Section,
3192 &ModuleLoadBase,
3193 FileName,
3194 FALSE,
3195 NULL);
3197
3198 /* Get the size of the driver */
3199 DriverSize = ((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize;
3200
3201 /* Make sure we're not being loaded into session space */
3202 if (!Flags)
3203 {
3204 /* Check for success */
3205 if (NT_SUCCESS(Status))
3206 {
3207 /* Support large pages for drivers */
3208 MiUseLargeDriverPage(DriverSize / PAGE_SIZE,
3209 &ModuleLoadBase,
3210 &BaseName,
3211 TRUE);
3212 }
3213
3214 /* Dereference the section */
3215 ObDereferenceObject(Section);
3216 Section = NULL;
3217 }
3218
3219 /* Check for failure of the load earlier */
3220 if (!NT_SUCCESS(Status))
3221 {
3222 DPRINT1("MiLoadImageSection failed with status 0x%x\n", Status);
3223 goto Quickie;
3224 }
3225
3226 /* Relocate the driver */
3227 Status = LdrRelocateImageWithBias(ModuleLoadBase,
3228 0,
3229 "SYSLDR",
3233 if (!NT_SUCCESS(Status))
3234 {
3235 DPRINT1("LdrRelocateImageWithBias failed with status 0x%x\n", Status);
3236 goto Quickie;
3237 }
3238
3239 /* Get the NT Header */
3240 NtHeader = RtlImageNtHeader(ModuleLoadBase);
3241
3242 /* Calculate the size we'll need for the entry and allocate it */
3244 BaseName.Length +
3245 sizeof(UNICODE_NULL);
3246
3247 /* Allocate the entry */
3249 if (!LdrEntry)
3250 {
3251 /* Fail */
3253 goto Quickie;
3254 }
3255
3256 /* Setup the entry */
3257 LdrEntry->Flags = LDRP_LOAD_IN_PROGRESS;
3258 LdrEntry->LoadCount = 1;
3259 LdrEntry->LoadedImports = LoadedImports;
3260 LdrEntry->PatchInformation = NULL;
3261
3262 /* Check the version */
3263 if ((NtHeader->OptionalHeader.MajorOperatingSystemVersion >= 5) &&
3264 (NtHeader->OptionalHeader.MajorImageVersion >= 5))
3265 {
3266 /* Mark this image as a native image */
3267 LdrEntry->Flags |= LDRP_ENTRY_NATIVE;
3268 }
3269
3270 /* Setup the rest of the entry */
3271 LdrEntry->DllBase = ModuleLoadBase;
3272 LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)ModuleLoadBase +
3274 LdrEntry->SizeOfImage = DriverSize;
3275 LdrEntry->CheckSum = NtHeader->OptionalHeader.CheckSum;
3276 LdrEntry->SectionPointer = Section;
3277
3278 /* Now write the DLL name */
3279 LdrEntry->BaseDllName.Buffer = (PVOID)(LdrEntry + 1);
3280 LdrEntry->BaseDllName.Length = BaseName.Length;
3281 LdrEntry->BaseDllName.MaximumLength = BaseName.Length;
3282
3283 /* Copy and null-terminate it */
3285 BaseName.Buffer,
3286 BaseName.Length);
3287 LdrEntry->BaseDllName.Buffer[BaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3288
3289 /* Now allocate the full name */
3291 PrefixName.Length +
3292 sizeof(UNICODE_NULL),
3293 TAG_LDR_WSTR);
3294 if (!LdrEntry->FullDllName.Buffer)
3295 {
3296 /* Don't fail, just set it to zero */
3297 LdrEntry->FullDllName.Length = 0;
3298 LdrEntry->FullDllName.MaximumLength = 0;
3299 }
3300 else
3301 {
3302 /* Set it up */
3303 LdrEntry->FullDllName.Length = PrefixName.Length;
3304 LdrEntry->FullDllName.MaximumLength = PrefixName.Length;
3305
3306 /* Copy and null-terminate */
3308 PrefixName.Buffer,
3309 PrefixName.Length);
3310 LdrEntry->FullDllName.Buffer[PrefixName.Length / sizeof(WCHAR)] = UNICODE_NULL;
3311 }
3312
3313 /* Add the entry */
3314 MiProcessLoaderEntry(LdrEntry, TRUE);
3315
3316 /* Resolve imports */
3317 MissingApiName = Buffer;
3318 MissingDriverName = NULL;
3319 Status = MiResolveImageReferences(ModuleLoadBase,
3320 &BaseDirectory,
3321 NULL,
3322 &MissingApiName,
3323 &MissingDriverName,
3324 &LoadedImports);
3325 if (!NT_SUCCESS(Status))
3326 {
3327 BOOLEAN NeedToFreeString = FALSE;
3328
3329 /* If the lowest bit is set to 1, this is a hint that we need to free */
3330 if (*(ULONG_PTR*)&MissingDriverName & 1)
3331 {
3332 NeedToFreeString = TRUE;
3333 *(ULONG_PTR*)&MissingDriverName &= ~1;
3334 }
3335
3336 DPRINT1("MiResolveImageReferences failed with status 0x%x\n", Status);
3337 DPRINT1(" Missing driver '%ls', missing API '%s'\n",
3338 MissingDriverName, MissingApiName);
3339
3340 if (NeedToFreeString)
3341 {
3342 ExFreePoolWithTag(MissingDriverName, TAG_LDR_WSTR);
3343 }
3344
3345 /* Fail */
3346 MiProcessLoaderEntry(LdrEntry, FALSE);
3347
3348 /* Check if we need to free the name */
3349 if (LdrEntry->FullDllName.Buffer)
3350 {
3351 /* Free it */
3353 }
3354
3355 /* Free the entry itself */
3357 LdrEntry = NULL;
3358 goto Quickie;
3359 }
3360
3361 /* Update the loader entry */
3362 LdrEntry->Flags |= (LDRP_SYSTEM_MAPPED |
3365 LdrEntry->Flags &= ~LDRP_LOAD_IN_PROGRESS;
3366 LdrEntry->LoadedImports = LoadedImports;
3367
3368 /* FIXME: Call driver verifier's loader function */
3369
3370 /* Write-protect the system image */
3372
3373 /* Initialize the security cookie (Win7 is not doing this yet!) */
3374 LdrpInitSecurityCookie(LdrEntry);
3375
3376 /* Check if notifications are enabled */
3378 {
3379 /* Fill out the notification data */
3380 ImageInfo.Properties = 0;
3382 ImageInfo.SystemModeImage = TRUE;
3383 ImageInfo.ImageSize = LdrEntry->SizeOfImage;
3384 ImageInfo.ImageBase = LdrEntry->DllBase;
3385 ImageInfo.ImageSectionNumber = ImageInfo.ImageSelector = 0;
3386
3387 /* Send the notification */
3389 }
3390
3391#ifdef __ROS_ROSSYM__
3392 /* MiCacheImageSymbols doesn't detect rossym */
3393 if (TRUE)
3394#else
3395 /* Check if there's symbols */
3396 if (MiCacheImageSymbols(LdrEntry->DllBase))
3397#endif
3398 {
3399 UNICODE_STRING UnicodeTemp;
3400 STRING AnsiTemp;
3401
3402 /* Check if the system root is present */
3403 if ((PrefixName.Length > (11 * sizeof(WCHAR))) &&
3404 !(_wcsnicmp(PrefixName.Buffer, L"\\SystemRoot", 11)))
3405 {
3406 /* Add the system root */
3407 UnicodeTemp = PrefixName;
3408 UnicodeTemp.Buffer += 11;
3409 UnicodeTemp.Length -= (11 * sizeof(WCHAR));
3412 "%ws%wZ",
3413 &SharedUserData->NtSystemRoot[2],
3414 &UnicodeTemp);
3415 }
3416 else
3417 {
3418 /* Build the name */
3420 "%wZ", &BaseName);
3421 }
3422
3423 /* Setup the ANSI string */
3424 RtlInitString(&AnsiTemp, Buffer);
3425
3426 /* Notify the debugger */
3427 DbgLoadImageSymbols(&AnsiTemp,
3428 LdrEntry->DllBase,
3430 LdrEntry->Flags |= LDRP_DEBUG_SYMBOLS_LOADED;
3431 }
3432
3433 /* Page the driver */
3434 ASSERT(Section == NULL);
3435 MiEnablePagingOfDriver(LdrEntry);
3436
3437 /* Return pointers */
3438 *ModuleObject = LdrEntry;
3439 *ImageBaseAddress = LdrEntry->DllBase;
3440
3441Quickie:
3442 /* Check if we have the lock acquired */
3443 if (LockOwned)
3444 {
3445 /* Release the lock */
3448 LockOwned = FALSE;
3449 }
3450
3451 /* If we have a file handle, close it */
3453
3454 /* If we have allocated a prefixed name buffer, free it */
3455 if (PrefixedBuffer) ExFreePoolWithTag(PrefixedBuffer, TAG_LDR_WSTR);
3456
3457 /* Free the name buffer and return status */
3459 return Status;
3460}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
Definition: bufpool.h:45
#define SECTION_MAP_READ
Definition: compat.h:139
#define FILE_SHARE_READ
Definition: compat.h:136
struct _FileName FileName
Definition: fatprocs.h:896
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
std::wstring STRING
Definition: fontsub.cpp:33
GLfloat GLfloat p
Definition: glext.h:8902
#define FLG_SHOW_LDR_SNAPS
Definition: pstypes.h:57
#define IMAGE_ADDRESSING_MODE_32BIT
Definition: pstypes.h:194
BOOLEAN KdDebuggerNotPresent
Definition: kddata.c:82
BOOLEAN KdDebuggerEnabled
Definition: kddata.c:83
#define LDRP_DEBUG_SYMBOLS_LOADED
Definition: ldrtypes.h:50
#define LDRP_ENTRY_PROCESSED
Definition: ldrtypes.h:44
#define LDRP_ENTRY_NATIVE
Definition: ldrtypes.h:57
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
VOID NTAPI DbgLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
struct _MM_IMAGE_SECTION_OBJECT * PMM_IMAGE_SECTION_OBJECT
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
#define STATUS_IMAGE_ALREADY_LOADED
Definition: ntstatus.h:506
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:270
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
BOOLEAN PsImageNotifyEnabled
Definition: psnotify.c:18
FORCEINLINE VOID PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
Definition: ps_x.h:84
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define SharedUserData
POBJECT_TYPE MmSectionObjectType
Definition: section.c:195
SIZE_T ImageSize
Definition: pstypes.h:209
ULONG SystemModeImage
Definition: pstypes.h:201
ULONG ImageSectionNumber
Definition: pstypes.h:210
PVOID ImageBase
Definition: pstypes.h:207
ULONG Properties
Definition: pstypes.h:198
ULONG ImageAddressingMode
Definition: pstypes.h:200
ULONG ImageSelector
Definition: pstypes.h:208
PVOID SectionPointer
Definition: ntddk_ex.h:213
ULONG CheckSum
Definition: btrfs_drv.h:1886
PVOID PatchInformation
Definition: ldrtypes.h:164
NTSTATUS NTAPI MiResolveImageReferences(IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
Definition: sysldr.c:987
PVOID NTAPI LdrpInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2848
VOID NTAPI MiWriteProtectSystemImage(_In_ PVOID ImageBase)
Definition: sysldr.c:2430
VOID NTAPI MiEnablePagingOfDriver(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2606
VOID NTAPI MiProcessLoaderEntry(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN BOOLEAN Insert)
Definition: sysldr.c:552
PVOID NTAPI MiCacheImageSymbols(IN PVOID BaseAddress)
Definition: sysldr.c:50
NTSTATUS NTAPI MiLoadImageSection(_Inout_ PSECTION *SectionPtr, _Out_ PVOID *ImageBase, _In_ PUNICODE_STRING FileName, _In_ BOOLEAN SessionLoad, _In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:77
NTSTATUS NTAPI MmCheckSystemImage(IN HANDLE ImageHandle, IN BOOLEAN PurgeSection)
Definition: sysldr.c:2694
LOGICAL NTAPI MiUseLargeDriverPage(IN ULONG NumberOfPtes, IN OUT PVOID *ImageBaseAddress, IN PUNICODE_STRING BaseImageName, IN BOOLEAN BootDriver)
Definition: sysldr.c:2334
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by IopLoadDriver(), MiResolveImageReferences(), and SSI_DEF().

◆ MmMakeKernelResourceSectionWritable()

VOID NTAPI MmMakeKernelResourceSectionWritable ( VOID  )

Definition at line 2311 of file sysldr.c.

2312{
2313 /* Don't do anything if the resource section is already writable */
2315 return;
2316
2317 /* If the resource section is physical, we cannot change its protection */
2319 return;
2320
2322 {
2323 /*
2324 * Invalidate the cached resource section PTEs
2325 * so as to not change its protection again later.
2326 */
2329 }
2330}
#define MM_READWRITE
Definition: bootanim.c:19
BOOLEAN NTAPI MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask)
Definition: sysldr.c:2280

Referenced by KeGetBugMessageText().

◆ MmPageEntireDriver()

PVOID NTAPI MmPageEntireDriver ( IN PVOID  AddressWithinSection)

Definition at line 3504 of file sysldr.c.

3505{
3506 PMMPTE StartPte, EndPte;
3507 PLDR_DATA_TABLE_ENTRY LdrEntry;
3508 PAGED_CODE();
3509
3510 /* Get the loader entry */
3511 LdrEntry = MiLookupDataTableEntry(AddressWithinSection);
3512 if (!LdrEntry) return NULL;
3513
3514 /* Check if paging of kernel mode is disabled or if the driver is mapped as an image */
3515 if ((MmDisablePagingExecutive) || (LdrEntry->SectionPointer))
3516 {
3517 /* Don't do anything, just return the base address */
3518 return LdrEntry->DllBase;
3519 }
3520
3521 /* Wait for active DPCs to finish before we page out the driver */
3523
3524 /* Get the PTE range for the whole driver image */
3525 StartPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase);
3526 EndPte = MiAddressToPte((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage);
3527
3528 /* Enable paging for the PTE range */
3529 ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(AddressWithinSection) == FALSE);
3530 MiSetPagingOfDriver(StartPte, EndPte);
3531
3532 /* Return the base address */
3533 return LdrEntry->DllBase;
3534}
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:919
PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry(IN PVOID Address)
Definition: sysldr.c:3464

Referenced by DriverEntry().

◆ MmResetDriverPaging()

VOID NTAPI MmResetDriverPaging ( IN PVOID  AddressWithinSection)

Definition at line 3541 of file sysldr.c.

3542{
3544}
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmUnloadSystemImage()

NTSTATUS NTAPI MmUnloadSystemImage ( IN PVOID  ImageHandle)

Definition at line 898 of file sysldr.c.

899{
900 PLDR_DATA_TABLE_ENTRY LdrEntry = ImageHandle;
901 PVOID BaseAddress = LdrEntry->DllBase;
903 STRING TempName;
904 BOOLEAN HadEntry = FALSE;
905
906 /* Acquire the loader lock */
911 FALSE,
912 NULL);
913
914 /* Check if this driver was loaded at boot and didn't get imports parsed */
915 if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) goto Done;
916
917 /* We should still be alive */
918 ASSERT(LdrEntry->LoadCount != 0);
919 LdrEntry->LoadCount--;
920
921 /* Check if we're still loaded */
922 if (LdrEntry->LoadCount) goto Done;
923
924 /* We should cleanup... are symbols loaded */
925 if (LdrEntry->Flags & LDRP_DEBUG_SYMBOLS_LOADED)
926 {
927 /* Create the ANSI name */
929 &LdrEntry->BaseDllName,
930 TRUE);
931 if (NT_SUCCESS(Status))
932 {
933 /* Unload the symbols */
934 DbgUnLoadImageSymbols(&TempName,
937 RtlFreeAnsiString(&TempName);
938 }
939 }
940
941 /* FIXME: Free the driver */
942 DPRINT1("Leaking driver: %wZ\n", &LdrEntry->BaseDllName);
943 //MmFreeSection(LdrEntry->DllBase);
944
945 /* Check if we're linked in */
946 if (LdrEntry->InLoadOrderLinks.Flink)
947 {
948 /* Remove us */
949 MiProcessLoaderEntry(LdrEntry, FALSE);
950 HadEntry = TRUE;
951 }
952
953 /* Dereference and clear the imports */
955 MiClearImports(LdrEntry);
956
957 /* Check if the entry needs to go away */
958 if (HadEntry)
959 {
960 /* Check if it had a name */
961 if (LdrEntry->FullDllName.Buffer)
962 {
963 /* Free it */
965 }
966
967 /* Check if we had a section */
968 if (LdrEntry->SectionPointer)
969 {
970 /* Dereference it */
972 }
973
974 /* Free the entry */
976 }
977
978 /* Release the system lock and return */
979Done:
982 return STATUS_SUCCESS;
983}
VOID NTAPI DbgUnLoadImageSymbols(_In_ PSTRING Name, _In_ PVOID Base, _In_ ULONG_PTR ProcessId)
VOID NTAPI MiClearImports(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:457

Referenced by IopDeleteDriver(), IopInitializeDriverModule(), LoadSymbolsRoutine(), MiCallDllUnloadAndUnloadDll(), MiResolveImageReferences(), and SSI_DEF().

◆ MmVerifyImageIsOkForMpUse()

BOOLEAN NTAPI MmVerifyImageIsOkForMpUse ( IN PVOID  BaseAddress)

Definition at line 2670 of file sysldr.c.

2671{
2672 PIMAGE_NT_HEADERS NtHeader;
2673 PAGED_CODE();
2674
2675 /* Get NT Headers */
2676 NtHeader = RtlImageNtHeader(BaseAddress);
2677 if (NtHeader)
2678 {
2679 /* Check if this image is only safe for UP while we have 2+ CPUs */
2680 if ((KeNumberProcessors > 1) &&
2682 {
2683 /* Fail */
2684 return FALSE;
2685 }
2686 }
2687
2688 /* Otherwise, it's safe */
2689 return TRUE;
2690}
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define IMAGE_FILE_UP_SYSTEM_ONLY
Definition: pedump.c:170

Referenced by MmCheckSystemImage().

Variable Documentation

◆ ExPoolCodeEnd

ULONG_PTR ExPoolCodeEnd

Definition at line 37 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ ExPoolCodeStart

ULONG_PTR ExPoolCodeStart

Definition at line 37 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MiKernelResourceEndPte

PMMPTE MiKernelResourceEndPte

◆ MiKernelResourceStartPte

PMMPTE MiKernelResourceStartPte

◆ MmEnforceWriteProtection

BOOLEAN MmEnforceWriteProtection = TRUE

Definition at line 34 of file sysldr.c.

Referenced by MiWriteProtectSystemImage().

◆ MmLastUnloadedDrivers

PVOID MmLastUnloadedDrivers

Definition at line 31 of file sysldr.c.

◆ MmLoadedUserImageList

LIST_ENTRY MmLoadedUserImageList

Definition at line 22 of file sysldr.c.

Referenced by MiLoadUserSymbols(), MmArmInitSystem(), and QSI_DEF().

◆ MmMakeLowMemory

BOOLEAN MmMakeLowMemory

Definition at line 33 of file sysldr.c.

◆ MmPoolCodeEnd

ULONG_PTR MmPoolCodeEnd

Definition at line 37 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MmPoolCodeStart

ULONG_PTR MmPoolCodeStart

Definition at line 37 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MmPteCodeEnd

ULONG_PTR MmPteCodeEnd

Definition at line 38 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MmPteCodeStart

ULONG_PTR MmPteCodeStart

Definition at line 38 of file sysldr.c.

Referenced by MiLocateKernelSections().

◆ MmSystemLoadLock

◆ MmTotalSystemDriverPages

PFN_NUMBER MmTotalSystemDriverPages

Definition at line 28 of file sysldr.c.

Referenced by MiSetPagingOfDriver().

◆ MmUnloadedDrivers

PVOID MmUnloadedDrivers

Definition at line 30 of file sysldr.c.

◆ PsLoadedModuleList

◆ PsLoadedModuleResource

◆ PsLoadedModuleSpinLock

KSPIN_LOCK PsLoadedModuleSpinLock

◆ PsNtosImageBase

ULONG_PTR PsNtosImageBase