Alexandre Julliard : ntdll: Implement NtWow64Read/WriteVirtualMemory64().
Alexandre Julliard
julliard at winehq.org
Tue Jun 29 15:58:26 CDT 2021
Module: wine
Branch: master
Commit: bfd2d1d77d8efd7dfc0613140e6281c924c3a1c7
URL: https://source.winehq.org/git/wine.git/?a=commit;h=bfd2d1d77d8efd7dfc0613140e6281c924c3a1c7
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Jun 28 20:24:56 2021 +0200
ntdll: Implement NtWow64Read/WriteVirtualMemory64().
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/ntdll.spec | 4 +++
dlls/ntdll/tests/wow64.c | 42 +++++++++++++++++++++++++++++
dlls/ntdll/unix/virtual.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++
include/winternl.h | 16 +++++------
4 files changed, 121 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index bd72f50b864..70e752eb43b 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -430,6 +430,8 @@
@ stdcall -syscall NtWaitForSingleObject(long long ptr)
@ stub NtWaitHighEventPair
@ stub NtWaitLowEventPair
+@ stdcall -syscall -arch=win32 NtWow64ReadVirtualMemory64(long int64 ptr int64 ptr)
+@ stdcall -syscall -arch=win32 NtWow64WriteVirtualMemory64(long int64 ptr int64 ptr)
@ stdcall -syscall NtWriteFile(long long ptr ptr ptr ptr long ptr ptr)
@ stdcall -syscall NtWriteFileGather(long long ptr ptr ptr ptr long ptr ptr)
@ stub NtWriteRequestData
@@ -1444,6 +1446,8 @@
@ stdcall -private -syscall ZwWaitForSingleObject(long long ptr) NtWaitForSingleObject
@ stub ZwWaitHighEventPair
@ stub ZwWaitLowEventPair
+@ stdcall -syscall -arch=win32 ZwWow64ReadVirtualMemory64(long int64 ptr int64 ptr) NtWow64ReadVirtualMemory64
+@ stdcall -syscall -arch=win32 ZwWow64WriteVirtualMemory64(long int64 ptr int64 ptr) NtWow64WriteVirtualMemory64
@ stdcall -private -syscall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr) NtWriteFile
@ stdcall -private -syscall ZwWriteFileGather(long long ptr ptr ptr ptr long ptr ptr) NtWriteFileGather
@ stub ZwWriteRequestData
diff --git a/dlls/ntdll/tests/wow64.c b/dlls/ntdll/tests/wow64.c
index 17082d2d329..8146ab0363e 100644
--- a/dlls/ntdll/tests/wow64.c
+++ b/dlls/ntdll/tests/wow64.c
@@ -27,6 +27,9 @@ static NTSTATUS (WINAPI *pRtlWow64GetProcessMachines)(HANDLE,WORD*,WORD*);
static NTSTATUS (WINAPI *pRtlWow64IsWowGuestMachineSupported)(USHORT,BOOLEAN*);
#ifdef _WIN64
static NTSTATUS (WINAPI *pRtlWow64GetCpuAreaInfo)(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
+#else
+static NTSTATUS (WINAPI *pNtWow64ReadVirtualMemory64)(HANDLE,ULONG64,void*,ULONG64,ULONG64*);
+static NTSTATUS (WINAPI *pNtWow64WriteVirtualMemory64)(HANDLE,ULONG64,const void *,ULONG64,ULONG64*);
#endif
static BOOL is_wow64;
@@ -44,6 +47,9 @@ static void init(void)
GET_PROC( RtlWow64IsWowGuestMachineSupported );
#ifdef _WIN64
GET_PROC( RtlWow64GetCpuAreaInfo );
+#else
+ GET_PROC( NtWow64ReadVirtualMemory64 );
+ GET_PROC( NtWow64WriteVirtualMemory64 );
#endif
#undef GET_PROC
}
@@ -453,6 +459,40 @@ static void test_cpu_area(void)
else win_skip( "RtlWow64GetCpuAreaInfo not supported\n" );
}
+#else /* _WIN64 */
+
+static void test_nt_wow64(void)
+{
+ const char str[] = "hello wow64";
+ char buffer[100];
+ NTSTATUS status;
+ ULONG64 res;
+ HANDLE process = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() );
+
+ ok( process != 0, "failed to open current process %u\n", GetLastError() );
+ if (pNtWow64ReadVirtualMemory64)
+ {
+ status = pNtWow64ReadVirtualMemory64( process, (ULONG_PTR)str, buffer, sizeof(str), &res );
+ ok( !status, "NtWow64ReadVirtualMemory64 failed %x\n", status );
+ ok( res == sizeof(str), "wrong size %s\n", wine_dbgstr_longlong(res) );
+ ok( !strcmp( buffer, str ), "wrong data %s\n", debugstr_a(buffer) );
+ status = pNtWow64WriteVirtualMemory64( process, (ULONG_PTR)buffer, " bye ", 5, &res );
+ ok( !status, "NtWow64WriteVirtualMemory64 failed %x\n", status );
+ ok( res == 5, "wrong size %s\n", wine_dbgstr_longlong(res) );
+ ok( !strcmp( buffer, " bye wow64" ), "wrong data %s\n", debugstr_a(buffer) );
+ /* current process pseudo-handle is broken on some Windows versions */
+ status = pNtWow64ReadVirtualMemory64( GetCurrentProcess(), (ULONG_PTR)str, buffer, sizeof(str), &res );
+ ok( !status || broken( status == STATUS_INVALID_HANDLE ),
+ "NtWow64ReadVirtualMemory64 failed %x\n", status );
+ status = pNtWow64WriteVirtualMemory64( GetCurrentProcess(), (ULONG_PTR)buffer, " bye ", 5, &res );
+ ok( !status || broken( status == STATUS_INVALID_HANDLE ),
+ "NtWow64WriteVirtualMemory64 failed %x\n", status );
+ }
+ else win_skip( "NtWow64ReadVirtualMemory64 not supported\n" );
+
+ NtClose( process );
+}
+
#endif /* _WIN64 */
@@ -463,5 +503,7 @@ START_TEST(wow64)
test_peb_teb();
#ifdef _WIN64
test_cpu_area();
+#else
+ test_nt_wow64();
#endif
}
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 52af195aa56..d42cf74208a 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -4833,3 +4833,70 @@ NTSTATUS WINAPI NtCreatePagingFile( UNICODE_STRING *name, LARGE_INTEGER *min_siz
FIXME( "(%s %p %p %p) stub\n", debugstr_us(name), min_size, max_size, actual_size );
return STATUS_SUCCESS;
}
+
+#ifndef _WIN64
+
+/***********************************************************************
+ * NtWow64ReadVirtualMemory64 (NTDLL.@)
+ * ZwWow64ReadVirtualMemory64 (NTDLL.@)
+ */
+NTSTATUS WINAPI NtWow64ReadVirtualMemory64( HANDLE process, ULONG64 addr, void *buffer,
+ ULONG64 size, ULONG64 *bytes_read )
+{
+ NTSTATUS status;
+
+ if (size > MAXLONG) size = MAXLONG;
+
+ if (virtual_check_buffer_for_write( buffer, size ))
+ {
+ SERVER_START_REQ( read_process_memory )
+ {
+ req->handle = wine_server_obj_handle( process );
+ req->addr = addr;
+ wine_server_set_reply( req, buffer, size );
+ if ((status = wine_server_call( req ))) size = 0;
+ }
+ SERVER_END_REQ;
+ }
+ else
+ {
+ status = STATUS_ACCESS_VIOLATION;
+ size = 0;
+ }
+ if (bytes_read) *bytes_read = size;
+ return status;
+}
+
+
+/***********************************************************************
+ * NtWow64WriteVirtualMemory64 (NTDLL.@)
+ * ZwWow64WriteVirtualMemory64 (NTDLL.@)
+ */
+NTSTATUS WINAPI NtWow64WriteVirtualMemory64( HANDLE process, ULONG64 addr, const void *buffer,
+ ULONG64 size, ULONG64 *bytes_written )
+{
+ NTSTATUS status;
+
+ if (size > MAXLONG) size = MAXLONG;
+
+ if (virtual_check_buffer_for_read( buffer, size ))
+ {
+ SERVER_START_REQ( write_process_memory )
+ {
+ req->handle = wine_server_obj_handle( process );
+ req->addr = addr;
+ wine_server_add_data( req, buffer, size );
+ if ((status = wine_server_call( req ))) size = 0;
+ }
+ SERVER_END_REQ;
+ }
+ else
+ {
+ status = STATUS_PARTIAL_COPY;
+ size = 0;
+ }
+ if (bytes_written) *bytes_written = size;
+ return status;
+}
+
+#endif /* _WIN64 */
diff --git a/include/winternl.h b/include/winternl.h
index 7221c0632b0..042936f4a7f 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -4396,19 +4396,19 @@ NTSYSAPI NTSTATUS WINAPI RtlpUnWaitCriticalSection(RTL_CRITICAL_SECTION *);
NTSYSAPI NTSTATUS WINAPI vDbgPrintEx(ULONG,ULONG,LPCSTR,__ms_va_list);
NTSYSAPI NTSTATUS WINAPI vDbgPrintExWithPrefix(LPCSTR,ULONG,ULONG,LPCSTR,__ms_va_list);
-#ifdef _WIN64
-NTSYSAPI NTSTATUS WINAPI RtlWow64GetCpuAreaInfo(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
-NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE,WOW64_CONTEXT*);
-NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*);
-#endif
-
#ifndef __WINE_USE_MSVCRT
NTSYSAPI int __cdecl _strnicmp(LPCSTR,LPCSTR,size_t);
#endif
-/* 32-bit only functions */
+/* 32-bit or 64-bit only functions */
-#ifndef _WIN64
+#ifdef _WIN64
+NTSYSAPI NTSTATUS WINAPI RtlWow64GetCpuAreaInfo(WOW64_CPURESERVED*,ULONG,WOW64_CPU_AREA_INFO*);
+NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE,WOW64_CONTEXT*);
+NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE,const WOW64_CONTEXT*);
+#else
+NTSYSAPI NTSTATUS WINAPI NtWow64ReadVirtualMemory64(HANDLE,ULONG64,void*,ULONG64,ULONG64*);
+NTSYSAPI NTSTATUS WINAPI NtWow64WriteVirtualMemory64(HANDLE,ULONG64,const void*,ULONG64,ULONG64*);
NTSYSAPI LONGLONG WINAPI RtlConvertLongToLargeInteger(LONG);
NTSYSAPI ULONGLONG WINAPI RtlConvertUlongToLargeInteger(ULONG);
NTSYSAPI LONGLONG WINAPI RtlEnlargedIntegerMultiply(INT,INT);
More information about the wine-cvs
mailing list