IN OUT PLIST_ENTRY ModuleListHead,
IN PCH DllName,
OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
+
+PVOID
+PeLdrInitSecurityCookie(
+ _In_ PLDR_DATA_TABLE_ENTRY LdrEntry);
PELDR_IMPORTDLL_LOAD_CALLBACK PeLdrImportDllLoadCallback = NULL;
+#ifdef _WIN64
+#define COOKIE_MAX 0x0000FFFFFFFFFFFFll
+#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
+#else
+#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
+#endif
+
/* PRIVATE FUNCTIONS *********************************************************/
+static PVOID
+PeLdrpFetchAddressOfSecurityCookie(PVOID BaseAddress, ULONG SizeOfImage)
+{
+ PIMAGE_LOAD_CONFIG_DIRECTORY ConfigDir;
+ ULONG DirSize;
+ PULONG_PTR Cookie = NULL;
+
+ /* Get the pointer to the config directory */
+ ConfigDir = RtlImageDirectoryEntryToData(BaseAddress,
+ TRUE,
+ IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
+ &DirSize);
+
+ /* Check for sanity */
+ if (!ConfigDir ||
+ DirSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, SecurityCookie))
+ {
+ /* Invalid directory*/
+ return NULL;
+ }
+
+ /* Now get the cookie */
+ Cookie = VaToPa((PULONG_PTR)ConfigDir->SecurityCookie);
+
+ /* Check this cookie */
+ if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
+ (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage - sizeof(*Cookie))
+ {
+ Cookie = NULL;
+ }
+
+ /* Return validated security cookie */
+ return Cookie;
+}
+
/* DllName - physical, UnicodeString->Buffer - virtual */
static BOOLEAN
PeLdrpCompareDllName(
return Success;
}
+ /* Init security cookie */
+ PeLdrInitSecurityCookie(*DataTableEntry);
+
(*DataTableEntry)->Flags |= LDRP_DRIVER_DEPENDENT_DLL;
/* Scan its dependencies too */
/* FUNCTIONS *****************************************************************/
+PVOID
+PeLdrInitSecurityCookie(PLDR_DATA_TABLE_ENTRY LdrEntry)
+{
+ PULONG_PTR Cookie;
+ ULONG_PTR NewCookie;
+
+ /* Fetch address of the cookie */
+ Cookie = PeLdrpFetchAddressOfSecurityCookie(VaToPa(LdrEntry->DllBase), LdrEntry->SizeOfImage);
+
+ if (!Cookie)
+ return NULL;
+
+ /* Check if it's a default one */
+ if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
+ (*Cookie == 0))
+ {
+ /* Generate new cookie using cookie address and time as seed */
+ NewCookie = (ULONG_PTR)Cookie ^ (ULONG_PTR)ArcGetRelativeTime();
+#ifdef _WIN64
+ /* Some images expect first 16 bits to be kept clean (like in default cookie) */
+ if (NewCookie > COOKIE_MAX)
+ {
+ NewCookie >>= 16;
+ }
+#endif
+ /* If the result is 0 or the same as we got, just add one to the default value */
+ if ((NewCookie == 0) || (NewCookie == *Cookie))
+ {
+ NewCookie = DEFAULT_SECURITY_COOKIE + 1;
+ }
+
+ /* Set the new cookie value */
+ *Cookie = NewCookie;
+ }
+
+ return Cookie;
+}
+
/* Returns TRUE if DLL has already been loaded - looks in LoadOrderList in LPB */
BOOLEAN
PeLdrCheckForLoadedDll(
return FALSE;
}
+ /* Init security cookie */
+ PeLdrInitSecurityCookie(*DriverDTE);
+
// Modify any flags, if needed
(*DriverDTE)->Flags |= Flags;
/* Cleanup and bail out */
ERR("PeLdrAllocateDataTableEntry('%s') failed\n", FullFileName);
MmFreeMemory(BaseAddress);
- BaseAddress = NULL;
+ return NULL;
}
+ /* Init security cookie */
+ PeLdrInitSecurityCookie(*Dte);
+
return BaseAddress;
}
ULONG_PTR MmPteCodeStart, MmPteCodeEnd;
#ifdef _WIN64
+#define COOKIE_MAX 0x0000FFFFFFFFFFFFll
#define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
#else
#define DEFAULT_SECURITY_COOKIE 0xBB40E64E
{
PIMAGE_LOAD_CONFIG_DIRECTORY ConfigDir;
ULONG DirSize;
- PVOID Cookie = NULL;
-
- /* Check NT header first */
- if (!RtlImageNtHeader(BaseAddress)) return NULL;
+ PULONG_PTR Cookie = NULL;
/* Get the pointer to the config directory */
ConfigDir = RtlImageDirectoryEntryToData(BaseAddress,
/* Check for sanity */
if (!ConfigDir ||
- DirSize < FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, SEHandlerTable) || /* SEHandlerTable is after SecurityCookie */
- (ConfigDir->Size != DirSize))
+ DirSize < RTL_SIZEOF_THROUGH_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, SecurityCookie))
{
/* Invalid directory*/
return NULL;
}
/* Now get the cookie */
- Cookie = (PVOID)ConfigDir->SecurityCookie;
+ Cookie = (PULONG_PTR)ConfigDir->SecurityCookie;
/* Check this cookie */
if ((PCHAR)Cookie <= (PCHAR)BaseAddress ||
- (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage)
+ (PCHAR)Cookie >= (PCHAR)BaseAddress + SizeOfImage - sizeof(*Cookie))
{
Cookie = NULL;
}
/* Fetch address of the cookie */
Cookie = LdrpFetchAddressOfSecurityCookie(LdrEntry->DllBase, LdrEntry->SizeOfImage);
- if (Cookie)
+ if (!Cookie)
+ return NULL;
+
+ /* Check if it's a default one */
+ if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
+ (*Cookie == 0))
{
- /* Check if it's a default one */
- if ((*Cookie == DEFAULT_SECURITY_COOKIE) ||
- (*Cookie == 0))
- {
- LARGE_INTEGER Counter = KeQueryPerformanceCounter(NULL);
- /* The address should be unique */
- NewCookie = (ULONG_PTR)Cookie;
-
- /* We just need a simple tick, don't care about precision and whatnot */
- NewCookie ^= (ULONG_PTR)Counter.LowPart;
-
- /* If the result is 0 or the same as we got, just add one to the default value */
- if ((NewCookie == 0) || (NewCookie == *Cookie))
- {
- NewCookie = DEFAULT_SECURITY_COOKIE + 1;
- }
+ LARGE_INTEGER Counter = KeQueryPerformanceCounter(NULL);
+ /* The address should be unique */
+ NewCookie = (ULONG_PTR)Cookie;
- /* Set the new cookie value */
- *Cookie = NewCookie;
+ /* We just need a simple tick, don't care about precision and whatnot */
+ NewCookie ^= (ULONG_PTR)Counter.LowPart;
+#ifdef _WIN64
+ /* Some images expect first 16 bits to be kept clean (like in default cookie) */
+ if (NewCookie > COOKIE_MAX)
+ {
+ NewCookie >>= 16;
+ }
+#endif
+ /* If the result is 0 or the same as we got, just add one to the default value */
+ if ((NewCookie == 0) || (NewCookie == *Cookie))
+ {
+ NewCookie = DEFAULT_SECURITY_COOKIE + 1;
}
+
+ /* Set the new cookie value */
+ *Cookie = NewCookie;
}
return Cookie;