ntdll: Randomize security cookie when available

André Hentschel nerv at dawncrow.de
Sun Jun 21 09:56:49 CDT 2015


Tested on x86, x86_64 and arm64
(Haven't found a suitable binary for arm yet)

https://bugs.winehq.org/show_bug.cgi?id=38714

---
 dlls/ntdll/virtual.c | 23 +++++++++++++++++++++++
 include/winnt.h      | 35 +++++++++++++++++++++++++++++++++--
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 72309f6..7f74fd0 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1053,6 +1053,24 @@ static NTSTATUS stat_mapping_file( struct file_view *view, struct stat *st )
     return status;
 }
 
+static void set_security_cookie(const char *base, const IMAGE_NT_HEADERS *nt)
+{
+    DWORD addr;
+
+    if(IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG < nt->OptionalHeader.NumberOfRvaAndSizes &&
+       (addr = nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].VirtualAddress))
+    {
+        IMAGE_LOAD_CONFIG_DIRECTORY *loadcfg = (IMAGE_LOAD_CONFIG_DIRECTORY *)(base + addr);
+        PULONG_PTR cookie = (PULONG_PTR)loadcfg->SecurityCookie;
+
+        srand( time( NULL ) );
+        *cookie = rand();
+#ifdef _WIN64
+        /* Fill up, but keep the highest word clear */
+        *cookie ^= (ULONGLONG)rand() << 16;
+#endif
+    }
+}
 
 /***********************************************************************
  *           map_image
@@ -1278,6 +1296,11 @@ static NTSTATUS map_image( HANDLE hmapping, int fd, char *base, SIZE_T total_siz
         }
     }
 
+
+    /* adjust security cookie */
+
+    set_security_cookie( ptr, nt );
+
     /* set the image protections */
 
     VIRTUAL_SetProt( view, ptr, ROUND_SIZE( 0, header_size ), VPROT_COMMITTED | VPROT_READ );
diff --git a/include/winnt.h b/include/winnt.h
index 08e7f48..d077005 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -3620,7 +3620,30 @@ typedef struct _FPO_DATA {
   WORD  cbFrame  : 2;
 } FPO_DATA, *PFPO_DATA;
 
-typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY {
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64 {
+  DWORD     Size;
+  DWORD     TimeDateStamp;
+  WORD      MajorVersion;
+  WORD      MinorVersion;
+  DWORD     GlobalFlagsClear;
+  DWORD     GlobalFlagsSet;
+  DWORD     CriticalSectionDefaultTimeout;
+  ULONGLONG DeCommitFreeBlockThreshold;
+  ULONGLONG DeCommitTotalFreeThreshold;
+  ULONGLONG LockPrefixTable;
+  ULONGLONG MaximumAllocationSize;
+  ULONGLONG VirtualMemoryThreshold;
+  ULONGLONG ProcessAffinityMask;
+  DWORD     ProcessHeapFlags;
+  WORD      CSDVersion;
+  WORD      Reserved1;
+  ULONGLONG EditList;
+  ULONGLONG SecurityCookie;
+  ULONGLONG SEHandlerTable;
+  ULONGLONG SEHandlerCount;
+} IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;
+
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32 {
   DWORD Size;
   DWORD TimeDateStamp;
   WORD  MajorVersion;
@@ -3641,7 +3664,15 @@ typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY {
   DWORD SecurityCookie;
   DWORD SEHandlerTable;
   DWORD SEHandlerCount;
-} IMAGE_LOAD_CONFIG_DIRECTORY, *PIMAGE_LOAD_CONFIG_DIRECTORY;
+} IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32;
+
+#ifdef _WIN64
+typedef IMAGE_LOAD_CONFIG_DIRECTORY64   IMAGE_LOAD_CONFIG_DIRECTORY;
+typedef PIMAGE_LOAD_CONFIG_DIRECTORY64  PIMAGE_LOAD_CONFIG_DIRECTORY;
+#else
+typedef IMAGE_LOAD_CONFIG_DIRECTORY32   IMAGE_LOAD_CONFIG_DIRECTORY;
+typedef PIMAGE_LOAD_CONFIG_DIRECTORY32  PIMAGE_LOAD_CONFIG_DIRECTORY;
+#endif
 
 typedef struct _IMAGE_FUNCTION_ENTRY {
   DWORD StartingAddress;
-- 
1.9.1




More information about the wine-patches mailing list