[PATCH] ntdll: Fix QueryVirtual information on builtin DLLs

Marcus Meissner marcus at jet.franken.de
Tue Jul 6 03:09:34 CDT 2010


Hi,

Make sure we report the correct flags in NtQueryVirtualMemory.

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
(not yet checked if it fixes the above problem itself.)

Ciao, Marcus
---
 dlls/ntdll/loader.c     |   19 ++++++++++++++++---
 dlls/ntdll/tests/info.c |   14 +++++++-------
 dlls/ntdll/virtual.c    |    5 ++++-
 3 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 4a2641b..628c33d 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -1389,9 +1389,11 @@ static void load_builtin_callback( void *module, const char *filename )
 {
     static const WCHAR emptyW[1];
     IMAGE_NT_HEADERS *nt;
+    IMAGE_SECTION_HEADER *sec;
     WINE_MODREF *wm;
     WCHAR *fullname;
     const WCHAR *load_path;
+    int i;
 
     if (!module)
     {
@@ -1404,9 +1406,20 @@ 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 );
+    sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader+nt->FileHeader.SizeOfOptionalHeader);
+    /* This view creation is for the sake of NtQueryVirtualMemory, the data is mapped already by dlopen. */
+    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;
+        /* The section handling is incomplete for real PE binaries/dlls, but is sufficient
+         * for the builtin ones generated by Wine */
+        virtual_create_system_view( (char*)module + sec[i].VirtualAddress, sec[i].Misc.VirtualSize, flags );
+       
+    }
 
     /* create the MODREF */
 
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 13c29f8..efd5343 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -981,15 +981,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);
@@ -999,7 +999,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);
@@ -1007,7 +1007,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);
@@ -1016,13 +1016,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..5181907 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -2179,7 +2179,10 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
         info->Protect = (vprot & VPROT_COMMITTED) ? VIRTUAL_GetWin32Prot( vprot ) : 0;
         info->AllocationBase = alloc_base;
         info->AllocationProtect = VIRTUAL_GetWin32Prot( view->protect );
-        if (view->protect & VPROT_IMAGE) info->Type = MEM_IMAGE;
+        if (view->protect & VPROT_IMAGE) {
+            info->Type = MEM_IMAGE;
+            info->AllocationProtect = PAGE_EXECUTE_WRITECOPY;
+        }
         else if (view->protect & VPROT_VALLOC) info->Type = MEM_PRIVATE;
         else info->Type = MEM_MAPPED;
         for (size = base - alloc_base; size < base + range_size - alloc_base; size += page_size)
-- 
1.5.6



More information about the wine-patches mailing list