Loader Section Protection

Filip Navara navaraf at reactos.com
Sun Jun 20 07:46:46 CDT 2004


Changelog:
Unprotect Import Address Table while filling it (since it can be in 
read-only section) and also unprotect all image sections during relocation.
-------------- next part --------------
--- dlls/ntdll/loader.c	Tue Apr 20 00:36:30 2004
+++ dlls/ntdll/loader.c	Sat Jun 12 16:23:34 2004
@@ -371,6 +371,9 @@
     WCHAR buffer[32];
     char *name = get_rva( module, descr->Name );
     DWORD len = strlen(name) + 1;
+    PVOID protect_base;
+    DWORD protect_size = 0;
+    DWORD protect_old;
 
     thunk_list = get_rva( module, (DWORD)descr->FirstThunk );
     if (descr->u.OriginalFirstThunk)
@@ -403,6 +406,20 @@
         return NULL;
     }
 
+    /* unprotect the import address table since it can be located in
+     * readonly section */
+    while (import_list[protect_size].u1.Ordinal)
+        protect_size++;
+    protect_base = thunk_list;
+    protect_size *= sizeof(PVOID *);
+    status = NtProtectVirtualMemory( GetCurrentProcess(), &protect_base,
+                                     &protect_size, PAGE_READWRITE, &protect_old );
+    if (status)
+    {
+        ERR("Can't unprotect IAT for %s\n", name);
+        return NULL;
+    }
+
     imp_mod = wmImp->ldr.BaseAddress;
     exports = RtlImageDirectoryEntryToData( imp_mod, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size );
 
@@ -427,6 +444,11 @@
             import_list++;
             thunk_list++;
         }
+
+        /* restore old protection of the import address table */
+        NtProtectVirtualMemory( GetCurrentProcess(), &protect_base,
+                                &protect_size, protect_old, NULL );
+        
         return wmImp;
     }
 
@@ -463,6 +485,11 @@
         import_list++;
         thunk_list++;
     }
+
+    /* restore old protection of the import address table */
+    NtProtectVirtualMemory( GetCurrentProcess(), &protect_base,
+                            &protect_size, protect_old, NULL );
+    
     return wmImp;
 }
 
--- dlls/ntdll/virtual.c	Tue Apr  6 23:13:48 2004
+++ dlls/ntdll/virtual.c	Sat Jun 12 17:10:06 2004
@@ -511,6 +511,10 @@
                            int delta, DWORD total_size )
 {
     IMAGE_BASE_RELOCATION *rel;
+    NTSTATUS status;
+    PVOID protect_base;
+    DWORD protect_size = page_size;
+    DWORD protect_old;
 
     TRACE_(module)( "relocating from %p-%p to %p-%p\n",
                     base - delta, base - delta + total_size, base, base + total_size );
@@ -537,6 +541,16 @@
 
         TRACE_(module)("%ld relocations for page %lx\n", rel->SizeOfBlock, rel->VirtualAddress);
 
+        /* unprotect the page we're about to relocate */
+        protect_base = page;
+        status = NtProtectVirtualMemory( GetCurrentProcess(), &protect_base,
+                                         &protect_size, PAGE_READWRITE, &protect_old );
+        if (status)
+        {
+            ERR("Can't unprotect page during relocation\n");
+            return 0;
+        }
+
         /* patching in reverse order */
         for (i = 0 ; i < count; i++)
         {
@@ -561,6 +575,10 @@
                 break;
             }
         }
+
+        /* restore old protection */
+        NtProtectVirtualMemory( GetCurrentProcess(), &protect_base,
+                                &protect_size, protect_old, NULL );
     }
     return 1;
 }


More information about the wine-patches mailing list