ntdll: Implement NtWow64Read/WriteVirtualMemory64().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-06-28 20:24:56 +02:00
parent cbf7a10176
commit bfd2d1d77d
4 changed files with 121 additions and 8 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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 */

View File

@ -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);