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