mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 05:31:39 +00:00
kernelbase: Make memory writable in WriteProcessMemory if necessary.
This commit is contained in:
parent
b639319830
commit
6ea77ec086
|
@ -206,10 +206,8 @@ static void test_VirtualAllocEx(void)
|
|||
ok( b, "VirtualProtectEx, error %lu\n", GetLastError() );
|
||||
bytes_written = 0xdeadbeef;
|
||||
b = WriteProcessMemory(hProcess, addr1, src, alloc_size, &bytes_written);
|
||||
todo_wine
|
||||
ok( !b, "WriteProcessMemory succeeded\n" );
|
||||
if (!b) ok( GetLastError() == ERROR_NOACCESS, "wrong error %lu\n", GetLastError() );
|
||||
todo_wine
|
||||
ok( bytes_written == 0xdeadbeef, "%Iu bytes written\n", bytes_written );
|
||||
status = pNtWriteVirtualMemory( hProcess, addr1, src, alloc_size, &bytes_written );
|
||||
todo_wine
|
||||
|
|
|
@ -46,6 +46,9 @@ WINE_DECLARE_DEBUG_CHANNEL(globalmem);
|
|||
* Virtual memory functions
|
||||
***********************************************************************/
|
||||
|
||||
static const SIZE_T page_mask = 0xfff;
|
||||
#define ROUND_ADDR(addr) ((void *)((UINT_PTR)(addr) & ~page_mask))
|
||||
#define ROUND_SIZE(addr,size) (((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask)
|
||||
|
||||
/***********************************************************************
|
||||
* DiscardVirtualMemory (kernelbase.@)
|
||||
|
@ -537,7 +540,46 @@ BOOL WINAPI DECLSPEC_HOTPATCH VirtualUnlock( void *addr, SIZE_T size )
|
|||
BOOL WINAPI DECLSPEC_HOTPATCH WriteProcessMemory( HANDLE process, void *addr, const void *buffer,
|
||||
SIZE_T size, SIZE_T *bytes_written )
|
||||
{
|
||||
return set_ntstatus( NtWriteVirtualMemory( process, addr, buffer, size, bytes_written ));
|
||||
DWORD old_prot, prot = PAGE_TARGETS_NO_UPDATE | PAGE_ENCLAVE_NO_CHANGE | PAGE_EXECUTE_WRITECOPY;
|
||||
MEMORY_BASIC_INFORMATION info;
|
||||
void *base_addr;
|
||||
SIZE_T region_size;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!VirtualQueryEx( process, addr, &info, sizeof(info) )) return FALSE;
|
||||
|
||||
switch (info.Protect)
|
||||
{
|
||||
case PAGE_READWRITE:
|
||||
case PAGE_WRITECOPY:
|
||||
case PAGE_EXECUTE_READWRITE:
|
||||
case PAGE_EXECUTE_WRITECOPY:
|
||||
/* already writable */
|
||||
if ((status = NtWriteVirtualMemory( process, addr, buffer, size, bytes_written ))) break;
|
||||
NtFlushInstructionCache( process, addr, size );
|
||||
break;
|
||||
|
||||
case PAGE_EXECUTE:
|
||||
case PAGE_EXECUTE_READ:
|
||||
/* make it writable */
|
||||
base_addr = ROUND_ADDR( addr );
|
||||
region_size = ROUND_SIZE( addr, size );
|
||||
region_size = min( region_size, (char *)info.BaseAddress + info.RegionSize - (char *)base_addr );
|
||||
status = NtProtectVirtualMemory( process, &base_addr, ®ion_size, prot, &old_prot );
|
||||
if (status) break;
|
||||
status = NtWriteVirtualMemory( process, addr, buffer, size, bytes_written );
|
||||
if (!status) NtFlushInstructionCache( process, addr, size );
|
||||
prot = PAGE_TARGETS_NO_UPDATE | PAGE_ENCLAVE_NO_CHANGE | old_prot;
|
||||
NtProtectVirtualMemory( process, &base_addr, ®ion_size, prot, &old_prot );
|
||||
break;
|
||||
|
||||
default:
|
||||
/* not writable */
|
||||
status = STATUS_ACCESS_VIOLATION;
|
||||
break;
|
||||
}
|
||||
|
||||
return set_ntstatus( status );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -729,7 +729,7 @@ static void test_cross_process_notifications( HANDLE process, ULONG_PTR section,
|
|||
|
||||
WriteProcessMemory( process, (char *)addr + 0x1ffe, data, sizeof(data), &size );
|
||||
entry = pop_from_work_list( &list->work_list );
|
||||
todo_wine
|
||||
todo_wine_if (current_machine == IMAGE_FILE_MACHINE_ARM64)
|
||||
{
|
||||
entry = expect_cross_work_entry( list, entry, CrossProcessPreVirtualProtect,
|
||||
(char *)addr + 0x1000, 0x2000, 0x60000000 | PAGE_EXECUTE_WRITECOPY,
|
||||
|
|
|
@ -815,17 +815,35 @@ typedef struct DECLSPEC_ALIGN(8) MEM_EXTENDED_PARAMETER {
|
|||
#define MEM_EXTENDED_PARAMETER_EC_CODE 0x00000040
|
||||
#define MEM_EXTENDED_PARAMETER_IMAGE_NO_HPAT 0x00000080
|
||||
|
||||
#define PAGE_NOACCESS 0x01
|
||||
#define PAGE_READONLY 0x02
|
||||
#define PAGE_READWRITE 0x04
|
||||
#define PAGE_WRITECOPY 0x08
|
||||
#define PAGE_EXECUTE 0x10
|
||||
#define PAGE_EXECUTE_READ 0x20
|
||||
#define PAGE_EXECUTE_READWRITE 0x40
|
||||
#define PAGE_EXECUTE_WRITECOPY 0x80
|
||||
#define PAGE_GUARD 0x100
|
||||
#define PAGE_NOCACHE 0x200
|
||||
#define PAGE_WRITECOMBINE 0x400
|
||||
#define PAGE_NOACCESS 0x00000001
|
||||
#define PAGE_READONLY 0x00000002
|
||||
#define PAGE_READWRITE 0x00000004
|
||||
#define PAGE_WRITECOPY 0x00000008
|
||||
#define PAGE_EXECUTE 0x00000010
|
||||
#define PAGE_EXECUTE_READ 0x00000020
|
||||
#define PAGE_EXECUTE_READWRITE 0x00000040
|
||||
#define PAGE_EXECUTE_WRITECOPY 0x00000080
|
||||
#define PAGE_GUARD 0x00000100
|
||||
#define PAGE_NOCACHE 0x00000200
|
||||
#define PAGE_WRITECOMBINE 0x00000400
|
||||
#define PAGE_GRAPHICS_NOACCESS 0x00000800
|
||||
#define PAGE_GRAPHICS_READONLY 0x00001000
|
||||
#define PAGE_GRAPHICS_READWRITE 0x00002000
|
||||
#define PAGE_GRAPHICS_EXECUTE 0x00004000
|
||||
#define PAGE_GRAPHICS_EXECUTE_READ 0x00008000
|
||||
#define PAGE_GRAPHICS_EXECUTE_READWRITE 0x00010000
|
||||
#define PAGE_GRAPHICS_COHERENT 0x00020000
|
||||
#define PAGE_GRAPHICS_NOCACHE 0x00040000
|
||||
#define PAGE_ENCLAVE_MASK 0x10000000
|
||||
#define PAGE_ENCLAVE_UNVALIDATED 0x20000000
|
||||
#define PAGE_ENCLAVE_NO_CHANGE 0x20000000
|
||||
#define PAGE_TARGETS_NO_UPDATE 0x40000000
|
||||
#define PAGE_TARGETS_INVALID 0x40000000
|
||||
#define PAGE_REVERT_TO_FILE_MAP 0x80000000
|
||||
#define PAGE_ENCLAVE_THREAD_CONTROL 0x80000000
|
||||
#define PAGE_ENCLAVE_DECOMMIT (PAGE_ENCLAVE_MASK | 0)
|
||||
#define PAGE_ENCLAVE_SS_FIRST (PAGE_ENCLAVE_MASK | 1)
|
||||
#define PAGE_ENCLAVE_SS_REST (PAGE_ENCLAVE_MASK | 2)
|
||||
|
||||
#define MEM_COMMIT 0x00001000
|
||||
#define MEM_RESERVE 0x00002000
|
||||
|
|
Loading…
Reference in a new issue