[PATCH] ntdll: set correct protection flags on sections in builtin DLLs

Marcus Meissner marcus at jet.franken.de
Mon Aug 23 10:12:53 CDT 2010


Hi,

Make sure we report the correct flags in NtQueryVirtualMemory
on a per section basis.

Triggered by the less correct patch in:
        http://appdb.winehq.org/objectManager.php?sClass=version&iId=18971
        http://bugs.winehq.org/show_bug.cgi?id=16998

Ciao, Marcus
---
 dlls/ntdll/loader.c     |    5 ++---
 dlls/ntdll/ntdll_misc.h |    2 +-
 dlls/ntdll/tests/info.c |   14 +++++++-------
 dlls/ntdll/virtual.c    |   32 +++++++++++++++++++++++++++-----
 4 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 79ae817..0724879 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1404,9 +1404,8 @@ static void load_builtin_callback( void *module, const char *filename )
         builtin_load_info->status = STATUS_INVALID_IMAGE_FORMAT;
         return;
     }
-    virtual_create_system_view( module, nt->OptionalHeader.SizeOfImage,
-                                VPROT_SYSTEM | VPROT_IMAGE | VPROT_COMMITTED |
-                                VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC );
+
+    virtual_create_builtin_view( module );
 
     /* create the MODREF */
 
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index c7b721a..212edf5 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -155,7 +155,7 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
 
 /* virtual memory */
 extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info );
-extern NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot );
+extern NTSTATUS virtual_create_builtin_view( void *base );
 extern NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commit_size );
 extern void virtual_clear_thread_stack(void);
 extern BOOL virtual_handle_stack_fault( void *addr );
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index a56bcd1..f30c6ab 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1077,15 +1077,15 @@ static void test_queryvirtualmemory(void)
     MEMORY_BASIC_INFORMATION mbi;
     char stackbuf[42];
 
-    trace("Check flags of a function entry in NTDLL.DLL\n");
+    trace("Check flags of a function entry in NTDLL.DLL at %p\n", pNtQueryVirtualMemory);
     status = pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
     ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
     ok (mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_EXECUTE_WRITECOPY);
     ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%x\n", mbi.State, MEM_COMMIT);
-    todo_wine ok (mbi.Protect == PAGE_EXECUTE_READ, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_EXECUTE_READ);
+    ok (mbi.Protect == PAGE_EXECUTE_READ, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_EXECUTE_READ);
 
-    trace("Check flags of heap\n");
+    trace("Check flags of heap at %p\n", GetProcessHeap());
     status = pNtQueryVirtualMemory(NtCurrentProcess(), GetProcessHeap(), MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
     ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
@@ -1095,7 +1095,7 @@ static void test_queryvirtualmemory(void)
     ok (mbi.Protect == PAGE_READWRITE || mbi.Protect == PAGE_EXECUTE_READWRITE,
         "mbi.Protect is 0x%x\n", mbi.Protect);
 
-    trace("Check flags of stack\n");
+    trace("Check flags of stack at %p\n", stackbuf);
     status = pNtQueryVirtualMemory(NtCurrentProcess(), stackbuf, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
     ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
@@ -1103,7 +1103,7 @@ static void test_queryvirtualmemory(void)
     ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%x\n", mbi.State, MEM_COMMIT);
     ok (mbi.Protect == PAGE_READWRITE, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_READWRITE);
 
-    trace("Check flags of read-only data\n");
+    trace("Check flags of read-only data at %p\n", teststring);
     status = pNtQueryVirtualMemory(NtCurrentProcess(), teststring, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
     ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
@@ -1112,13 +1112,13 @@ static void test_queryvirtualmemory(void)
     if (mbi.Protect != PAGE_READONLY)
         todo_wine ok( mbi.Protect == PAGE_READONLY, "mbi.Protect is 0x%x, expected 0x%X\n", mbi.Protect, PAGE_READONLY);
 
-    trace("Check flags of read-write global data (.bss)\n");
+    trace("Check flags of read-write global data (.bss) at %p\n", rwtestbuf);
     status = pNtQueryVirtualMemory(NtCurrentProcess(), rwtestbuf, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
     ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
     ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
     ok (mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY, "mbi.AllocationProtect is 0x%x, expected 0x%x\n", mbi.AllocationProtect, PAGE_EXECUTE_WRITECOPY);
     ok (mbi.State == MEM_COMMIT, "mbi.State is 0x%x, expected 0x%X\n", mbi.State, MEM_COMMIT);
-    todo_wine ok (mbi.Protect == PAGE_READWRITE, "mbi.Protect is 0x%x, expected 0x%X\n", mbi.Protect, PAGE_READWRITE);
+    ok (mbi.Protect == PAGE_READWRITE, "mbi.Protect is 0x%x, expected 0x%X\n", mbi.Protect, PAGE_READWRITE);
 }
 
 static void test_affinity(void)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 84427fb..b25d093 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1395,18 +1395,40 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info )
 /***********************************************************************
  *           virtual_create_system_view
  */
-NTSTATUS virtual_create_system_view( void *base, SIZE_T size, DWORD vprot )
+NTSTATUS virtual_create_builtin_view( void *module )
 {
-    FILE_VIEW *view;
     NTSTATUS status;
     sigset_t sigset;
+    IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module );
+    SIZE_T size = nt->OptionalHeader.SizeOfImage;
+    IMAGE_SECTION_HEADER *sec;
+    FILE_VIEW *view;
+    void *base;
+    int i;
 
-    size = ROUND_SIZE( base, size );
-    base = ROUND_ADDR( base, page_mask );
+    size = ROUND_SIZE( module, size );
+    base = ROUND_ADDR( module, page_mask );
     server_enter_uninterrupted_section( &csVirtual, &sigset );
-    status = create_view( &view, base, size, vprot );
+    status = create_view( &view, base, size, VPROT_SYSTEM | VPROT_IMAGE |
+                          VPROT_COMMITTED | VPROT_READ | VPROT_WRITECOPY | VPROT_EXEC );
     if (!status) TRACE( "created %p-%p\n", base, (char *)base + size );
     server_leave_uninterrupted_section( &csVirtual, &sigset );
+
+    if (status) return status;
+
+    sec = (IMAGE_SECTION_HEADER *)((char *)&nt->OptionalHeader + nt->FileHeader.SizeOfOptionalHeader);
+    for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
+    {
+        DWORD flags = VPROT_SYSTEM | VPROT_IMAGE | VPROT_COMMITTED;
+
+        if (sec[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) flags |= VPROT_EXEC;
+        if (sec[i].Characteristics & IMAGE_SCN_MEM_READ) flags |= VPROT_READ;
+        if (sec[i].Characteristics & IMAGE_SCN_MEM_WRITE) flags |= VPROT_WRITE;
+        if (sec[i].Characteristics & IMAGE_SCN_MEM_SHARED) flags |= VPROT_WRITECOPY;
+        memset (view->prot + (sec[i].VirtualAddress >> page_shift), flags,
+                ROUND_SIZE( sec[i].VirtualAddress, sec[i].Misc.VirtualSize ) >> page_shift );
+    }
+
     return status;
 }
 
-- 
1.5.6




More information about the wine-patches mailing list