Paul Gofman : ntoskrnl.exe/tests: Add a test for accessing process memory.

Alexandre Julliard julliard at winehq.org
Mon Jun 1 15:14:55 CDT 2020


Module: wine
Branch: master
Commit: 64946e554303b7ae6d2dbf7f4a2c69412424d136
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=64946e554303b7ae6d2dbf7f4a2c69412424d136

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Sun May 31 18:26:25 2020 +0300

ntoskrnl.exe/tests: Add a test for accessing process memory.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntoskrnl.exe/tests/driver.c   | 66 ++++++++++++++++++++++++++++++++++++++
 dlls/ntoskrnl.exe/tests/driver.h   |  3 ++
 dlls/ntoskrnl.exe/tests/ntoskrnl.c | 10 +++++-
 3 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index ba2b4d6ac8..f51064986b 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -2067,6 +2067,71 @@ static void test_dpc(void)
     KeRevertToUserAffinityThread();
 }
 
+static void test_process_memory(const struct test_input *test_input)
+{
+    NTSTATUS (WINAPI *pMmCopyVirtualMemory)(PEPROCESS fromprocess, void *fromaddress, PEPROCESS toprocess,
+            void *toaddress, SIZE_T bufsize, KPROCESSOR_MODE mode, SIZE_T *copied);
+    char buffer[sizeof(teststr)];
+    ULONG64 modified_value;
+    PEPROCESS process;
+    KAPC_STATE state;
+    NTSTATUS status;
+    SIZE_T size;
+    BYTE *base;
+
+    pMmCopyVirtualMemory = get_proc_address("MmCopyVirtualMemory");
+
+    status = PsLookupProcessByProcessId((HANDLE)(ULONG_PTR)test_input->process_id, &process);
+    ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
+
+    if (status)
+        return;
+
+    if (0) /* Crashes on Windows. */
+        PsGetProcessSectionBaseAddress(NULL);
+
+    base = PsGetProcessSectionBaseAddress(process);
+    ok(!!base, "Got NULL base address.\n");
+
+    ok(process == PsGetCurrentProcess(), "Got unexpected process %p, PsGetCurrentProcess() %p.\n",
+            process, PsGetCurrentProcess());
+
+    modified_value = 0xdeadbeeffeedcafe;
+    if (pMmCopyVirtualMemory)
+    {
+        size = 0xdeadbeef;
+        status = pMmCopyVirtualMemory(process, base + test_input->teststr_offset, PsGetCurrentProcess(),
+                buffer, sizeof(buffer), UserMode, &size);
+        todo_wine ok(status == STATUS_ACCESS_VIOLATION, "Got unexpected status %#x.\n", status);
+        ok(!size, "Got unexpected size %#lx.\n", size);
+
+        memset(buffer, 0, sizeof(buffer));
+        size = 0xdeadbeef;
+        if (0)  /* Passing NULL for the copied size address hangs Windows. */
+            pMmCopyVirtualMemory(process, base + test_input->teststr_offset, PsGetCurrentProcess(),
+                                 buffer, sizeof(buffer), KernelMode, NULL);
+        status = pMmCopyVirtualMemory(process, base + test_input->teststr_offset, PsGetCurrentProcess(),
+                buffer, sizeof(buffer), KernelMode, &size);
+        todo_wine ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
+        todo_wine ok(size == sizeof(buffer), "Got unexpected size %lu.\n", size);
+        todo_wine ok(!strcmp(buffer, teststr), "Got unexpected test string.\n");
+    }
+    else
+    {
+       win_skip("MmCopyVirtualMemory is not available.\n");
+    }
+
+    if (!test_input->running_under_wine)
+    {
+        KeStackAttachProcess((PKPROCESS)process, &state);
+        todo_wine ok(!strcmp(teststr, (char *)(base + test_input->teststr_offset)),
+                "Strings do not match.\n");
+        *test_input->modified_value = modified_value;
+        KeUnstackDetachProcess(&state);
+    }
+    ObDereferenceObject(process);
+}
+
 static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack)
 {
     ULONG length = stack->Parameters.DeviceIoControl.OutputBufferLength;
@@ -2122,6 +2187,7 @@ static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *st
 #endif
     test_affinity();
     test_dpc();
+    test_process_memory(test_input);
 
     if (main_test_work_item) return STATUS_UNEXPECTED_IO_ERROR;
 
diff --git a/dlls/ntoskrnl.exe/tests/driver.h b/dlls/ntoskrnl.exe/tests/driver.h
index aa9de674e2..6012efc41c 100644
--- a/dlls/ntoskrnl.exe/tests/driver.h
+++ b/dlls/ntoskrnl.exe/tests/driver.h
@@ -42,6 +42,9 @@ struct test_input
     int running_under_wine;
     int winetest_report_success;
     int winetest_debug;
+    DWORD process_id;
+    SIZE_T teststr_offset;
+    ULONG64 *modified_value;
     WCHAR path[1];
 };
 
diff --git a/dlls/ntoskrnl.exe/tests/ntoskrnl.c b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
index 2535ed903e..8d2da92455 100644
--- a/dlls/ntoskrnl.exe/tests/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/tests/ntoskrnl.c
@@ -148,8 +148,9 @@ static void main_test(void)
     static const WCHAR dokW[] = {'d','o','k',0};
     WCHAR temppathW[MAX_PATH], pathW[MAX_PATH];
     struct test_input *test_input;
-    UNICODE_STRING pathU;
     DWORD len, written, read;
+    ULONG64 modified_value;
+    UNICODE_STRING pathU;
     LONG new_failures;
     char buffer[512];
     HANDLE okfile;
@@ -165,6 +166,11 @@ static void main_test(void)
     test_input->running_under_wine = !strcmp(winetest_platform, "wine");
     test_input->winetest_report_success = winetest_report_success;
     test_input->winetest_debug = winetest_debug;
+    test_input->process_id = GetCurrentProcessId();
+    test_input->teststr_offset = (SIZE_T)((BYTE *)&teststr - (BYTE *)NtCurrentTeb()->Peb->ImageBaseAddress);
+    test_input->modified_value = &modified_value;
+    modified_value = 0;
+
     memcpy(test_input->path, pathU.Buffer, len);
     res = DeviceIoControl(device, IOCTL_WINETEST_MAIN_TEST, test_input,
                           offsetof( struct test_input, path[len / sizeof(WCHAR)]),
@@ -172,6 +178,8 @@ static void main_test(void)
     ok(res, "DeviceIoControl failed: %u\n", GetLastError());
     ok(written == sizeof(new_failures), "got size %x\n", written);
 
+    todo_wine ok(modified_value == 0xdeadbeeffeedcafe, "Got unexpected value %#I64x.\n", modified_value);
+
     okfile = CreateFileW(pathW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
     ok(okfile != INVALID_HANDLE_VALUE, "failed to create %s: %u\n", wine_dbgstr_w(pathW), GetLastError());
 




More information about the wine-cvs mailing list