ReactOS  0.4.15-dev-3297-g037c744
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

static VOID sprintf_nt (IN PCHAR Buffer, IN PCHAR Format, IN ...)
 
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 56 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 2821 of file sysldr.c.

2822 {
2823  PIMAGE_LOAD_CONFIG_DIRECTORY ConfigDir;
2824  ULONG DirSize;
2825  PVOID Cookie = NULL;
2826 
2827  /* Check NT header first */
2828  if (!RtlImageNtHeader(BaseAddress)) return NULL;
2829 
2830  /* Get the pointer to the config directory */
2832  TRUE,
2834  &DirSize);
2835 
2836  /* Check for sanity */
2837  if (!ConfigDir ||
2838  DirSize < FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, SEHandlerTable) || /* SEHandlerTable is after SecurityCookie */
2839  (ConfigDir->Size != DirSize))
2840  {
2841  /* Invalid directory*/
2842  return NULL;
2843  }
2844 
2845  /* Now get the cookie */
2846  Cookie = (PVOID)ConfigDir->SecurityCookie;
2847 
2848  /* Check this cookie */
2849  if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
2850  (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
2851  {
2852  Cookie = NULL;
2853  }
2854 
2855  /* Return validated security cookie */
2856  return Cookie;
2857 }
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
if(dx==0 &&dy==0)
Definition: linetemp.h:174
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
void * PVOID
Definition: retypes.h:9
#define PCHAR
Definition: match.c:90
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
#define RtlImageDirectoryEntryToData
Definition: compat.h:668
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NULL
Definition: types.h:112
#define RtlImageNtHeader
Definition: compat.h:665
unsigned int ULONG
Definition: retypes.h:1

Referenced by LdrpInitSecurityCookie().

◆ LdrpInitSecurityCookie()

PVOID NTAPI LdrpInitSecurityCookie ( PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2861 of file sysldr.c.

2862 {
2864  ULONG_PTR NewCookie;
2865 
2866  /* Fetch address of the cookie */
2868 
2869  if (Cookie)
2870  {
2871  /* Check if it's a default one */
2872  if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
2873  (*Cookie == 0))
2874  {
2876  /* The address should be unique */
2877  NewCookie = (ULONG_PTR)Cookie;
2878 
2879  /* We just need a simple tick, don't care about precision and whatnot */
2880  NewCookie ^= (ULONG_PTR)Counter.LowPart;
2881 
2882  /* If the result is 0 or the same as we got, just add one to the default value */
2883  if ((NewCookie == 0) || (NewCookie == *Cookie))
2884  {
2885  NewCookie = DEFAULT_SECURITY_COOKIE + 1;
2886  }
2887 
2888  /* Set the new cookie value */
2889  *Cookie = NewCookie;
2890  }
2891  }
2892 
2893  return Cookie;
2894 }
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
#define DEFAULT_SECURITY_COOKIE
Definition: sysldr.c:56
ULONG SizeOfImage
Definition: ldrtypes.h:143
if(dx==0 &&dy==0)
Definition: linetemp.h:174
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DllBase
Definition: btrfs_drv.h:1926
PVOID NTAPI LdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
Definition: sysldr.c:2821
_In_opt_ PVOID _Out_ PLARGE_INTEGER Cookie
Definition: cmfuncs.h:13
ULONG LowPart
Definition: typedefs.h:106
#define NULL
Definition: types.h:112
static LARGE_INTEGER Counter
Definition: clock.c:43
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65

Referenced by MmLoadSystemImage().

◆ MiBuildImportsForBootDrivers()

NTSTATUS NTAPI MiBuildImportsForBootDrivers ( VOID  )

Definition at line 1882 of file sysldr.c.

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

Referenced by MiInitializeLoadedModuleList().

◆ MiCacheImageSymbols()

PVOID NTAPI MiCacheImageSymbols ( IN PVOID  BaseAddress)

Definition at line 63 of file sysldr.c.

64 {
65  ULONG DebugSize;
66  PVOID DebugDirectory = NULL;
67  PAGED_CODE();
68 
69  /* Make sure it's safe to access the image */
70  _SEH2_TRY
71  {
72  /* Get the debug directory */
74  TRUE,
76  &DebugSize);
77  }
79  {
80  /* Nothing */
81  }
82  _SEH2_END;
83 
84  /* Return the directory */
85  return DebugDirectory;
86 }
#define TRUE
Definition: types.h:120
_SEH2_TRY
Definition: create.c:4226
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define RtlImageDirectoryEntryToData
Definition: compat.h:668
_SEH2_END
Definition: create.c:4400
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:152
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define PAGED_CODE()

Referenced by MmLoadSystemImage().

◆ MiCallDllUnloadAndUnloadDll()

BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 370 of file sysldr.c.

371 {
374  PAGED_CODE();
375 
376  /* Get the unload routine */
377  Func = (PMM_DLL_UNLOAD)MiLocateExportName(LdrEntry->DllBase, "DllUnload");
378  if (!Func) return FALSE;
379 
380  /* Call it and check for success */
381  Status = Func();
382  if (!NT_SUCCESS(Status)) return FALSE;
383 
384  /* Lie about the load count so we can unload the image */
385  ASSERT(LdrEntry->LoadCount == 0);
386  LdrEntry->LoadCount = 1;
387 
388  /* Unload it and return true */
389  MmUnloadSystemImage(LdrEntry);
390  return TRUE;
391 }
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:911
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS(NTAPI * PMM_DLL_UNLOAD)(VOID)
Definition: iotypes.h:2854
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
void(* Func)(int)
PVOID NTAPI MiLocateExportName(IN PVOID DllBase, IN PCHAR ExportName)
Definition: sysldr.c:231
#define PAGED_CODE()

Referenced by MiDereferenceImports().

◆ MiClearImports()

VOID NTAPI MiClearImports ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 470 of file sysldr.c.

471 {
472  PAGED_CODE();
473 
474  /* Check if there's no imports or we're a boot driver or only one entry */
475  if ((LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) ||
476  (LdrEntry->LoadedImports == MM_SYSLDR_NO_IMPORTS) ||
477  ((ULONG_PTR)LdrEntry->LoadedImports & MM_SYSLDR_SINGLE_ENTRY))
478  {
479  /* Nothing to do */
480  return;
481  }
482 
483  /* Otherwise, free the import list */
484  ExFreePoolWithTag(LdrEntry->LoadedImports, TAG_LDR_IMPORTS);
485  LdrEntry->LoadedImports = MM_SYSLDR_BOOT_LOADED;
486 }
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:207
#define TAG_LDR_IMPORTS
Definition: tag.h:111
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:205
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:204
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by MmUnloadSystemImage().

◆ MiDereferenceImports()

NTSTATUS NTAPI MiDereferenceImports ( IN PLOAD_IMPORTS  ImportList)

Definition at line 395 of file sysldr.c.

396 {
397  SIZE_T i;
398  LOAD_IMPORTS SingleEntry;
399  PLDR_DATA_TABLE_ENTRY LdrEntry;
400  PVOID CurrentImports;
401  PAGED_CODE();
402 
403  /* Check if there's no imports or if we're a boot driver */
404  if ((ImportList == MM_SYSLDR_NO_IMPORTS) ||
405  (ImportList == MM_SYSLDR_BOOT_LOADED) ||
406  (ImportList->Count == 0))
407  {
408  /* Then there's nothing to do */
409  return STATUS_SUCCESS;
410  }
411 
412  /* Check for single-entry */
413  if ((ULONG_PTR)ImportList & MM_SYSLDR_SINGLE_ENTRY)
414  {
415  /* Set it up */
416  SingleEntry.Count = 1;
417  SingleEntry.Entry[0] = (PVOID)((ULONG_PTR)ImportList &~ MM_SYSLDR_SINGLE_ENTRY);
418 
419  /* Use this as the import list */
420  ImportList = &SingleEntry;
421  }
422 
423  /* Loop the import list */
424  for (i = 0; (i < ImportList->Count) && (ImportList->Entry[i]); i++)
425  {
426  /* Get the entry */
427  LdrEntry = ImportList->Entry[i];
428  DPRINT1("%wZ <%wZ>\n", &LdrEntry->FullDllName, &LdrEntry->BaseDllName);
429 
430  /* Skip boot loaded images */
431  if (LdrEntry->LoadedImports == MM_SYSLDR_BOOT_LOADED) continue;
432 
433  /* Dereference the entry */
434  ASSERT(LdrEntry->LoadCount >= 1);
435  if (!--LdrEntry->LoadCount)
436  {
437  /* Save the import data in case unload fails */
438  CurrentImports = LdrEntry->LoadedImports;
439 
440  /* This is the last entry */
442  if (MiCallDllUnloadAndUnloadDll(LdrEntry))
443  {
444  /* Unloading worked, parse this DLL's imports too */
445  MiDereferenceImports(CurrentImports);
446 
447  /* Check if we had valid imports */
448  if ((CurrentImports != MM_SYSLDR_BOOT_LOADED) &&
449  (CurrentImports != MM_SYSLDR_NO_IMPORTS) &&
450  !((ULONG_PTR)CurrentImports & MM_SYSLDR_SINGLE_ENTRY))
451  {
452  /* Free them */
453  ExFreePoolWithTag(CurrentImports, TAG_LDR_IMPORTS);
454  }
455  }
456  else
457  {
458  /* Unload failed, restore imports */
459  LdrEntry->LoadedImports = CurrentImports;
460  }
461  }
462  }
463 
464  /* Done */
465  return STATUS_SUCCESS;
466 }
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:173
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:207
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:395
#define TAG_LDR_IMPORTS
Definition: tag.h:111
uint32_t ULONG_PTR
Definition: typedefs.h:65
void * PVOID
Definition: retypes.h:9
#define ASSERT(a)
Definition: mode.c:44
PVOID LoadedImports
Definition: ldrtypes.h:161
Definition: btrfs_drv.h:1922
BOOLEAN NTAPI MiCallDllUnloadAndUnloadDll(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:370
#define MM_SYSLDR_BOOT_LOADED
Definition: miarm.h:205
SIZE_T Count
Definition: ldrtypes.h:172
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:80
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
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1928
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define DPRINT1
Definition: precomp.h:8
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
USHORT LoadCount
Definition: ntddk_ex.h:208
#define PAGED_CODE()

Referenced by MiResolveImageReferences(), and MmUnloadSystemImage().

◆ MiEnablePagingOfDriver()

VOID NTAPI MiEnablePagingOfDriver ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2619 of file sysldr.c.

2620 {
2621  ULONG_PTR ImageBase;
2622  PIMAGE_NT_HEADERS NtHeaders;
2623  ULONG Sections, Alignment, Size;
2624  PIMAGE_SECTION_HEADER Section;
2625  PMMPTE PointerPte = NULL, LastPte = NULL;
2626  if (MmDisablePagingExecutive) return;
2627 
2628  /* Get the driver base address and its NT header */
2629  ImageBase = (ULONG_PTR)LdrEntry->DllBase;
2630  NtHeaders = RtlImageNtHeader((PVOID)ImageBase);
2631  if (!NtHeaders) return;
2632 
2633  /* Get the sections and their alignment */
2634  Sections = NtHeaders->FileHeader.NumberOfSections;
2635  Alignment = NtHeaders->OptionalHeader.SectionAlignment - 1;
2636 
2637  /* Loop each section */
2638  Section = IMAGE_FIRST_SECTION(NtHeaders);
2639  while (Sections)
2640  {
2641  /* Find PAGE or .edata */
2642  if ((*(PULONG)Section->Name == 'EGAP') ||
2643  (*(PULONG)Section->Name == 'ade.'))
2644  {
2645  /* Had we already done some work? */
2646  if (!PointerPte)
2647  {
2648  /* Nope, setup the first PTE address */
2649  PointerPte = MiAddressToPte(ROUND_TO_PAGES(ImageBase +
2650  Section->VirtualAddress));
2651  }
2652 
2653  /* Compute the size */
2654  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2655 
2656  /* Find the last PTE that maps this section */
2657  LastPte = MiAddressToPte(ImageBase +
2658  Section->VirtualAddress +
2659  Alignment + Size - PAGE_SIZE);
2660  }
2661  else
2662  {
2663  /* Had we found a section before? */
2664  if (PointerPte)
2665  {
2666  /* Mark it as pageable */
2667  MiSetPagingOfDriver(PointerPte, LastPte);
2668  PointerPte = NULL;
2669  }
2670  }
2671 
2672  /* Keep searching */
2673  Sections--;
2674  Section++;
2675  }
2676 
2677  /* Handle the straggler */
2678  if (PointerPte) MiSetPagingOfDriver(PointerPte, LastPte);
2679 }
#define max(a, b)
Definition: svc.c:63
VOID NTAPI MiSetPagingOfDriver(IN PMMPTE PointerPte, IN PMMPTE LastPte)
Definition: sysldr.c:2560
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
union Alignment_ Alignment
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define ROUND_TO_PAGES(Size)
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define RtlImageNtHeader
Definition: compat.h:665
union _IMAGE_SECTION_HEADER::@1510 Misc
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
UCHAR MmDisablePagingExecutive
Definition: mminit.c:25

Referenced by MmLoadSystemImage().

◆ MiFindExportedRoutineByName()

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

Definition at line 490 of file sysldr.c.

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

Referenced by MmGetSystemRoutineAddress().

◆ MiFindInitializationCode()

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

Definition at line 1450 of file sysldr.c.

1452 {
1453  ULONG Size, SectionCount, Alignment;
1454  PLDR_DATA_TABLE_ENTRY LdrEntry;
1455  ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1456  PLIST_ENTRY NextEntry;
1457  PIMAGE_NT_HEADERS NtHeader;
1458  PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1459  BOOLEAN InitFound;
1460  DBG_UNREFERENCED_LOCAL_VARIABLE(InitSection);
1461 
1462  /* So we don't free our own code yet */
1463  InitCode = (ULONG_PTR)&MiFindInitializationCode;
1464 
1465  /* Assume failure */
1466  *StartVa = NULL;
1467 
1468  /* Acquire the necessary locks while we loop the list */
1472  KernelMode,
1473  FALSE,
1474  NULL);
1476 
1477  /* Loop all loaded modules */
1478  NextEntry = PsLoadedModuleList.Flink;
1479  while (NextEntry != &PsLoadedModuleList)
1480  {
1481  /* Get the loader entry and its DLL base */
1482  LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1483  DllBase = (ULONG_PTR)LdrEntry->DllBase;
1484 
1485  /* Only process boot loaded images. Other drivers are processed by
1486  MmFreeDriverInitialization */
1487  if (LdrEntry->Flags & LDRP_MM_LOADED)
1488  {
1489  /* Keep going */
1490  NextEntry = NextEntry->Flink;
1491  continue;
1492  }
1493 
1494  /* Get the NT header */
1495  NtHeader = RtlImageNtHeader((PVOID)DllBase);
1496  if (!NtHeader)
1497  {
1498  /* Keep going */
1499  NextEntry = NextEntry->Flink;
1500  continue;
1501  }
1502 
1503  /* Get the first section, the section count, and scan them all */
1504  Section = IMAGE_FIRST_SECTION(NtHeader);
1505  SectionCount = NtHeader->FileHeader.NumberOfSections;
1506  InitStart = 0;
1507  while (SectionCount > 0)
1508  {
1509  /* Assume failure */
1510  InitFound = FALSE;
1511 
1512  /* Is this the INIT section or a discardable section? */
1513  if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1515  {
1516  /* Remember this */
1517  InitFound = TRUE;
1518  InitSection = Section;
1519  }
1520 
1521  if (InitFound)
1522  {
1523  /* Pick the biggest size -- either raw or virtual */
1524  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1525 
1526  /* Read the section alignment */
1528 
1529  /* Get the start and end addresses */
1530  InitStart = DllBase + Section->VirtualAddress;
1531  InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1532 
1533  /* Align the addresses to PAGE_SIZE */
1534  InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1535  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1536 
1537  /* Have we reached the last section? */
1538  if (SectionCount == 1)
1539  {
1540  /* Remember this */
1541  LastSection = Section;
1542  }
1543  else
1544  {
1545  /* We have not, loop all the sections */
1546  LastSection = NULL;
1547  do
1548  {
1549  /* Keep going until we find a non-discardable section range */
1550  SectionCount--;
1551  Section++;
1553  {
1554  /* Discardable, so record it, then keep going */
1555  LastSection = Section;
1556  }
1557  else
1558  {
1559  /* Non-contigous discard flag, or no flag, break out */
1560  break;
1561  }
1562  }
1563  while (SectionCount > 1);
1564  }
1565 
1566  /* Have we found a discardable or init section? */
1567  if (LastSection)
1568  {
1569  /* Pick the biggest size -- either raw or virtual */
1570  Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1571 
1572  /* Use this as the end of the section address */
1573  InitEnd = DllBase + LastSection->VirtualAddress + Size;
1574 
1575  /* Have we reached the last section yet? */
1576  if (SectionCount != 1)
1577  {
1578  /* Then align this accross the session boundary */
1579  InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1580  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1581  }
1582  }
1583 
1584  /* Make sure we don't let the init section go past the image */
1585  ImageEnd = DllBase + LdrEntry->SizeOfImage;
1586  if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1587 
1588  /* Make sure we have a valid, non-zero init section */
1589  if (InitStart < InitEnd)
1590  {
1591  /* Make sure we are not within this code itself */
1592  if ((InitCode >= InitStart) && (InitCode < InitEnd))
1593  {
1594  /* Return it, we can't free ourselves now */
1595  ASSERT(*StartVa == 0);
1596  *StartVa = (PVOID)InitStart;
1597  *EndVa = (PVOID)InitEnd;
1598  }
1599  else
1600  {
1601  /* This isn't us -- go ahead and free it */
1602  ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1603  DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1604  (PVOID)InitStart,
1605  (PVOID)InitEnd,
1606  &LdrEntry->BaseDllName,
1607  LdrEntry->DllBase,
1608  InitSection->Name);
1609  MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1610  }
1611  }
1612  }
1613 
1614  /* Move to the next section */
1615  SectionCount--;
1616  Section++;
1617  }
1618 
1619  /* Move to the next module */
1620  NextEntry = NextEntry->Flink;
1621  }
1622 
1623  /* Release the locks and return */
1627 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
ULONG SizeOfImage
Definition: ldrtypes.h:143
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
if(dx==0 &&dy==0)
Definition: linetemp.h:174
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
PVOID DllBase
Definition: btrfs_drv.h:1926
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1427
#define FALSE
Definition: types.h:117
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
union Alignment_ Alignment
unsigned char BOOLEAN
void * PVOID
Definition: retypes.h:9
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:319
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
CONST CHAR * PCCH
Definition: ntbasedef.h:392
#define ASSERT(a)
Definition: mode.c:44
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
KMUTANT MmSystemLoadLock
Definition: sysldr.c:39
#define MUTANT_INCREMENT
Definition: extypes.h:84
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: btrfs_drv.h:1922
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:119
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define ALIGN_DOWN_BY(size, align)
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define NULL
Definition: types.h:112
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define RtlImageNtHeader
Definition: compat.h:665
union _IMAGE_SECTION_HEADER::@1510 Misc
ULONG Flags
Definition: ntddk_ex.h:207
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define ALIGN_UP_BY(size, align)
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1450
#define LDRP_MM_LOADED
Definition: ldrtypes.h:60
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiFreeInitializationCode()

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

Definition at line 1427 of file sysldr.c.

1429 {
1430  PMMPTE PointerPte;
1431  PFN_NUMBER PagesFreed;
1432 
1433  /* Get the start PTE */
1434  PointerPte = MiAddressToPte(InitStart);
1435  ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1436 
1437  /* Compute the number of pages we expect to free */
1438  PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1439 
1440  /* Try to actually free them */
1441  PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1442  PagesFreed,
1443  0,
1444  NULL);
1445 }
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
#define NULL
Definition: types.h:112
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiInitializeLoadedModuleList()

BOOLEAN NTAPI MiInitializeLoadedModuleList ( IN PLOADER_PARAMETER_BLOCK  LoaderBlock)

Definition at line 2204 of file sysldr.c.

2205 {
2206  PLDR_DATA_TABLE_ENTRY LdrEntry, NewEntry;
2207  PLIST_ENTRY ListHead, NextEntry;
2208  ULONG EntrySize;
2209 
2210  /* Setup the loaded module list and locks */
2214 
2215  /* Get loop variables and the kernel entry */
2216  ListHead = &LoaderBlock->LoadOrderListHead;
2217  NextEntry = ListHead->Flink;
2218  LdrEntry = CONTAINING_RECORD(NextEntry,
2220  InLoadOrderLinks);
2221  PsNtosImageBase = (ULONG_PTR)LdrEntry->DllBase;
2222 
2223  /* Locate resource section, pool code, and system pte code */
2224  MiLocateKernelSections(LdrEntry);
2225 
2226  /* Loop the loader block */
2227  while (NextEntry != ListHead)
2228  {
2229  /* Get the loader entry */
2230  LdrEntry = CONTAINING_RECORD(NextEntry,
2232  InLoadOrderLinks);
2233 
2234  /* FIXME: ROS HACK. Make sure this is a driver */
2235  if (!RtlImageNtHeader(LdrEntry->DllBase))
2236  {
2237  /* Skip this entry */
2238  NextEntry = NextEntry->Flink;
2239  continue;
2240  }
2241 
2242  /* Calculate the size we'll need and allocate a copy */
2243  EntrySize = sizeof(LDR_DATA_TABLE_ENTRY) +
2244  LdrEntry->BaseDllName.MaximumLength +
2245  sizeof(UNICODE_NULL);
2247  if (!NewEntry) return FALSE;
2248 
2249  /* Copy the entry over */
2250  *NewEntry = *LdrEntry;
2251 
2252  /* Allocate the name */
2253  NewEntry->FullDllName.Buffer =
2255  LdrEntry->FullDllName.MaximumLength +
2256  sizeof(UNICODE_NULL),
2257  TAG_LDR_WSTR);
2258  if (!NewEntry->FullDllName.Buffer)
2259  {
2261  return FALSE;
2262  }
2263 
2264  /* Set the base name */
2265  NewEntry->BaseDllName.Buffer = (PVOID)(NewEntry + 1);
2266 
2267  /* Copy the full and base name */
2268  RtlCopyMemory(NewEntry->FullDllName.Buffer,
2269  LdrEntry->FullDllName.Buffer,
2270  LdrEntry->FullDllName.MaximumLength);
2271  RtlCopyMemory(NewEntry->BaseDllName.Buffer,
2272  LdrEntry->BaseDllName.Buffer,
2273  LdrEntry->BaseDllName.MaximumLength);
2274 
2275  /* Null-terminate the base name */
2276  NewEntry->BaseDllName.Buffer[NewEntry->BaseDllName.Length /
2277  sizeof(WCHAR)] = UNICODE_NULL;
2278 
2279  /* Insert the entry into the list */
2281  NextEntry = NextEntry->Flink;
2282  }
2283 
2284  /* Build the import lists for the boot drivers */
2286 
2287  /* We're done */
2288  return TRUE;
2289 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
struct _LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY
VOID NTAPI MiLocateKernelSections(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:2147
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG_PTR PsNtosImageBase
Definition: sysldr.c:38
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define InsertTailList(ListHead, Entry)
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:36
PVOID DllBase
Definition: btrfs_drv.h:1926
#define TAG_LDR_WSTR
Definition: tag.h:110
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
LIST_ENTRY InLoadOrderLinks
Definition: ldrtypes.h:138
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSTATUS NTAPI MiBuildImportsForBootDrivers(VOID)
Definition: sysldr.c:1882
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1928
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define RtlImageNtHeader
Definition: compat.h:665
#define TAG_MODULE_OBJECT
Definition: tag.h:109
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

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 90 of file sysldr.c.

95 {
96  PSECTION Section = *SectionPtr;
99  PVOID Base = NULL;
100  SIZE_T ViewSize = 0;
102  LARGE_INTEGER SectionOffset = {{0, 0}};
104  PFN_COUNT PteCount;
105  PMMPTE PointerPte, LastPte;
106  PVOID DriverBase;
107  MMPTE TempPte;
108  KIRQL OldIrql;
109  PFN_NUMBER PageFrameIndex;
110  PAGED_CODE();
111 
112  /* Detect session load */
113  if (SessionLoad)
114  {
115  /* Fail */
116  UNIMPLEMENTED_DBGBREAK("Session loading not yet supported!\n");
117  return STATUS_NOT_IMPLEMENTED;
118  }
119 
120  /* Not session load, shouldn't have an entry */
121  ASSERT(LdrEntry == NULL);
122 
123  /* Attach to the system process */
125 
126  /* Check if we need to load symbols */
128  {
129  /* Yes we do */
130  LoadSymbols = TRUE;
132  }
133 
134  /* Map the driver */
136  Status = MmMapViewOfSection(Section,
137  Process,
138  &Base,
139  0,
140  0,
141  &SectionOffset,
142  &ViewSize,
143  ViewUnmap,
144  0,
145  PAGE_EXECUTE);
146 
147  /* Re-enable the flag */
149 
150  /* Check if we failed with distinguished status code */
152  {
153  /* Change it to something more generic */
155  }
156 
157  /* Now check if we failed */
158  if (!NT_SUCCESS(Status))
159  {
160  /* Detach and return */
161  DPRINT1("MmMapViewOfSection failed with status 0x%x\n", Status);
163  return Status;
164  }
165 
166  /* Reserve system PTEs needed */
167  PteCount = ROUND_TO_PAGES(((PMM_IMAGE_SECTION_OBJECT)Section->Segment)->ImageInformation.ImageFileSize) >> PAGE_SHIFT;
168  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
169  if (!PointerPte)
170  {
171  DPRINT1("MiReserveSystemPtes failed\n");
174  }
175 
176  /* New driver base */
177  LastPte = PointerPte + PteCount;
178  DriverBase = MiPteToAddress(PointerPte);
179 
180  /* The driver is here */
181  *ImageBase = DriverBase;
182  DPRINT1("Loading: %wZ at %p with %lx pages\n", FileName, DriverBase, PteCount);
183 
184  /* Lock the PFN database */
185  OldIrql = MiAcquirePfnLock();
186 
187  /* Loop the new driver PTEs */
189  while (PointerPte < LastPte)
190  {
191  /* Make sure the PTE is not valid for whatever reason */
192  ASSERT(PointerPte->u.Hard.Valid == 0);
193 
194  /* Some debug stuff */
196 #if MI_TRACE_PFNS
197  MI_SET_PROCESS_USTR(FileName);
198 #endif
199 
200  /* Grab a page */
201  PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
202 
203  /* Initialize its PFN entry */
204  MiInitializePfn(PageFrameIndex, PointerPte, TRUE);
205 
206  /* Write the PTE */
207  TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
208  MI_WRITE_VALID_PTE(PointerPte, TempPte);
209 
210  /* Move on */
211  PointerPte++;
212  }
213 
214  /* Release the PFN lock */
215  MiReleasePfnLock(OldIrql);
216 
217  /* Copy the image */
218  RtlCopyMemory(DriverBase, Base, PteCount << PAGE_SHIFT);
219 
220  /* Now unmap the view */
223 
224  /* Detach and return status */
226  return Status;
227 }
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:962
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
KAPC_STATE
Definition: ketypes.h:1280
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PSEGMENT Segment
Definition: mmtypes.h:809
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define TRUE
Definition: types.h:120
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:237
UCHAR KIRQL
Definition: env_spec_w32.h:591
return STATUS_NOT_IMPLEMENTED
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
#define PAGE_EXECUTE
Definition: nt_native.h:1306
#define MI_SET_USAGE(x)
Definition: mm.h:306
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:3906
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:404
KIRQL OldIrql
Definition: mm.h:1502
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI MmUnmapViewOfSection(IN PEPROCESS Process, IN PVOID BaseAddress)
Definition: section.c:3109
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPTE::@2275 u
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPTE ValidKernelPte
Definition: init.c:29
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH
Definition: ntstatus.h:128
KPROCESS Pcb
Definition: pstypes.h:1262
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
ULONG_PTR SIZE_T
Definition: typedefs.h:80
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define ROUND_TO_PAGES(Size)
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1679
#define NULL
Definition: types.h:112
#define FLG_ENABLE_KDEBUG_SYMBOL_LOAD
Definition: pstypes.h:73
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:29
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
ULONG NtGlobalFlag
Definition: init.c:52
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define PAGED_CODE()

Referenced by MmLoadSystemImage().

◆ MiLocateExportName()

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

Definition at line 231 of file sysldr.c.

233 {
234  PULONG NameTable;
235  PUSHORT OrdinalTable;
236  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
237  LONG Low = 0, Mid = 0, High, Ret;
238  USHORT Ordinal;
239  PVOID Function;
240  ULONG ExportSize;
241  PULONG ExportTable;
242  PAGED_CODE();
243 
244  /* Get the export directory */
245  ExportDirectory = RtlImageDirectoryEntryToData(DllBase,
246  TRUE,
248  &ExportSize);
249  if (!ExportDirectory) return NULL;
250 
251  /* Setup name tables */
252  NameTable = (PULONG)((ULONG_PTR)DllBase +
253  ExportDirectory->AddressOfNames);
254  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
255  ExportDirectory->AddressOfNameOrdinals);
256 
257  /* Do a binary search */
258  High = ExportDirectory->NumberOfNames - 1;
259  while (High >= Low)
260  {
261  /* Get new middle value */
262  Mid = (Low + High) >> 1;
263 
264  /* Compare name */
265  Ret = strcmp(ExportName, (PCHAR)DllBase + NameTable[Mid]);
266  if (Ret < 0)
267  {
268  /* Update high */
269  High = Mid - 1;
270  }
271  else if (Ret > 0)
272  {
273  /* Update low */
274  Low = Mid + 1;
275  }
276  else
277  {
278  /* We got it */
279  break;
280  }
281  }
282 
283  /* Check if we couldn't find it */
284  if (High < Low) return NULL;
285 
286  /* Otherwise, this is the ordinal */
287  Ordinal = OrdinalTable[Mid];
288 
289  /* Resolve the address and write it */
290  ExportTable = (PULONG)((ULONG_PTR)DllBase +
291  ExportDirectory->AddressOfFunctions);
292  Function = (PVOID)((ULONG_PTR)DllBase + ExportTable[Ordinal]);
293 
294  /* Check if the function is actually a forwarder */
295  if (((ULONG_PTR)Function > (ULONG_PTR)ExportDirectory) &&
296  ((ULONG_PTR)Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
297  {
298  /* It is, fail */
299  return NULL;
300  }
301 
302  /* We found it */
303  return Function;
304 }
signed char * PCHAR
Definition: retypes.h:7
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1154
#define TRUE
Definition: types.h:120
Definition: strmini.h:380
DWORD AddressOfNameOrdinals
Definition: compat.h:167
uint32_t ULONG_PTR
Definition: typedefs.h:65
long LONG
Definition: pedump.c:60
void * PVOID
Definition: retypes.h:9
Definition: strmini.h:378
#define RtlImageDirectoryEntryToData
Definition: compat.h:668
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ULONG_PTR
Definition: config.h:101
unsigned short * PUSHORT
Definition: retypes.h:2
#define PAGED_CODE()

Referenced by MiCallDllUnloadAndUnloadDll(), and MmCallDllInitialize().

◆ MiLocateKernelSections()

VOID NTAPI MiLocateKernelSections ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 2147 of file sysldr.c.

2148 {
2149  ULONG_PTR DllBase;
2150  PIMAGE_NT_HEADERS NtHeaders;
2151  PIMAGE_SECTION_HEADER SectionHeader;
2152  ULONG Sections, Size;
2153 
2154  /* Get the kernel section header */
2155  DllBase = (ULONG_PTR)LdrEntry->DllBase;
2156  NtHeaders = RtlImageNtHeader((PVOID)DllBase);
2157  SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);
2158 
2159  /* Loop all the sections */
2160  for (Sections = NtHeaders->FileHeader.NumberOfSections;
2161  Sections > 0; --Sections, ++SectionHeader)
2162  {
2163  /* Grab the size of the section */
2164  Size = max(SectionHeader->SizeOfRawData, SectionHeader->Misc.VirtualSize);
2165 
2166  /* Check for .RSRC section */
2167  if (*(PULONG)SectionHeader->Name == 'rsr.')
2168  {
2169  /* Remember the PTEs so we can modify them later */
2171  SectionHeader->VirtualAddress);
2173  SectionHeader->VirtualAddress + Size));
2174  }
2175  else if (*(PULONG)SectionHeader->Name == 'LOOP')
2176  {
2177  /* POOLCODE vs. POOLMI */
2178  if (*(PULONG)&SectionHeader->Name[4] == 'EDOC')
2179  {
2180  /* Found Ex* Pool code */
2181  ExPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2183  }
2184  else if (*(PUSHORT)&SectionHeader->Name[4] == 'MI')
2185  {
2186  /* Found Mm* Pool code */
2187  MmPoolCodeStart = DllBase + SectionHeader->VirtualAddress;
2189  }
2190  }
2191  else if ((*(PULONG)SectionHeader->Name == 'YSIM') &&
2192  (*(PULONG)&SectionHeader->Name[4] == 'ETPS'))
2193  {
2194  /* Found MISYSPTE (Mm System PTE code) */
2195  MmPteCodeStart = DllBase + SectionHeader->VirtualAddress;
2197  }
2198  }
2199 }
#define max(a, b)
Definition: svc.c:63
PMMPTE MiKernelResourceEndPte
Definition: sysldr.c:49
ULONG_PTR MmPoolCodeStart
Definition: sysldr.c:50
ULONG_PTR MmPoolCodeEnd
Definition: sysldr.c:50
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG_PTR MmPteCodeStart
Definition: sysldr.c:51
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
ULONG_PTR MmPteCodeEnd
Definition: sysldr.c:51
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
ULONG_PTR ExPoolCodeStart
Definition: sysldr.c:50
ULONG_PTR ExPoolCodeEnd
Definition: sysldr.c:50
#define ROUND_TO_PAGES(Size)
unsigned int * PULONG
Definition: retypes.h:1
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define RtlImageNtHeader
Definition: compat.h:665
union _IMAGE_SECTION_HEADER::@1510 Misc
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
PMMPTE MiKernelResourceStartPte
Definition: sysldr.c:49
unsigned short * PUSHORT
Definition: retypes.h:2

Referenced by MiInitializeLoadedModuleList().

◆ MiLookupDataTableEntry()

PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry ( IN PVOID  Address)

Definition at line 3427 of file sysldr.c.

3428 {
3429  PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL;
3430  PLIST_ENTRY NextEntry;
3431  PAGED_CODE();
3432 
3433  /* Loop entries */
3434  NextEntry = PsLoadedModuleList.Flink;
3435  do
3436  {
3437  /* Get the loader entry */
3438  LdrEntry = CONTAINING_RECORD(NextEntry,
3440  InLoadOrderLinks);
3441 
3442  /* Check if the address matches */
3443  if ((Address >= LdrEntry->DllBase) &&
3444  (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase +
3445  LdrEntry->SizeOfImage)))
3446  {
3447  /* Found a match */
3448  FoundEntry = LdrEntry;
3449  break;
3450  }
3451 
3452  /* Move on */
3453  NextEntry = NextEntry->Flink;
3454  } while(NextEntry != &PsLoadedModuleList);
3455 
3456  /* Return the entry */
3457  return FoundEntry;
3458 }
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
ULONG SizeOfImage
Definition: ldrtypes.h:143
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DllBase
Definition: btrfs_drv.h:1926
static WCHAR Address[46]
Definition: ping.c:68
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define PAGED_CODE()

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

◆ MiProcessLoaderEntry()

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

Definition at line 565 of file sysldr.c.

567 {
568  KIRQL OldIrql;
569 
570  /* Acquire module list lock */
573 
574  /* Acquire the spinlock too as we will insert or remove the entry */
576 
577  /* Insert or remove from the list */
578  if (Insert)
579  InsertTailList(&PsLoadedModuleList, &LdrEntry->InLoadOrderLinks);
580  else
581  RemoveEntryList(&LdrEntry->InLoadOrderLinks);
582 
583  /* Release locks */
587 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
#define InsertTailList(ListHead, Entry)
KSPIN_LOCK PsLoadedModuleSpinLock
Definition: sysldr.c:36
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
UCHAR KIRQL
Definition: env_spec_w32.h:591
KIRQL OldIrql
Definition: mm.h:1502
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#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 1693 of file sysldr.c.

1694 {
1695  PLIST_ENTRY NextEntry;
1696  ULONG i = 0;
1697  PIMAGE_NT_HEADERS NtHeader;
1698  PLDR_DATA_TABLE_ENTRY LdrEntry;
1699  PIMAGE_FILE_HEADER FileHeader;
1700  BOOLEAN ValidRelocs;
1701  PIMAGE_DATA_DIRECTORY DataDirectory;
1702  PVOID DllBase, NewImageAddress;
1703  NTSTATUS Status;
1704  PMMPTE PointerPte, StartPte, LastPte;
1705  PFN_COUNT PteCount;
1706  PMMPFN Pfn1;
1707  MMPTE TempPte, OldPte;
1708 
1709  /* Loop driver list */
1710  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
1711  NextEntry != &LoaderBlock->LoadOrderListHead;
1712  NextEntry = NextEntry->Flink)
1713  {
1714  /* Get the loader entry and NT header */
1715  LdrEntry = CONTAINING_RECORD(NextEntry,
1717  InLoadOrderLinks);
1718  NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
1719 
1720  /* Debug info */
1721  DPRINT("[Mm0]: Driver at: %p ending at: %p for module: %wZ\n",
1722  LdrEntry->DllBase,
1723  (ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage,
1724  &LdrEntry->FullDllName);
1725 
1726  /* Get the first PTE and the number of PTEs we'll need */
1727  PointerPte = StartPte = MiAddressToPte(LdrEntry->DllBase);
1728  PteCount = ROUND_TO_PAGES(LdrEntry->SizeOfImage) >> PAGE_SHIFT;
1729  LastPte = StartPte + PteCount;
1730 
1731 #if MI_TRACE_PFNS
1732  /* Loop the PTEs */
1733  while (PointerPte < LastPte)
1734  {
1735  ULONG len;
1736  ASSERT(PointerPte->u.Hard.Valid == 1);
1737  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1738  len = wcslen(LdrEntry->BaseDllName.Buffer) * sizeof(WCHAR);
1739  snprintf(Pfn1->ProcessName, min(16, len), "%S", LdrEntry->BaseDllName.Buffer);
1740  PointerPte++;
1741  }
1742 #endif
1743  /* Skip kernel and HAL */
1744  /* ROS HACK: Skip BOOTVID/KDCOM too */
1745  i++;
1746  if (i <= 4) continue;
1747 
1748  /* Skip non-drivers */
1749  if (!NtHeader) continue;
1750 
1751  /* Get the file header and make sure we can relocate */
1752  FileHeader = &NtHeader->FileHeader;
1753  if (FileHeader->Characteristics & IMAGE_FILE_RELOCS_STRIPPED) continue;
1754  if (NtHeader->OptionalHeader.NumberOfRvaAndSizes <
1756 
1757  /* Everything made sense until now, check the relocation section too */
1758  DataDirectory = &NtHeader->OptionalHeader.
1759  DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
1760  if (!DataDirectory->VirtualAddress)
1761  {
1762  /* We don't really have relocations */
1763  ValidRelocs = FALSE;
1764  }
1765  else
1766  {
1767  /* Make sure the size is valid */
1768  if ((DataDirectory->VirtualAddress + DataDirectory->Size) >
1769  LdrEntry->SizeOfImage)
1770  {
1771  /* They're not, skip */
1772  continue;
1773  }
1774 
1775  /* We have relocations */
1776  ValidRelocs = TRUE;
1777  }
1778 
1779  /* Remember the original address */
1780  DllBase = LdrEntry->DllBase;
1781 
1782  /* Loop the PTEs */
1783  PointerPte = StartPte;
1784  while (PointerPte < LastPte)
1785  {
1786  /* Mark the page modified in the PFN database */
1787  ASSERT(PointerPte->u.Hard.Valid == 1);
1788  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
1789  ASSERT(Pfn1->u3.e1.Rom == 0);
1790  Pfn1->u3.e1.Modified = TRUE;
1791 
1792  /* Next */
1793  PointerPte++;
1794  }
1795 
1796  /* Now reserve system PTEs for the image */
1797  PointerPte = MiReserveSystemPtes(PteCount, SystemPteSpace);
1798  if (!PointerPte)
1799  {
1800  /* Shouldn't happen */
1801  ERROR_FATAL("[Mm0]: Couldn't allocate driver section!\n");
1802  return;
1803  }
1804 
1805  /* This is the new virtual address for the module */
1806  LastPte = PointerPte + PteCount;
1807  NewImageAddress = MiPteToAddress(PointerPte);
1808 
1809  /* Sanity check */
1810  DPRINT("[Mm0]: Copying from: %p to: %p\n", DllBase, NewImageAddress);
1812 
1813  /* Loop the new driver PTEs */
1815  while (PointerPte < LastPte)
1816  {
1817  /* Copy the old data */
1818  OldPte = *StartPte;
1819  ASSERT(OldPte.u.Hard.Valid == 1);
1820 
1821  /* Set page number from the loader's memory */
1822  TempPte.u.Hard.PageFrameNumber = OldPte.u.Hard.PageFrameNumber;
1823 
1824  /* Write it */
1825  MI_WRITE_VALID_PTE(PointerPte, TempPte);
1826 
1827  /* Move on */
1828  PointerPte++;
1829  StartPte++;
1830  }
1831 
1832  /* Update position */
1833  PointerPte -= PteCount;
1834 
1835  /* Sanity check */
1836  ASSERT(*(PULONG)NewImageAddress == *(PULONG)DllBase);
1837 
1838  /* Set the image base to the address where the loader put it */
1839  NtHeader->OptionalHeader.ImageBase = (ULONG_PTR)DllBase;
1840 
1841  /* Check if we had relocations */
1842  if (ValidRelocs)
1843  {
1844  /* Relocate the image */
1845  Status = LdrRelocateImageWithBias(NewImageAddress,
1846  0,
1847  "SYSLDR",
1851  if (!NT_SUCCESS(Status))
1852  {
1853  /* This shouldn't happen */
1854  ERROR_FATAL("Relocations failed!\n");
1855  return;
1856  }
1857  }
1858 
1859  /* Update the loader entry */
1860  LdrEntry->DllBase = NewImageAddress;
1861 
1862  /* Update the thunks */
1863  DPRINT("[Mm0]: Updating thunks to: %wZ\n", &LdrEntry->BaseDllName);
1864  MiUpdateThunks(LoaderBlock,
1865  DllBase,
1866  NewImageAddress,
1867  LdrEntry->SizeOfImage);
1868 
1869  /* Update the loader entry */
1870  LdrEntry->Flags |= LDRP_SYSTEM_MAPPED;
1871  LdrEntry->EntryPoint = (PVOID)((ULONG_PTR)NewImageAddress +
1873  LdrEntry->SizeOfImage = PteCount << PAGE_SHIFT;
1874 
1875  /* FIXME: We'll need to fixup the PFN linkage when switching to ARM3 */
1876  }
1877 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define TRUE
Definition: types.h:120
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
LONG NTSTATUS
Definition: precomp.h:26
ULONG SizeOfImage
Definition: ldrtypes.h:143
#define snprintf
Definition: wintirpc.h:48
USHORT Modified
Definition: mm.h:349
union _MMPFN::@1749 u3
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ERROR_FATAL(...)
Definition: debug.h:238
PVOID DllBase
Definition: btrfs_drv.h:1926
MMPFNENTRY e1
Definition: mm.h:386
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
PVOID EntryPoint
Definition: ntddk_ex.h:203
unsigned char BOOLEAN
void * PVOID
Definition: retypes.h:9
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPTE::@2275 u
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPTE ValidKernelPte
Definition: init.c:29
Definition: mm.h:362
Definition: btrfs_drv.h:1922
ULONG ExpInitializationPhase
Definition: init.c:66
GLenum GLsizei len
Definition: glext.h:6722
Definition: typedefs.h:119
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1000
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
NTSYSAPI ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID NewAddress, _In_ LONGLONG AdditionalBias, _In_ PCCH LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
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
#define ROUND_TO_PAGES(Size)
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1928
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
USHORT Rom
Definition: mm.h:357
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define RtlImageNtHeader
Definition: compat.h:665
ULONG Flags
Definition: ntddk_ex.h:207
VOID NTAPI MiUpdateThunks(IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PVOID OldBase, IN PVOID NewBase, IN ULONG Size)
Definition: sysldr.c:592
unsigned int ULONG
Definition: retypes.h:1
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define PFN_FROM_PTE(v)
Definition: mm.h:92
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define LDRP_SYSTEM_MAPPED
Definition: ldrtypes.h:54

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 1000 of file sysldr.c.

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

Referenced by LdrProcessDriverModule(), and MmLoadSystemImage().

◆ MiSetPagingOfDriver()

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

Definition at line 2560 of file sysldr.c.

2562 {
2563 #ifdef ENABLE_MISETPAGINGOFDRIVER
2564  PVOID ImageBase;
2565  PETHREAD CurrentThread = PsGetCurrentThread();
2566  PFN_COUNT PageCount = 0;
2567  PFN_NUMBER PageFrameIndex;
2568  PMMPFN Pfn1;
2569 #endif // ENABLE_MISETPAGINGOFDRIVER
2570 
2571  PAGED_CODE();
2572 
2573 #ifndef ENABLE_MISETPAGINGOFDRIVER
2574  /* The page fault handler is broken and doesn't page back in! */
2575  DPRINT1("WARNING: MiSetPagingOfDriver() called, but paging is broken! ignoring!\n");
2576 #else // ENABLE_MISETPAGINGOFDRIVER
2577  /* Get the driver's base address */
2578  ImageBase = MiPteToAddress(PointerPte);
2579  ASSERT(MI_IS_SESSION_IMAGE_ADDRESS(ImageBase) == FALSE);
2580 
2581  /* If this is a large page, it's stuck in physical memory */
2582  if (MI_IS_PHYSICAL_ADDRESS(ImageBase)) return;
2583 
2584  /* Lock the working set */
2585  MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
2586 
2587  /* Loop the PTEs */
2588  while (PointerPte <= LastPte)
2589  {
2590  /* Check for valid PTE */
2591  if (PointerPte->u.Hard.Valid == 1)
2592  {
2593  PageFrameIndex = PFN_FROM_PTE(PointerPte);
2594  Pfn1 = MiGetPfnEntry(PageFrameIndex);
2595  ASSERT(Pfn1->u2.ShareCount == 1);
2596 
2597  /* No working sets in ReactOS yet */
2598  PageCount++;
2599  }
2600 
2601  ImageBase = (PVOID)((ULONG_PTR)ImageBase + PAGE_SIZE);
2602  PointerPte++;
2603  }
2604 
2605  /* Release the working set */
2606  MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
2607 
2608  /* Do we have any driver pages? */
2609  if (PageCount)
2610  {
2611  /* Update counters */
2613  }
2614 #endif // ENABLE_MISETPAGINGOFDRIVER
2615 }
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG PFN_COUNT
Definition: mmtypes.h:102
PFN_NUMBER MmTotalSystemDriverPages
Definition: sysldr.c:41
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
ULONG_PTR ShareCount
Definition: mm.h:379
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1356
void * PVOID
Definition: retypes.h:9
#define InterlockedExchangeAdd
Definition: interlocked.h:181
#define ASSERT(a)
Definition: mode.c:44
Definition: mm.h:362
#define PAGE_SIZE
Definition: env_spec_w32.h:49
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1000
#define DPRINT1
Definition: precomp.h:8
union _MMPFN::@1748 u2
#define MI_IS_SESSION_IMAGE_ADDRESS(Address)
Definition: miarm.h:168
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1270
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
signed int * PLONG
Definition: retypes.h:5
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define PAGED_CODE()

Referenced by MiEnablePagingOfDriver(), and MmPageEntireDriver().

◆ MiSetSystemCodeProtection()

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

Definition at line 2404 of file sysldr.c.

2408 {
2409  PMMPTE PointerPte;
2410  MMPTE TempPte;
2411 
2412  /* Loop the PTEs */
2413  for (PointerPte = FirstPte; PointerPte <= LastPte; PointerPte++)
2414  {
2415  /* Read the PTE */
2416  TempPte = *PointerPte;
2417 
2418  /* Make sure it's valid */
2419  if (TempPte.u.Hard.Valid != 1)
2420  {
2421  DPRINT1("CORE-16449: FirstPte=%p, LastPte=%p, Protection=%lx\n", FirstPte, LastPte, Protection);
2422  DPRINT1("CORE-16449: PointerPte=%p, TempPte=%lx\n", PointerPte, TempPte.u.Long);
2423  DPRINT1("CORE-16449: Please issue the 'mod' and 'bt' (KDBG) or 'lm' and 'kp' (WinDbg) commands. Then report this in Jira.\n");
2424  ASSERT(TempPte.u.Hard.Valid == 1);
2425  break;
2426  }
2427 
2428  /* Update the protection */
2429  TempPte.u.Hard.Write = BooleanFlagOn(Protection, IMAGE_SCN_MEM_WRITE);
2430 #if _MI_HAS_NO_EXECUTE
2431  TempPte.u.Hard.NoExecute = !BooleanFlagOn(Protection, IMAGE_SCN_MEM_EXECUTE);
2432 #endif
2433 
2434  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2435  }
2436 
2437  /* Flush it all */
2439 }
#define TRUE
Definition: types.h:120
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:403
#define ASSERT(a)
Definition: mode.c:44
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:982
#define IMAGE_SCN_MEM_EXECUTE
Definition: ntimage.h:239

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 691 of file sysldr.c.

699 {
700  BOOLEAN IsOrdinal;
701  USHORT Ordinal;
702  PULONG NameTable;
703  PUSHORT OrdinalTable;
704  PIMAGE_IMPORT_BY_NAME NameImport;
705  USHORT Hint;
706  ULONG Low = 0, Mid = 0, High;
707  LONG Ret;
709  PCHAR MissingForwarder;
710  CHAR NameBuffer[MAXIMUM_FILENAME_LENGTH];
711  PULONG ExportTable;
712  ANSI_STRING DllName;
713  UNICODE_STRING ForwarderName;
714  PLIST_ENTRY NextEntry;
715  PLDR_DATA_TABLE_ENTRY LdrEntry;
716  ULONG ForwardExportSize;
717  PIMAGE_EXPORT_DIRECTORY ForwardExportDirectory;
718  PIMAGE_IMPORT_BY_NAME ForwardName;
719  SIZE_T ForwardLength;
720  IMAGE_THUNK_DATA ForwardThunk;
721  PAGED_CODE();
722 
723  /* Check if this is an ordinal */
724  IsOrdinal = IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal);
725  if ((IsOrdinal) && !(SnapForwarder))
726  {
727  /* Get the ordinal number and set it as missing */
728  Ordinal = (USHORT)(IMAGE_ORDINAL(Name->u1.Ordinal) -
729  ExportDirectory->Base);
730  *MissingApi = (PCHAR)(ULONG_PTR)Ordinal;
731  }
732  else
733  {
734  /* Get the VA if we don't have to snap */
735  if (!SnapForwarder) Name->u1.AddressOfData += (ULONG_PTR)ImageBase;
736  NameImport = (PIMAGE_IMPORT_BY_NAME)Name->u1.AddressOfData;
737 
738  /* Copy the procedure name */
739  RtlStringCbCopyA(*MissingApi,
741  (PCHAR)&NameImport->Name[0]);
742 
743  /* Setup name tables */
744  DPRINT("Import name: %s\n", NameImport->Name);
745  NameTable = (PULONG)((ULONG_PTR)DllBase +
746  ExportDirectory->AddressOfNames);
747  OrdinalTable = (PUSHORT)((ULONG_PTR)DllBase +
748  ExportDirectory->AddressOfNameOrdinals);
749 
750  /* Get the hint and check if it's valid */
751  Hint = NameImport->Hint;
752  if ((Hint < ExportDirectory->NumberOfNames) &&
753  !(strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Hint])))
754  {
755  /* We have a match, get the ordinal number from here */
756  Ordinal = OrdinalTable[Hint];
757  }
758  else
759  {
760  /* Do a binary search */
761  High = ExportDirectory->NumberOfNames - 1;
762  while (High >= Low)
763  {
764  /* Get new middle value */
765  Mid = (Low + High) >> 1;
766 
767  /* Compare name */
768  Ret = strcmp((PCHAR)NameImport->Name, (PCHAR)DllBase + NameTable[Mid]);
769  if (Ret < 0)
770  {
771  /* Update high */
772  High = Mid - 1;
773  }
774  else if (Ret > 0)
775  {
776  /* Update low */
777  Low = Mid + 1;
778  }
779  else
780  {
781  /* We got it */
782  break;
783  }
784  }
785 
786  /* Check if we couldn't find it */
787  if (High < Low)
788  {
789  DPRINT1("Warning: Driver failed to load, %s not found\n", NameImport->Name);
791  }
792 
793  /* Otherwise, this is the ordinal */
794  Ordinal = OrdinalTable[Mid];
795  }
796  }
797 
798  /* Check if the ordinal is invalid */
799  if (Ordinal >= ExportDirectory->NumberOfFunctions)
800  {
801  /* Fail */
803  }
804  else
805  {
806  /* In case the forwarder is missing */
807  MissingForwarder = NameBuffer;
808 
809  /* Resolve the address and write it */
810  ExportTable = (PULONG)((ULONG_PTR)DllBase +
811  ExportDirectory->AddressOfFunctions);
812  Address->u1.Function = (ULONG_PTR)DllBase + ExportTable[Ordinal];
813 
814  /* Assume success from now on */
816 
817  /* Check if the function is actually a forwarder */
818  if ((Address->u1.Function > (ULONG_PTR)ExportDirectory) &&
819  (Address->u1.Function < ((ULONG_PTR)ExportDirectory + ExportSize)))
820  {
821  /* Now assume failure in case the forwarder doesn't exist */
823 
824  /* Build the forwarder name */
825  DllName.Buffer = (PCHAR)Address->u1.Function;
826  DllName.Length = (USHORT)(strchr(DllName.Buffer, '.') -
827  DllName.Buffer) +
828  sizeof(ANSI_NULL);
829  DllName.MaximumLength = DllName.Length;
830 
831  /* Convert it */
832  if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&ForwarderName,
833  &DllName,
834  TRUE)))
835  {
836  /* We failed, just return an error */
837  return Status;
838  }
839 
840  /* Loop the module list */
841  NextEntry = PsLoadedModuleList.Flink;
842  while (NextEntry != &PsLoadedModuleList)
843  {
844  /* Get the loader entry */
845  LdrEntry = CONTAINING_RECORD(NextEntry,
847  InLoadOrderLinks);
848 
849  /* Check if it matches */
850  if (RtlPrefixUnicodeString(&ForwarderName,
851  &LdrEntry->BaseDllName,
852  TRUE))
853  {
854  /* Get the forwarder export directory */
855  ForwardExportDirectory =
857  TRUE,
859  &ForwardExportSize);
860  if (!ForwardExportDirectory) break;
861 
862  /* Allocate a name entry */
863  ForwardLength = strlen(DllName.Buffer + DllName.Length) +
864  sizeof(ANSI_NULL);
865  ForwardName = ExAllocatePoolWithTag(PagedPool,
866  sizeof(*ForwardName) +
867  ForwardLength,
868  TAG_LDR_WSTR);
869  if (!ForwardName) break;
870 
871  /* Copy the data */
872  RtlCopyMemory(&ForwardName->Name[0],
873  DllName.Buffer + DllName.Length,
874  ForwardLength);
875  ForwardName->Hint = 0;
876 
877  /* Set the new address */
878  ForwardThunk.u1.AddressOfData = (ULONG_PTR)ForwardName;
879 
880  /* Snap the forwarder */
881  Status = MiSnapThunk(LdrEntry->DllBase,
882  ImageBase,
883  &ForwardThunk,
884  &ForwardThunk,
885  ForwardExportDirectory,
886  ForwardExportSize,
887  TRUE,
888  &MissingForwarder);
889 
890  /* Free the forwarder name and set the thunk */
891  ExFreePoolWithTag(ForwardName, TAG_LDR_WSTR);
892  Address->u1 = ForwardThunk.u1;
893  break;
894  }
895 
896  /* Go to the next entry */
897  NextEntry = NextEntry->Flink;
898  }
899 
900  /* Free the name */
901  RtlFreeUnicodeString(&ForwarderName);
902  }
903  }
904 
905  /* Return status */
906  return Status;
907 }
signed char * PCHAR
Definition: retypes.h:7
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
union _IMAGE_THUNK_DATA32::@2079 u1
#define STATUS_DRIVER_ORDINAL_NOT_FOUND
Definition: ntstatus.h:735
Definition: strmini.h:380
struct _IMAGE_IMPORT_BY_NAME * PIMAGE_IMPORT_BY_NAME
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:736
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
PVOID DllBase
Definition: btrfs_drv.h:1926
#define TAG_LDR_WSTR
Definition: tag.h:110
#define ANSI_NULL
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define PCHAR
Definition: match.c:90
Status
Definition: gdiplustypes.h:24
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: strmini.h:378
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define RtlImageDirectoryEntryToData
Definition: compat.h:668
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define IMAGE_SNAP_BY_ORDINAL(Ordinal)
Definition: ntimage.h:567
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
unsigned int * PULONG
Definition: retypes.h:1
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ULONG_PTR
Definition: config.h:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
#define IMAGE_ORDINAL(Ordinal)
Definition: pedump.c:337
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
unsigned short * PUSHORT
Definition: retypes.h:2
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:691
#define PAGED_CODE()

Referenced by MiResolveImageReferences().

◆ MiUpdateThunks()

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

Definition at line 592 of file sysldr.c.

596 {
597  ULONG_PTR OldBaseTop, Delta;
598  PLDR_DATA_TABLE_ENTRY LdrEntry;
599  PLIST_ENTRY NextEntry;
600  ULONG ImportSize;
601  //
602  // FIXME: MINGW-W64 must fix LD to generate drivers that Windows can load,
603  // since a real version of Windows would fail at this point, but they seem
604  // busy implementing features such as "HotPatch" support in GCC 4.6 instead,
605  // a feature which isn't even used by Windows. Priorities, priorities...
606  // Please note that Microsoft WDK EULA and license prohibits using
607  // the information contained within it for the generation of "non-Windows"
608  // drivers, which is precisely what LD will generate, since an LD driver
609  // will not load on Windows.
610  //
611 #ifdef _WORKING_LINKER_
612  ULONG i;
613 #endif
614  PULONG_PTR ImageThunk;
615  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
616 
617  /* Calculate the top and delta */
618  OldBaseTop = (ULONG_PTR)OldBase + Size - 1;
619  Delta = (ULONG_PTR)NewBase - (ULONG_PTR)OldBase;
620 
621  /* Loop the loader block */
622  for (NextEntry = LoaderBlock->LoadOrderListHead.Flink;
623  NextEntry != &LoaderBlock->LoadOrderListHead;
624  NextEntry = NextEntry->Flink)
625  {
626  /* Get the loader entry */
627  LdrEntry = CONTAINING_RECORD(NextEntry,
629  InLoadOrderLinks);
630 #ifdef _WORKING_LINKER_
631  /* Get the IAT */
632  ImageThunk = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
633  TRUE,
635  &ImportSize);
636  if (!ImageThunk) continue;
637 
638  /* Make sure we have an IAT */
639  DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
640  for (i = 0; i < ImportSize; i++, ImageThunk++)
641  {
642  /* Check if it's within this module */
643  if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
644  {
645  /* Relocate it */
646  DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
647  ImageThunk, *ImageThunk, *ImageThunk + Delta);
648  *ImageThunk += Delta;
649  }
650  }
651 #else
652  /* Get the import table */
653  ImportDescriptor = RtlImageDirectoryEntryToData(LdrEntry->DllBase,
654  TRUE,
656  &ImportSize);
657  if (!ImportDescriptor) continue;
658 
659  /* Make sure we have an IAT */
660  DPRINT("[Mm0]: Updating thunks in: %wZ\n", &LdrEntry->BaseDllName);
661  while ((ImportDescriptor->Name) &&
662  (ImportDescriptor->OriginalFirstThunk))
663  {
664  /* Get the image thunk */
665  ImageThunk = (PVOID)((ULONG_PTR)LdrEntry->DllBase +
666  ImportDescriptor->FirstThunk);
667  while (*ImageThunk)
668  {
669  /* Check if it's within this module */
670  if ((*ImageThunk >= (ULONG_PTR)OldBase) && (*ImageThunk <= OldBaseTop))
671  {
672  /* Relocate it */
673  DPRINT("[Mm0]: Updating IAT at: %p. Old Entry: %p. New Entry: %p.\n",
674  ImageThunk, *ImageThunk, *ImageThunk + Delta);
675  *ImageThunk += Delta;
676  }
677 
678  /* Go to the next thunk */
679  ImageThunk++;
680  }
681 
682  /* Go to the next import */
683  ImportDescriptor++;
684  }
685 #endif
686  }
687 }
#define TRUE
Definition: types.h:120
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DllBase
Definition: btrfs_drv.h:1926
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define RtlImageDirectoryEntryToData
Definition: compat.h:668
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
#define IMAGE_DIRECTORY_ENTRY_IAT
Definition: pedump.c:271
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
static ULONG Delta
Definition: xboxvideo.c:33
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define DPRINT
Definition: sndvol32.h:71

Referenced by MiReloadBootLoadedDrivers().

◆ MiUseLargeDriverPage()

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

Definition at line 2347 of file sysldr.c.

2351 {
2352  PLIST_ENTRY NextEntry;
2353  BOOLEAN DriverFound = FALSE;
2354  PMI_LARGE_PAGE_DRIVER_ENTRY LargePageDriverEntry;
2356  ASSERT(*ImageBaseAddress >= MmSystemRangeStart);
2357 
2358 #ifdef _X86_
2359  if (!(KeFeatureBits & KF_LARGE_PAGE)) return FALSE;
2360  if (!(__readcr4() & CR4_PSE)) return FALSE;
2361 #endif
2362 
2363  /* Make sure there's enough system PTEs for a large page driver */
2365  {
2366  return FALSE;
2367  }
2368 
2369  /* This happens if the registry key had a "*" (wildcard) in it */
2370  if (MiLargePageAllDrivers == 0)
2371  {
2372  /* It didn't, so scan the list */
2373  NextEntry = MiLargePageDriverList.Flink;
2374  while (NextEntry != &MiLargePageDriverList)
2375  {
2376  /* Check if the driver name matches */
2377  LargePageDriverEntry = CONTAINING_RECORD(NextEntry,
2379  Links);
2380  if (RtlEqualUnicodeString(BaseImageName,
2381  &LargePageDriverEntry->BaseName,
2382  TRUE))
2383  {
2384  /* Enable large pages for this driver */
2385  DriverFound = TRUE;
2386  break;
2387  }
2388 
2389  /* Keep trying */
2390  NextEntry = NextEntry->Flink;
2391  }
2392 
2393  /* If we didn't find the driver, it doesn't need large pages */
2394  if (DriverFound == FALSE) return FALSE;
2395  }
2396 
2397  /* Nothing to do yet */
2398  DPRINT1("Large pages not supported!\n");
2399  return FALSE;
2400 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define TRUE
Definition: types.h:120
#define CR4_PSE
Definition: ketypes.h:88
LIST_ENTRY MiLargePageDriverList
Definition: largepag.c:26
ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes]
Definition: syspte.c:25
ULONG KeFeatureBits
Definition: krnlinit.c:22
UNICODE_STRING BaseName
Definition: miarm.h:403
#define KF_LARGE_PAGE
Definition: ketypes.h:148
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
Definition: miarm.h:400
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
BOOLEAN MiLargePageAllDrivers
Definition: largepag.c:27
Definition: typedefs.h:119
__INTRIN_INLINE unsigned long __readcr4(void)
Definition: intrin_x86.h:1826
#define DPRINT1
Definition: precomp.h:8
#define PDE_MAPPED_VA
Definition: mm.h:39
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define MmSystemRangeStart
Definition: mm.h:32

Referenced by MmLoadSystemImage().

◆ MiWriteProtectSystemImage()

VOID NTAPI MiWriteProtectSystemImage ( _In_ PVOID  ImageBase)

Definition at line 2443 of file sysldr.c.

2445 {
2446  PIMAGE_NT_HEADERS NtHeaders;
2447  PIMAGE_SECTION_HEADER SectionHeaders, Section;
2448  ULONG i;
2449  PVOID SectionBase, SectionEnd;
2450  ULONG SectionSize;
2451  ULONG Protection;
2452  PMMPTE FirstPte, LastPte;
2453 
2454  /* Check if the registry setting is on or not */
2456  {
2457  /* Ignore section protection */
2458  return;
2459  }
2460 
2461  /* Large page mapped images are not supported */
2462  NT_ASSERT(!MI_IS_PHYSICAL_ADDRESS(ImageBase));
2463 
2464  /* Session images are not yet supported */
2465  NT_ASSERT(!MI_IS_SESSION_ADDRESS(ImageBase));
2466 
2467  /* Get the NT headers */
2468  NtHeaders = RtlImageNtHeader(ImageBase);
2469  if (NtHeaders == NULL)
2470  {
2471  DPRINT1("Failed to get NT headers for image @ %p\n", ImageBase);
2472  return;
2473  }
2474 
2475  /* Don't touch NT4 drivers */
2476  if ((NtHeaders->OptionalHeader.MajorOperatingSystemVersion < 5) ||
2477  (NtHeaders->OptionalHeader.MajorSubsystemVersion < 5))
2478  {
2479  DPRINT1("Skipping NT 4 driver @ %p\n", ImageBase);
2480  return;
2481  }
2482 
2483  /* Get the section headers */
2484  SectionHeaders = IMAGE_FIRST_SECTION(NtHeaders);
2485 
2486  /* Get the base address of the first section */
2487  SectionBase = Add2Ptr(ImageBase, SectionHeaders[0].VirtualAddress);
2488 
2489  /* Start protecting the image header as R/W */
2490  FirstPte = MiAddressToPte(ImageBase);
2491  LastPte = MiAddressToPte(SectionBase) - 1;
2492  Protection = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
2493  if (LastPte >= FirstPte)
2494  {
2495  MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2496  }
2497 
2498  /* Loop the sections */
2499  for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
2500  {
2501  /* Get the section base address and size */
2502  Section = &SectionHeaders[i];
2503  SectionBase = Add2Ptr(ImageBase, Section->VirtualAddress);
2504  SectionSize = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
2505 
2506  /* Get the first PTE of this section */
2507  FirstPte = MiAddressToPte(SectionBase);
2508 
2509  /* Check for overlap with the previous range */
2510  if (FirstPte == LastPte)
2511  {
2512  /* Combine the old and new protection by ORing them */
2513  Protection |= (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2514 
2515  /* Update the protection for this PTE */
2516  MiSetSystemCodeProtection(FirstPte, FirstPte, Protection);
2517 
2518  /* Skip this PTE */
2519  FirstPte++;
2520  }
2521 
2522  /* There can not be gaps! */
2523  NT_ASSERT(FirstPte == (LastPte + 1));
2524 
2525  /* Get the end of the section and the last PTE */
2526  SectionEnd = Add2Ptr(SectionBase, SectionSize - 1);
2527  NT_ASSERT(SectionEnd < Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage));
2528  LastPte = MiAddressToPte(SectionEnd);
2529 
2530  /* If there are no more pages (after an overlap), skip this section */
2531  if (LastPte < FirstPte)
2532  {
2533  NT_ASSERT(FirstPte == (LastPte + 1));
2534  continue;
2535  }
2536 
2537  /* Get the section protection */
2538  Protection = (Section->Characteristics & IMAGE_SCN_PROTECTION_MASK);
2539 
2540  /* Update the protection for this section */
2541  MiSetSystemCodeProtection(FirstPte, LastPte, Protection);
2542  }
2543 
2544  /* Image should end with the last section */
2545  if (ALIGN_UP_POINTER_BY(SectionEnd, PAGE_SIZE) !=
2546  Add2Ptr(ImageBase, NtHeaders->OptionalHeader.SizeOfImage))
2547  {
2548  DPRINT1("ImageBase 0x%p ImageSize 0x%lx Section %u VA 0x%lx Raw 0x%lx virt 0x%lx\n",
2549  ImageBase,
2550  NtHeaders->OptionalHeader.SizeOfImage,
2551  i,
2552  Section->VirtualAddress,
2553  Section->SizeOfRawData,
2554  Section->Misc.VirtualSize);
2555  }
2556 }
#define max(a, b)
Definition: svc.c:63
#define Add2Ptr(PTR, INC)
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:171
#define IMAGE_SCN_MEM_READ
Definition: ntimage.h:240
WORD MajorOperatingSystemVersion
Definition: ntddk_ex.h:160
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
VOID NTAPI MiSetSystemCodeProtection(_In_ PMMPTE FirstPte, _In_ PMMPTE LastPte, _In_ ULONG Protection)
Definition: sysldr.c:2404
#define IMAGE_SCN_PROTECTION_MASK
Definition: miarm.h:160
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define IMAGE_SCN_MEM_WRITE
Definition: ntimage.h:241
#define ALIGN_UP_POINTER_BY(ptr, align)
Definition: umtypes.h:85
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
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
BOOLEAN MmEnforceWriteProtection
Definition: sysldr.c:47
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define RtlImageNtHeader
Definition: compat.h:665
union _IMAGE_SECTION_HEADER::@1510 Misc
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
#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 308 of file sysldr.c.

310 {
312  L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
313  PMM_DLL_INITIALIZE DllInit;
314  UNICODE_STRING RegPath, ImportName;
316 
317  /* Try to see if the image exports a DllInitialize routine */
318  DllInit = (PMM_DLL_INITIALIZE)MiLocateExportName(LdrEntry->DllBase,
319  "DllInitialize");
320  if (!DllInit) return STATUS_SUCCESS;
321 
322  /*
323  * Do a temporary copy of BaseDllName called ImportName
324  * because we'll alter the length of the string.
325  */
326  ImportName.Length = LdrEntry->BaseDllName.Length;
327  ImportName.MaximumLength = LdrEntry->BaseDllName.MaximumLength;
328  ImportName.Buffer = LdrEntry->BaseDllName.Buffer;
329 
330  /* Obtain the path to this dll's service in the registry */
331  RegPath.MaximumLength = ServicesKeyName.Length +
332  ImportName.Length + sizeof(UNICODE_NULL);
334  RegPath.MaximumLength,
335  TAG_LDR_WSTR);
336 
337  /* Check if this allocation was unsuccessful */
338  if (!RegPath.Buffer) return STATUS_INSUFFICIENT_RESOURCES;
339 
340  /* Build and append the service name itself */
341  RegPath.Length = ServicesKeyName.Length;
342  RtlCopyMemory(RegPath.Buffer,
343  ServicesKeyName.Buffer,
344  ServicesKeyName.Length);
345 
346  /* Check if there is a dot in the filename */
347  if (wcschr(ImportName.Buffer, L'.'))
348  {
349  /* Remove the extension */
350  ImportName.Length = (USHORT)(wcschr(ImportName.Buffer, L'.') -
351  ImportName.Buffer) * sizeof(WCHAR);
352  }
353 
354  /* Append service name (the basename without extension) */
355  RtlAppendUnicodeStringToString(&RegPath, &ImportName);
356 
357  /* Now call the DllInit func */
358  DPRINT("Calling DllInit(%wZ)\n", &RegPath);
359  Status = DllInit(&RegPath);
360 
361  /* Clean up */
363 
364  /* Return status value which DllInitialize returned */
365  return Status;
366 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
#define TAG_LDR_WSTR
Definition: tag.h:110
#define UNICODE_NULL
Status
Definition: gdiplustypes.h:24
NTSTATUS(NTAPI * PMM_DLL_INITIALIZE)(_In_ PUNICODE_STRING RegistryPath)
Definition: iotypes.h:2850
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
PVOID NTAPI MiLocateExportName(IN PVOID DllBase, IN PCHAR ExportName)
Definition: sysldr.c:231
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
static const WCHAR ServicesKeyName[]
Definition: driver.c:31
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by IopInitializeBootDrivers(), and MiResolveImageReferences().

◆ MmChangeKernelResourceSectionProtection()

BOOLEAN NTAPI MmChangeKernelResourceSectionProtection ( IN ULONG_PTR  ProtectionMask)

Definition at line 2293 of file sysldr.c.

2294 {
2295  PMMPTE PointerPte;
2296  MMPTE TempPte;
2297 
2298  /* Don't do anything if the resource section is already writable */
2300  return FALSE;
2301 
2302  /* If the resource section is physical, we cannot change its protection */
2304  return FALSE;
2305 
2306  /* Loop the PTEs */
2307  for (PointerPte = MiKernelResourceStartPte; PointerPte < MiKernelResourceEndPte; ++PointerPte)
2308  {
2309  /* Read the PTE */
2310  TempPte = *PointerPte;
2311 
2312  /* Update the protection */
2313  MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, ProtectionMask, TempPte.u.Hard.PageFrameNumber);
2314  MI_UPDATE_VALID_PTE(PointerPte, TempPte);
2315  }
2316 
2317  /* Only flush the current processor's TLB */
2318  KeFlushCurrentTb();
2319  return TRUE;
2320 }
PMMPTE MiKernelResourceEndPte
Definition: sysldr.c:49
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define NULL
Definition: types.h:112
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:778
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
FORCEINLINE VOID MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:982
PMMPTE MiKernelResourceStartPte
Definition: sysldr.c:49
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:312
ULONG PageFrameNumber
Definition: mmtypes.h:109

Referenced by DisplayBootBitmap(), and MmMakeKernelResourceSectionWritable().

◆ MmCheckSystemImage()

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

Definition at line 2707 of file sysldr.c.

2709 {
2710  NTSTATUS Status;
2711  HANDLE SectionHandle;
2712  PVOID ViewBase = NULL;
2713  SIZE_T ViewSize = 0;
2715  FILE_STANDARD_INFORMATION FileStandardInfo;
2717  PIMAGE_NT_HEADERS NtHeaders;
2719  PAGED_CODE();
2720 
2721  /* Setup the object attributes */
2723  NULL,
2725  NULL,
2726  NULL);
2727 
2728  /* Create a section for the DLL */
2729  Status = ZwCreateSection(&SectionHandle,
2732  NULL,
2733  PAGE_EXECUTE,
2734  SEC_IMAGE,
2735  ImageHandle);
2736  if (!NT_SUCCESS(Status))
2737  {
2738  DPRINT1("ZwCreateSection failed with status 0x%x\n", Status);
2739  return Status;
2740  }
2741 
2742  /* Make sure we're in the system process */
2744 
2745  /* Map it */
2746  Status = ZwMapViewOfSection(SectionHandle,
2747  NtCurrentProcess(),
2748  &ViewBase,
2749  0,
2750  0,
2751  NULL,
2752  &ViewSize,
2753  ViewShare,
2754  0,
2755  PAGE_EXECUTE);
2756  if (!NT_SUCCESS(Status))
2757  {
2758  /* We failed, close the handle and return */
2759  DPRINT1("ZwMapViewOfSection failed with status 0x%x\n", Status);
2761  ZwClose(SectionHandle);
2762  return Status;
2763  }
2764 
2765  /* Now query image information */
2766  Status = ZwQueryInformationFile(ImageHandle,
2767  &IoStatusBlock,
2768  &FileStandardInfo,
2769  sizeof(FileStandardInfo),
2771  if (NT_SUCCESS(Status))
2772  {
2773  /* First, verify the checksum */
2775  ViewSize,
2776  FileStandardInfo.
2777  EndOfFile.LowPart))
2778  {
2779  /* Set checksum failure */
2781  goto Fail;
2782  }
2783 
2784  /* Make sure it's a real image */
2785  NtHeaders = RtlImageNtHeader(ViewBase);
2786  if (!NtHeaders)
2787  {
2788  /* Set checksum failure */
2790  goto Fail;
2791  }
2792 
2793  /* Make sure it's for the correct architecture */
2794  if ((NtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_NATIVE) ||
2796  {
2797  /* Set protection failure */
2799  goto Fail;
2800  }
2801 
2802  /* Check that it's a valid SMP image if we have more then one CPU */
2803  if (!MmVerifyImageIsOkForMpUse(ViewBase))
2804  {
2805  /* Otherwise it's not the right image */
2807  }
2808  }
2809 
2810  /* Unmap the section, close the handle, and return status */
2811 Fail:
2812  ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
2814  ZwClose(SectionHandle);
2815  return Status;
2816 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
KAPC_STATE
Definition: ketypes.h:1280
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
int Fail
Definition: ehthrow.cxx:24
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum(_In_ PVOID BaseAddress, _In_ SIZE_T NumberOfBytes, _In_ ULONG FileLength)
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
#define STATUS_IMAGE_MP_UP_MISMATCH
Definition: ntstatus.h:717
#define PAGE_EXECUTE
Definition: nt_native.h:1306
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define STATUS_IMAGE_CHECKSUM_MISMATCH
Definition: ntstatus.h:677
Status
Definition: gdiplustypes.h:24
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:540
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN NTAPI MmVerifyImageIsOkForMpUse(IN PVOID BaseAddress)
Definition: sysldr.c:2683
KPROCESS Pcb
Definition: pstypes.h:1262
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
ULONG_PTR SIZE_T
Definition: typedefs.h:80
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1679
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define IMAGE_NT_OPTIONAL_HDR_MAGIC
Definition: ntimage.h:387
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
#define RtlImageNtHeader
Definition: compat.h:665
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:404
#define SECTION_MAP_EXECUTE
Definition: nt_native.h:1290
#define SEC_IMAGE
Definition: mmtypes.h:96
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define PAGED_CODE()

Referenced by MmLoadSystemImage(), and PsLocateSystemDll().

◆ MmFreeDriverInitialization()

VOID NTAPI MmFreeDriverInitialization ( IN PLDR_DATA_TABLE_ENTRY  LdrEntry)

Definition at line 1635 of file sysldr.c.

1636 {
1637  PMMPTE StartPte, EndPte;
1638  PFN_NUMBER PageCount;
1639  PVOID DllBase;
1640  ULONG i;
1641  PIMAGE_NT_HEADERS NtHeader;
1642  PIMAGE_SECTION_HEADER Section, DiscardSection;
1643 
1644  /* Get the base address and the page count */
1645  DllBase = LdrEntry->DllBase;
1646  PageCount = LdrEntry->SizeOfImage >> PAGE_SHIFT;
1647 
1648  /* Get the last PTE in this image */
1649  EndPte = MiAddressToPte(DllBase) + PageCount;
1650 
1651  /* Get the NT header */
1652  NtHeader = RtlImageNtHeader(DllBase);
1653  if (!NtHeader) return;
1654 
1655  /* Get the last section and loop each section backwards */
1656  Section = IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections;
1657  DiscardSection = NULL;
1658  for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++)
1659  {
1660  /* Go back a section and check if it's discardable */
1661  Section--;
1663  {
1664  /* It is, select it for freeing */
1665  DiscardSection = Section;
1666  }
1667  else
1668  {
1669  /* No more discardable sections exist, bail out */
1670  break;
1671  }
1672  }
1673 
1674  /* Bail out if there's nothing to free */
1675  if (!DiscardSection) return;
1676 
1677  /* Push the DLL base to the first disacrable section, and get its PTE */
1678  DllBase = (PVOID)ROUND_TO_PAGES((ULONG_PTR)DllBase + DiscardSection->VirtualAddress);
1679  ASSERT(MI_IS_PHYSICAL_ADDRESS(DllBase) == FALSE);
1680  StartPte = MiAddressToPte(DllBase);
1681 
1682  /* Check how many pages to free total */
1683  PageCount = (PFN_NUMBER)(EndPte - StartPte);
1684  if (!PageCount) return;
1685 
1686  /* Delete this many PTEs */
1687  MiDeleteSystemPageableVm(StartPte, PageCount, 0, NULL);
1688 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
void * PVOID
Definition: retypes.h:9
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define ASSERT(a)
Definition: mode.c:44
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
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
#define ROUND_TO_PAGES(Size)
#define NULL
Definition: types.h:112
#define RtlImageNtHeader
Definition: compat.h:665
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235

Referenced by IopInitializeDriverModule().

◆ MmGetSystemRoutineAddress()

PVOID NTAPI MmGetSystemRoutineAddress ( IN PUNICODE_STRING  SystemRoutineName)

Definition at line 3514 of file sysldr.c.

3515 {
3516  PVOID ProcAddress = NULL;
3517  ANSI_STRING AnsiRoutineName;
3518  NTSTATUS Status;
3519  PLIST_ENTRY NextEntry;
3520  PLDR_DATA_TABLE_ENTRY LdrEntry;
3521  BOOLEAN Found = FALSE;
3522  UNICODE_STRING KernelName = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
3524  ULONG Modules = 0;
3525 
3526  /* Convert routine to ansi name */
3527  Status = RtlUnicodeStringToAnsiString(&AnsiRoutineName,
3528  SystemRoutineName,
3529  TRUE);
3530  if (!NT_SUCCESS(Status)) return NULL;
3531 
3532  /* Lock the list */
3535 
3536  /* Loop the loaded module list */
3537  NextEntry = PsLoadedModuleList.Flink;
3538  while (NextEntry != &PsLoadedModuleList)
3539  {
3540  /* Get the entry */
3541  LdrEntry = CONTAINING_RECORD(NextEntry,
3543  InLoadOrderLinks);
3544 
3545  /* Check if it's the kernel or HAL */
3546  if (RtlEqualUnicodeString(&KernelName, &LdrEntry->BaseDllName, TRUE))
3547  {
3548  /* Found it */
3549  Found = TRUE;
3550  Modules++;
3551  }
3552  else if (RtlEqualUnicodeString(&HalName, &LdrEntry->BaseDllName, TRUE))
3553  {
3554  /* Found it */
3555  Found = TRUE;
3556  Modules++;
3557  }
3558 
3559  /* Check if we found a valid binary */
3560  if (Found)
3561  {
3562  /* Find the procedure name */
3563  ProcAddress = MiFindExportedRoutineByName(LdrEntry->DllBase,
3564  &AnsiRoutineName);
3565 
3566  /* Break out if we found it or if we already tried both modules */
3567  if (ProcAddress) break;
3568  if (Modules == 2) break;
3569  }
3570 
3571  /* Keep looping */
3572  NextEntry = NextEntry->Flink;
3573  }
3574 
3575  /* Release the lock */
3578 
3579  /* Free the string and return */
3580  RtlFreeAnsiString(&AnsiRoutineName);
3581  return ProcAddress;
3582 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:37
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
LONG NTSTATUS
Definition: precomp.h:26
PVOID DllBase
Definition: btrfs_drv.h:1926
#define FALSE
Definition: types.h:117
PWCHAR HalName
Definition: halacpi.c:45
unsigned char BOOLEAN
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
return Found
Definition: dirsup.c:1270
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
static const WCHAR L[]
Definition: oid.c:1250
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define NULL
Definition: types.h:112
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
unsigned int ULONG
Definition: retypes.h:1
PVOID NTAPI MiFindExportedRoutineByName(IN PVOID DllBase, IN PANSI_STRING ExportName)
Definition: sysldr.c:490
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

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 2898 of file sysldr.c.

2904 {
2905  PVOID ModuleLoadBase = NULL;
2906  NTSTATUS Status;
2910  PIMAGE_NT_HEADERS NtHeader;
2911  UNICODE_STRING BaseName, BaseDirectory, PrefixName, UnicodeTemp;
2912  PLDR_DATA_TABLE_ENTRY LdrEntry = NULL;
2913  ULONG EntrySize, DriverSize;
2914  PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
2915  PCHAR MissingApiName, Buffer;
2916  PWCHAR MissingDriverName;
2917  HANDLE SectionHandle;
2919  PSECTION Section = NULL;
2920  BOOLEAN LockOwned = FALSE;
2921  PLIST_ENTRY NextEntry;
2922  IMAGE_INFO ImageInfo;
2923  STRING AnsiTemp;
2924  PAGED_CODE();
2925 
2926  /* Detect session-load */
2927  if (Flags)
2928  {
2929  /* Sanity checks */
2930  ASSERT(NamePrefix == NULL);
2931  ASSERT(LoadedName == NULL);
2932 
2933  /* Make sure the process is in session too */
2934  if (!PsGetCurrentProcess()->ProcessInSession) return STATUS_NO_MEMORY;
2935  }
2936 
2937  /* Allocate a buffer we'll use for names */
2940  TAG_LDR_WSTR);
2942 
2943  /* Check for a separator */
2944  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
2945  {
2946  PWCHAR p;
2947  ULONG BaseLength;
2948 
2949  /* Loop the path until we get to the base name */
2950  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
2951  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
2952 
2953  /* Get the length */
2954  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
2955  BaseLength *= sizeof(WCHAR);
2956 
2957  /* Setup the string */
2958  BaseName.Length = (USHORT)BaseLength;
2959  BaseName.Buffer = p;
2960  }
2961  else
2962  {
2963  /* Otherwise, we already have a base name */
2964  BaseName.Length = FileName->Length;
2965  BaseName.Buffer = FileName->Buffer;
2966  }
2967 
2968  /* Setup the maximum length */
2969  BaseName.MaximumLength = BaseName.Length;
2970 
2971  /* Now compute the base directory */
2972  BaseDirectory = *FileName;
2973  BaseDirectory.Length -= BaseName.Length;
2974  BaseDirectory.MaximumLength = BaseDirectory.Length;
2975 
2976  /* And the prefix, which for now is just the name itself */
2977  PrefixName = *FileName;
2978 
2979  /* Check if we have a prefix */
2980  if (NamePrefix) DPRINT1("Prefixed images are not yet supported!\n");
2981 
2982  /* Check if we already have a name, use it instead */
2983  if (LoadedName) BaseName = *LoadedName;
2984 
2985  /* Check for loader snap debugging */
2987  {
2988  /* Print out standard string */
2989  DPRINT1("MM:SYSLDR Loading %wZ (%wZ) %s\n",
2990  &PrefixName, &BaseName, Flags ? "in session space" : "");
2991  }
2992 
2993  /* Acquire the load lock */
2994 LoaderScan:
2995  ASSERT(LockOwned == FALSE);
2996  LockOwned = TRUE;
3000  KernelMode,
3001  FALSE,
3002  NULL);
3003 
3004  /* Scan the module list */
3005  NextEntry = PsLoadedModuleList.Flink;
3006  while (NextEntry != &PsLoadedModuleList)
3007  {
3008  /* Get the entry and compare the names */
3009  LdrEntry = CONTAINING_RECORD(NextEntry,
3011  InLoadOrderLinks);
3012  if (RtlEqualUnicodeString(&PrefixName, &LdrEntry->FullDllName, TRUE))
3013  {
3014  /* Found it, break out */
3015  break;
3016  }
3017 
3018  /* Keep scanning */
3019  NextEntry = NextEntry->Flink;
3020  }
3021 
3022  /* Check if we found the image */
3023  if (NextEntry != &PsLoadedModuleList)
3024  {
3025  /* Check if we had already mapped a section */
3026  if (Section)
3027  {
3028  /* Dereference and clear */
3029  ObDereferenceObject(Section);
3030  Section = NULL;
3031  }
3032 
3033  /* Check if this was supposed to be a session load */
3034  if (!Flags)
3035  {
3036  /* It wasn't, so just return the data */
3037  *ModuleObject = LdrEntry;
3038  *ImageBaseAddress = LdrEntry->DllBase;
3040  }
3041  else
3042  {
3043  /* We don't support session loading yet */
3044  UNIMPLEMENTED_DBGBREAK("Unsupported Session-Load!\n");
3046  }
3047 
3048  /* Do cleanup */
3049  goto Quickie;
3050  }
3051  else if (!Section)
3052  {
3053  /* It wasn't loaded, and we didn't have a previous attempt */
3056  LockOwned = FALSE;
3057 
3058  /* Check if KD is enabled */
3060  {
3061  /* FIXME: Attempt to get image from KD */
3062  }
3063 
3064  /* We don't have a valid entry */
3065  LdrEntry = NULL;
3066 
3067  /* Setup image attributes */
3069  FileName,
3071  NULL,
3072  NULL);
3073 
3074  /* Open the image */
3076  FILE_EXECUTE,
3078  &IoStatusBlock,
3080  0);
3081  if (!NT_SUCCESS(Status))
3082  {
3083  DPRINT1("ZwOpenFile failed for '%wZ' with status 0x%x\n",
3084  FileName, Status);
3085  goto Quickie;
3086  }
3087 
3088  /* Validate it */
3093  {
3094  /* Fail loading */
3095  goto Quickie;
3096  }
3097 
3098  /* Check if this is a session-load */
3099  if (Flags)
3100  {
3101  /* Then we only need read and execute */
3103  }
3104  else
3105  {
3106  /* Otherwise, we can allow write access */
3108  }
3109 
3110  /* Initialize the attributes for the section */
3112  NULL,
3114  NULL,
3115  NULL);
3116 
3117  /* Create the section */
3118  Status = ZwCreateSection(&SectionHandle,
3119  DesiredAccess,
3121  NULL,
3122  PAGE_EXECUTE,
3123  SEC_IMAGE,
3124  FileHandle);
3125  if (!NT_SUCCESS(Status))
3126  {<