diff --git a/dlls/kernel/process.c b/dlls/kernel/process.c index 32aa36e7541..15c9380bd5f 100644 --- a/dlls/kernel/process.c +++ b/dlls/kernel/process.c @@ -405,18 +405,9 @@ BOOL WINAPI SetProcessPriorityBoost(HANDLE hprocess,BOOL disableboost) BOOL WINAPI ReadProcessMemory( HANDLE process, LPCVOID addr, LPVOID buffer, SIZE_T size, SIZE_T *bytes_read ) { - DWORD res; - - SERVER_START_REQ( read_process_memory ) - { - req->handle = process; - req->addr = (void *)addr; - wine_server_set_reply( req, buffer, size ); - if ((res = wine_server_call_err( req ))) size = 0; - } - SERVER_END_REQ; - if (bytes_read) *bytes_read = size; - return !res; + NTSTATUS status = NtReadVirtualMemory( process, addr, buffer, size, bytes_read ); + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; } @@ -426,46 +417,9 @@ BOOL WINAPI ReadProcessMemory( HANDLE process, LPCVOID addr, LPVOID buffer, SIZE BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPCVOID buffer, SIZE_T size, SIZE_T *bytes_written ) { - static const int zero; - unsigned int first_offset, last_offset, first_mask, last_mask; - DWORD res; - - if (!size) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - - /* compute the mask for the first int */ - first_mask = ~0; - first_offset = (unsigned int)addr % sizeof(int); - memset( &first_mask, 0, first_offset ); - - /* compute the mask for the last int */ - last_offset = (size + first_offset) % sizeof(int); - last_mask = 0; - memset( &last_mask, 0xff, last_offset ? last_offset : sizeof(int) ); - - SERVER_START_REQ( write_process_memory ) - { - req->handle = process; - req->addr = (char *)addr - first_offset; - req->first_mask = first_mask; - req->last_mask = last_mask; - if (first_offset) wine_server_add_data( req, &zero, first_offset ); - wine_server_add_data( req, buffer, size ); - if (last_offset) wine_server_add_data( req, &zero, sizeof(int) - last_offset ); - - if ((res = wine_server_call_err( req ))) size = 0; - } - SERVER_END_REQ; - if (bytes_written) *bytes_written = size; - { - char dummy[32]; - SIZE_T read; - ReadProcessMemory( process, addr, dummy, sizeof(dummy), &read ); - } - return !res; + NTSTATUS status = NtWriteVirtualMemory( process, addr, buffer, size, bytes_written ); + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; } diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 66a81301d88..a48075c07f3 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -186,7 +186,7 @@ @ stub NtRaiseHardError @ stdcall NtReadFile(long long long long long long long long long) @ stub NtReadRequestData -@ stub NtReadVirtualMemory +@ stdcall NtReadVirtualMemory(long ptr ptr long ptr) @ stub NtRegisterNewDevice @ stdcall NtRegisterThreadTerminatePort(ptr) @ stub NtReleaseMutant @@ -257,7 +257,7 @@ @ stub NtWaitLowEventPair @ stdcall NtWriteFile(long long ptr ptr ptr ptr long ptr ptr) @ stub NtWriteRequestData -@ stub NtWriteVirtualMemory +@ stdcall NtWriteVirtualMemory(long ptr ptr long ptr) @ stub PfxFindPrefix @ stub PfxInitialize @ stub PfxInsertPrefix @@ -717,7 +717,7 @@ @ stub ZwRaiseHardError @ stdcall ZwReadFile(long long long long long long long long long) NtReadFile @ stub ZwReadRequestData -@ stub ZwReadVirtualMemory +@ stdcall ZwReadVirtualMemory(long ptr ptr long ptr) NtReadVirtualMemory @ stub ZwRegisterNewDevice @ stdcall ZwRegisterThreadTerminatePort(ptr) NtRegisterThreadTerminatePort @ stub ZwReleaseMutant @@ -786,7 +786,7 @@ @ stub ZwWaitLowEventPair @ stdcall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr) NtWriteFile @ stub ZwWriteRequestData -@ stub ZwWriteVirtualMemory +@ stdcall ZwWriteVirtualMemory(long ptr ptr long ptr) NtWriteVirtualMemory @ cdecl _CIpow() NTDLL__CIpow @ stub __eCommonExceptions @ stub __eEmulatorInit diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 8e2f20131ab..a656ae69cba 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -1542,3 +1542,66 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr, if (!msync( addr, *size_ptr, MS_SYNC )) return STATUS_SUCCESS; return STATUS_NOT_MAPPED_DATA; } + + +/*********************************************************************** + * NtReadVirtualMemory (NTDLL.@) + * ZwReadVirtualMemory (NTDLL.@) + */ +NTSTATUS WINAPI NtReadVirtualMemory( HANDLE process, const void *addr, void *buffer, + SIZE_T size, SIZE_T *bytes_read ) +{ + NTSTATUS status; + + SERVER_START_REQ( read_process_memory ) + { + req->handle = process; + req->addr = (void *)addr; + wine_server_set_reply( req, buffer, size ); + if ((status = wine_server_call( req ))) size = 0; + } + SERVER_END_REQ; + if (bytes_read) *bytes_read = size; + return status; +} + + +/*********************************************************************** + * NtWriteVirtualMemory (NTDLL.@) + * ZwWriteVirtualMemory (NTDLL.@) + */ +NTSTATUS WINAPI NtWriteVirtualMemory( HANDLE process, void *addr, const void *buffer, + SIZE_T size, SIZE_T *bytes_written ) +{ + static const unsigned int zero; + unsigned int first_offset, last_offset, first_mask, last_mask; + NTSTATUS status; + + if (!size) return STATUS_INVALID_PARAMETER; + + /* compute the mask for the first int */ + first_mask = ~0; + first_offset = (unsigned int)addr % sizeof(int); + memset( &first_mask, 0, first_offset ); + + /* compute the mask for the last int */ + last_offset = (size + first_offset) % sizeof(int); + last_mask = 0; + memset( &last_mask, 0xff, last_offset ? last_offset : sizeof(int) ); + + SERVER_START_REQ( write_process_memory ) + { + req->handle = process; + req->addr = (char *)addr - first_offset; + req->first_mask = first_mask; + req->last_mask = last_mask; + if (first_offset) wine_server_add_data( req, &zero, first_offset ); + wine_server_add_data( req, buffer, size ); + if (last_offset) wine_server_add_data( req, &zero, sizeof(int) - last_offset ); + + if ((status = wine_server_call( req ))) size = 0; + } + SERVER_END_REQ; + if (bytes_written) *bytes_written = size; + return status; +} diff --git a/include/winternl.h b/include/winternl.h index b8ed742e68d..b18e1668297 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -977,6 +977,7 @@ NTSTATUS WINAPI NtQueryValueKey(HKEY,const UNICODE_STRING *,KEY_VALUE_INFORMATI NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE,LPCVOID,MEMORY_INFORMATION_CLASS,PVOID,ULONG,ULONG*); void WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL); NTSTATUS WINAPI NtReadFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,PLARGE_INTEGER,PULONG); +NTSTATUS WINAPI NtReadVirtualMemory(HANDLE,const void*,void*,SIZE_T,SIZE_T*); NTSTATUS WINAPI NtReleaseSemaphore(HANDLE,ULONG,PULONG); NTSTATUS WINAPI NtReplaceKey(POBJECT_ATTRIBUTES,HKEY,POBJECT_ATTRIBUTES); NTSTATUS WINAPI NtResetEvent(HANDLE,PULONG); @@ -1003,6 +1004,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID); NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,const LARGE_INTEGER*); NTSTATUS WINAPI NtWaitForMultipleObjects(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*); NTSTATUS WINAPI NtWriteFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,const void*,ULONG,PLARGE_INTEGER,PULONG); +NTSTATUS WINAPI NtWriteVirtualMemory(HANDLE,void*,const void*,SIZE_T,SIZE_T*); void WINAPI RtlAcquirePebLock(void); BYTE WINAPI RtlAcquireResourceExclusive(LPRTL_RWLOCK,BYTE);