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