A stub for bug 45667 has been sitting in staging for a while. It is sufficient for League of Legends, but it is not correct by any definition.
The challenge with MemoryWorkingSetExInformation is that it requires information that is not exposed by the Linux kernel. One option was to allocate valloc memory with PROT_NONE, then handle the faults in virtual_handle_fault and keep our own statistics. This implies a SIGSEGV signal for *every* VirtualAlloc page, which sounded slow.
This patchset implements an optimized version of this by using /proc/pid/pagemap to handle demand-zero pages, which would have been the most common complicated case. The remaining complicated cases (e.g. VirtualProtect from PAGE_NOACCESS to PAGE_READONLY, ...) are handled by deferring changing the page protection until virtual_handle_fault.
It is possible that this patchset will introduce a performance regression if an application heavily uses PAGE_NOACCESS or PAGE_GUARD protections. Also, this patch reverts to the staging stub's behavior if pagemaps is not available.
If someone has an alternative approach, or there is appetite using the staging stub in upstream Wine, that would be very welcome feedback.
Andrew Wesie (3): ntdll: Implement NtQueryVirtualMemory(MemoryWorkingSetExInformation). kernel32: QueryWorkingSetEx should use MemoryWorkingSetExInformation. psapi/tests: Test QueryWorkingSetEx.
dlls/kernel32/process.c | 2 +- dlls/ntdll/virtual.c | 78 +++++++++++++++++++++++++++++--- dlls/psapi/tests/psapi_main.c | 84 +++++++++++++++++++++++++++++++++++ include/psapi.h | 18 ++++++++ include/winternl.h | 21 ++++++++- 5 files changed, 196 insertions(+), 7 deletions(-)
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45667 Signed-off-by: Andrew Wesie awesie@gmail.com --- dlls/ntdll/virtual.c | 78 +++++++++++++++++++++++++++++++++++++++++--- include/winternl.h | 21 +++++++++++- 2 files changed, 93 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index cb869feff0..fecc2d601d 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -84,6 +84,7 @@ struct file_view #define VPROT_GUARD 0x10 #define VPROT_COMMITTED 0x20 #define VPROT_WRITEWATCH 0x40 +#define VPROT_DEFERRED 0x80 /* per-mapping protection flags */ #define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */
@@ -319,7 +320,7 @@ static const char *VIRTUAL_GetProtStr( BYTE prot ) static int VIRTUAL_GetUnixProt( BYTE vprot ) { int prot = 0; - if ((vprot & VPROT_COMMITTED) && !(vprot & VPROT_GUARD)) + if ((vprot & VPROT_COMMITTED) && !(vprot & (VPROT_GUARD | VPROT_DEFERRED))) { if (vprot & VPROT_READ) prot |= PROT_READ; if (vprot & VPROT_WRITE) prot |= PROT_WRITE | PROT_READ; @@ -952,7 +953,7 @@ static BOOL VIRTUAL_SetProt( struct file_view *view, /* [in] Pointer to view */ * * Set page protections on a range of pages */ -static NTSTATUS set_protection( struct file_view *view, void *base, SIZE_T size, ULONG protect ) +static NTSTATUS set_protection( struct file_view *view, void *base, SIZE_T size, ULONG protect, BOOL apply ) { unsigned int vprot; NTSTATUS status; @@ -968,6 +969,8 @@ static NTSTATUS set_protection( struct file_view *view, void *base, SIZE_T size, if ((view->protect & access) != access) return STATUS_INVALID_PAGE_PROTECTION; }
+ if (!apply) + vprot |= VPROT_DEFERRED; if (!VIRTUAL_SetProt( view, base, size, vprot | VPROT_COMMITTED )) return STATUS_ACCESS_DENIED; return STATUS_SUCCESS; } @@ -2109,10 +2112,16 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) vprot = get_page_vprot( page ); if (!on_signal_stack && (vprot & VPROT_GUARD)) { - set_page_vprot_bits( page, page_size, 0, VPROT_GUARD ); + set_page_vprot_bits( page, page_size, 0, VPROT_GUARD | VPROT_DEFERRED ); mprotect_range( page, page_size, 0, 0 ); ret = STATUS_GUARD_PAGE_VIOLATION; } + else if (vprot & VPROT_DEFERRED) + { + set_page_vprot_bits( page, page_size, 0, VPROT_DEFERRED ); + mprotect_range( page, page_size, 0, 0 ); + ret = STATUS_SUCCESS; + } else if (err & EXCEPTION_WRITE_FAULT) { if (vprot & VPROT_WRITEWATCH) @@ -2684,7 +2693,7 @@ NTSTATUS virtual_alloc_aligned( PVOID *ret, unsigned short zero_bits_64, SIZE_T { if (!(view = VIRTUAL_FindView( base, size ))) status = STATUS_NOT_MAPPED_VIEW; else if (view->protect & SEC_FILE) status = STATUS_ALREADY_COMMITTED; - else if (!(status = set_protection( view, base, size, protect )) && (view->protect & SEC_RESERVE)) + else if (!(status = set_protection( view, base, size, protect, TRUE )) && (view->protect & SEC_RESERVE)) { SERVER_START_REQ( add_mapping_committed_range ) { @@ -2850,7 +2859,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH NtProtectVirtualMemory( HANDLE process, PVOID if (get_committed_size( view, base, &vprot ) >= size && (vprot & VPROT_COMMITTED)) { old = VIRTUAL_GetWin32Prot( vprot, view->protect ); - status = set_protection( view, base, size, new_prot ); + status = set_protection( view, base, size, new_prot, VIRTUAL_GetUnixProt(vprot) != PROT_NONE ); } else status = STATUS_NOT_COMMITTED; } @@ -2906,6 +2915,62 @@ static int get_free_mem_state_callback( void *start, size_t size, void *arg ) return 1; }
+static NTSTATUS get_working_set_ex( HANDLE process, LPCVOID addr, + MEMORY_WORKING_SET_EX_INFORMATION *info, + SIZE_T len, SIZE_T *res_len ) +{ + MEMORY_WORKING_SET_EX_INFORMATION *p; + char pagemap_path[128]; + FILE *f; + sigset_t sigset; + + if (process != NtCurrentProcess()) + { + FIXME("(process=%p,addr=%p) Unimplemented information class: MemoryWorkingSetExInformation\n", process, addr); + return STATUS_INVALID_INFO_CLASS; + } + + snprintf(pagemap_path, sizeof(pagemap_path), "/proc/%u/pagemap", getpid()); + f = fopen(pagemap_path, "rb"); + + server_enter_uninterrupted_section( &csVirtual, &sigset ); + for (p = info; (UINT_PTR)(p + 1) <= (UINT_PTR)info + len; p++) + { + BYTE vprot; + UINT64 pagemap; + struct file_view *view; + + memset(&p->VirtualAttributes, 0, sizeof(p->VirtualAttributes)); + /* If we don't have pagemap information, default to invalid. */ + if (f == NULL || + fseek(f, ((UINT_PTR)p->VirtualAddress >> 12) * sizeof(pagemap), SEEK_SET) == -1 || + fread(&pagemap, sizeof(pagemap), 1, f) != 1) + { + continue; + } + + if ((view = VIRTUAL_FindView( p->VirtualAddress, 0 )) && + get_committed_size( view, p->VirtualAddress, &vprot ) && + (vprot & VPROT_COMMITTED)) + { + p->VirtualAttributes.Valid = !(vprot & (VPROT_GUARD | VPROT_DEFERRED)) && (vprot & 0x0f) && (pagemap >> 62); + p->VirtualAttributes.Shared = (view->protect & (VPROT_SYSTEM | SEC_IMAGE | SEC_FILE | SEC_RESERVE | SEC_COMMIT)) != 0; + if (p->VirtualAttributes.Shared && p->VirtualAttributes.Valid) + p->VirtualAttributes.ShareCount = 1; /* FIXME */ + if (p->VirtualAttributes.Valid) + p->VirtualAttributes.Win32Protection = VIRTUAL_GetWin32Prot( vprot, view->protect ); + } + } + server_leave_uninterrupted_section( &csVirtual, &sigset ); + + if (f) + fclose(f); + if (res_len) + *res_len = (UINT_PTR)p - (UINT_PTR)info; + return STATUS_SUCCESS; +} + + #define UNIMPLEMENTED_INFO_CLASS(c) \ case c: \ FIXME("(process=%p,addr=%p) Unimplemented information class: " #c "\n", process, addr); \ @@ -2933,6 +2998,9 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr, UNIMPLEMENTED_INFO_CLASS(MemorySectionName); UNIMPLEMENTED_INFO_CLASS(MemoryBasicVlmInformation);
+ case MemoryWorkingSetExInformation: + return get_working_set_ex( process, addr, buffer, len, res_len ); + default: FIXME("(%p,%p,info_class=%d,%p,%ld,%p) Unknown information class\n", process, addr, info_class, buffer, len, res_len); diff --git a/include/winternl.h b/include/winternl.h index 0122684483..eef42be5b3 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1049,7 +1049,8 @@ typedef enum _MEMORY_INFORMATION_CLASS { MemoryBasicInformation, MemoryWorkingSetList, MemorySectionName, - MemoryBasicVlmInformation + MemoryBasicVlmInformation, + MemoryWorkingSetExInformation } MEMORY_INFORMATION_CLASS;
typedef struct _MEMORY_SECTION_NAME @@ -1057,6 +1058,24 @@ typedef struct _MEMORY_SECTION_NAME UNICODE_STRING SectionFileName; } MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;
+typedef union _MEMORY_WORKING_SET_EX_BLOCK { + ULONG_PTR Flags; + struct { + ULONG_PTR Valid :1; + ULONG_PTR ShareCount :3; + ULONG_PTR Win32Protection :11; + ULONG_PTR Shared :1; + ULONG_PTR Node :6; + ULONG_PTR Locked :1; + ULONG_PTR LargePage :1; + } DUMMYSTRUCTNAME; +} MEMORY_WORKING_SET_EX_BLOCK, *PMEMORY_WORKING_SET_EX_BLOCK; + +typedef struct _MEMORY_WORKING_SET_EX_INFORMATION { + PVOID VirtualAddress; + MEMORY_WORKING_SET_EX_BLOCK VirtualAttributes; +} MEMORY_WORKING_SET_EX_INFORMATION, *PMEMORY_WORKING_SET_EX_INFORMATION; + typedef enum _MUTANT_INFORMATION_CLASS { MutantBasicInformation
Signed-off-by: Andrew Wesie awesie@gmail.com --- dlls/kernel32/process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 7875f3469a..5146622230 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -722,7 +722,7 @@ BOOL WINAPI K32QueryWorkingSetEx( HANDLE process, LPVOID buffer, DWORD size ) { TRACE( "(%p, %p, %d)\n", process, buffer, size );
- return set_ntstatus( NtQueryVirtualMemory( process, NULL, MemoryWorkingSetList, buffer, size, NULL )); + return set_ntstatus( NtQueryVirtualMemory( process, NULL, MemoryWorkingSetExInformation, buffer, size, NULL )); }
/***********************************************************************
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62288
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32: comm.c:918: Test failed: OutQueue should not be empty virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:3929: Test succeeded inside todo block: VirtualProtect error -559038737, map 0x2, view 0x2, requested prot 0x8 virtual.c:3931: Test succeeded inside todo block: got 0x2, expected 0x2 virtual.c:3937: Test succeeded inside todo block: VirtualProtect wrong prot, map 0x2, view 0x2, requested prot 0x8 got 0x8 virtual.c:3992: Test succeeded inside todo block: VirtualProtect error 5, map 0x2, view 0x2 Unhandled exception: page fault on write access to 0x00340000 in 32-bit code (0x00526b5b).
Report errors: kernel32:virtual crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
kernel32: debugger: Timeout virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:3929: Test succeeded inside todo block: VirtualProtect error -559038737, map 0x2, view 0x2, requested prot 0x8 virtual.c:3931: Test succeeded inside todo block: got 0x2, expected 0x2 virtual.c:3937: Test succeeded inside todo block: VirtualProtect wrong prot, map 0x2, view 0x2, requested prot 0x8 got 0x8 virtual.c:3992: Test succeeded inside todo block: VirtualProtect error 5, map 0x2, view 0x2 Unhandled exception: page fault on write access to 0x00340000 in 32-bit code (0x00526b5b).
Report errors: kernel32:virtual crashed (c0000005)
=== debian10 (32 bit WoW report) ===
kernel32: virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:3929: Test succeeded inside todo block: VirtualProtect error -559038737, map 0x2, view 0x2, requested prot 0x8 virtual.c:3931: Test succeeded inside todo block: got 0x2, expected 0x2 virtual.c:3937: Test succeeded inside todo block: VirtualProtect wrong prot, map 0x2, view 0x2, requested prot 0x8 got 0x8 virtual.c:3992: Test succeeded inside todo block: VirtualProtect error 5, map 0x2, view 0x2 Unhandled exception: page fault on write access to 0x00340000 in 32-bit code (0x00526b5b).
Report errors: kernel32:virtual crashed (c0000005)
=== debian10 (64 bit WoW report) ===
kernel32: virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:3929: Test succeeded inside todo block: VirtualProtect error -559038737, map 0x2, view 0x2, requested prot 0x8 virtual.c:3931: Test succeeded inside todo block: got 0x2, expected 0x2 virtual.c:3937: Test succeeded inside todo block: VirtualProtect wrong prot, map 0x2, view 0x2, requested prot 0x8 got 0x8 virtual.c:3992: Test succeeded inside todo block: VirtualProtect error 5, map 0x2, view 0x2 Unhandled exception: page fault on write access to 0x00340000 in 32-bit code (0x00526b5b).
Report errors: kernel32:virtual crashed (c0000005)
Signed-off-by: Andrew Wesie awesie@gmail.com --- dlls/psapi/tests/psapi_main.c | 84 +++++++++++++++++++++++++++++++++++ include/psapi.h | 18 ++++++++ 2 files changed, 102 insertions(+)
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c index 9799d2ffae..fada1043c7 100644 --- a/dlls/psapi/tests/psapi_main.c +++ b/dlls/psapi/tests/psapi_main.c @@ -43,6 +43,7 @@ static NTSTATUS (WINAPI *pNtQueryVirtualMemory)(HANDLE, LPCVOID, ULONG, PVOID, S static BOOL (WINAPI *pIsWow64Process)(HANDLE, BOOL *); static BOOL (WINAPI *pWow64DisableWow64FsRedirection)(void **); static BOOL (WINAPI *pWow64RevertWow64FsRedirection)(void *); +static BOOL (WINAPI *pQueryWorkingSetEx)(HANDLE, PVOID, DWORD);
static BOOL wow64;
@@ -53,6 +54,7 @@ static BOOL init_func_ptrs(void) pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); pWow64DisableWow64FsRedirection = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "Wow64DisableWow64FsRedirection"); pWow64RevertWow64FsRedirection = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "Wow64RevertWow64FsRedirection"); + pQueryWorkingSetEx = (void *)GetProcAddress(GetModuleHandleA("psapi.dll"), "QueryWorkingSetEx"); return TRUE; }
@@ -791,6 +793,87 @@ free_page: VirtualFree(addr, 0, MEM_RELEASE); }
+static void check_QueryWorkingSetEx(PVOID addr, const char *desc, DWORD expected_valid, + BOOL expected_share_count, DWORD expected_protection, DWORD expected_shared) +{ + PSAPI_WORKING_SET_EX_INFORMATION info; + BOOL ret; + + memset(&info, 0x41, sizeof(info)); + info.VirtualAddress = addr; + ret = pQueryWorkingSetEx(GetCurrentProcess(), &info, sizeof(info)); + ok(ret, "QueryWorkingSetEx failed with %d\n", GetLastError()); + ok(info.VirtualAttributes.Valid == expected_valid, "%s expected Valid=%u but got %u\n", + desc, expected_valid, info.VirtualAttributes.Valid); + if (expected_share_count) + ok(info.VirtualAttributes.ShareCount > 0, "%s expected ShareCount > 0 but got %u\n", + desc, info.VirtualAttributes.ShareCount); + else + ok(info.VirtualAttributes.ShareCount == 0, "%s expected ShareCount == 0 but got %u\n", + desc, info.VirtualAttributes.ShareCount); + ok(info.VirtualAttributes.Win32Protection == expected_protection, "%s expected Win32Protection=%u but got %u\n", + desc, expected_protection, info.VirtualAttributes.Win32Protection); + ok(info.VirtualAttributes.Shared == expected_shared, "%s expected Shared=%u but got %u\n", + desc, expected_shared, info.VirtualAttributes.Shared); + ok(info.VirtualAttributes.Node == 0, "%s expected Node=0 but got %u\n", + desc, info.VirtualAttributes.Node); + ok(info.VirtualAttributes.LargePage == 0, "%s expected LargePage=0 but got %u\n", + desc, info.VirtualAttributes.LargePage); +} + +static void test_QueryWorkingSetEx(void) +{ + PVOID addr; + DWORD prot; + BOOL ret; + + if (pQueryWorkingSetEx == NULL) + { + win_skip("QueryWorkingSetEx not found, skipping tests\n"); + return; + } + + addr = GetModuleHandleA(NULL); + check_QueryWorkingSetEx(addr, "exe", 1, TRUE, PAGE_READONLY, 1); + + ret = VirtualProtect(addr, 0x1000, PAGE_NOACCESS, &prot); + ok(ret, "VirtualProtect failed with %d\n", GetLastError()); + check_QueryWorkingSetEx(addr, "exe,noaccess", 0, FALSE, 0, 1); + + ret = VirtualProtect(addr, 0x1000, prot, &prot); + ok(ret, "VirtualProtect failed with %d\n", GetLastError()); + check_QueryWorkingSetEx(addr, "exe,readonly1", 0, FALSE, 0, 1); + + *(volatile char *)addr; + ok(ret, "VirtualProtect failed with %d\n", GetLastError()); + check_QueryWorkingSetEx(addr, "exe,readonly2", 1, TRUE, PAGE_READONLY, 1); + + addr = VirtualAlloc(NULL, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + ok(addr != NULL, "VirtualAlloc failed with %d\n", GetLastError()); + check_QueryWorkingSetEx(addr, "valloc", 0, FALSE, 0, 0); + + *(volatile char *)addr; + check_QueryWorkingSetEx(addr, "valloc,read", 1, FALSE, PAGE_READWRITE, 0); + + *(volatile char *)addr = 0x42; + check_QueryWorkingSetEx(addr, "valloc,write", 1, FALSE, PAGE_READWRITE, 0); + + ret = VirtualProtect(addr, 0x1000, PAGE_NOACCESS, &prot); + ok(ret, "VirtualProtect failed with %d\n", GetLastError()); + check_QueryWorkingSetEx(addr, "valloc,noaccess", 0, FALSE, 0, 0); + + ret = VirtualProtect(addr, 0x1000, prot, &prot); + ok(ret, "VirtualProtect failed with %d\n", GetLastError()); + check_QueryWorkingSetEx(addr, "valloc,readwrite1", 0, FALSE, 0, 0); + + *(volatile char *)addr; + check_QueryWorkingSetEx(addr, "valloc,readwrite2", 1, FALSE, PAGE_READWRITE, 0); + + ret = VirtualFree(addr, 0, MEM_RELEASE); + ok(ret, "VirtualFree failed with %d\n", GetLastError()); + check_QueryWorkingSetEx(addr, "valloc,free", 0, FALSE, 0, 0); +} + START_TEST(psapi_main) { DWORD pid = GetCurrentProcessId(); @@ -818,6 +901,7 @@ START_TEST(psapi_main) test_GetProcessImageFileName(); test_GetModuleFileNameEx(); test_GetModuleBaseName(); + test_QueryWorkingSetEx(); test_ws_functions();
CloseHandle(hpSR); diff --git a/include/psapi.h b/include/psapi.h index 742bf7b574..66e660b243 100644 --- a/include/psapi.h +++ b/include/psapi.h @@ -45,6 +45,24 @@ typedef struct _PROCESS_MEMORY_COUNTERS { } PROCESS_MEMORY_COUNTERS; typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS;
+typedef union _PSAPI_WORKING_SET_EX_BLOCK { + ULONG_PTR Flags; + struct { + ULONG_PTR Valid :1; + ULONG_PTR ShareCount :3; + ULONG_PTR Win32Protection :11; + ULONG_PTR Shared :1; + ULONG_PTR Node :6; + ULONG_PTR Locked :1; + ULONG_PTR LargePage :1; + } DUMMYSTRUCTNAME; +} PSAPI_WORKING_SET_EX_BLOCK, *PPSAPI_WORKING_SET_EX_BLOCK; + +typedef struct _PSAPI_WORKING_SET_EX_INFORMATION { + PVOID VirtualAddress; + PSAPI_WORKING_SET_EX_BLOCK VirtualAttributes; +} PSAPI_WORKING_SET_EX_INFORMATION, *PPSAPI_WORKING_SET_EX_INFORMATION; + typedef struct _PSAPI_WS_WATCH_INFORMATION { LPVOID FaultingPc; LPVOID FaultingVa;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62289
Your paranoid android.
=== wxppro (32 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w2003std (32 bit report) ===
psapi: psapi_main.c:816: Test failed: exe,noaccess expected Shared=1 but got 0 psapi_main.c:816: Test failed: exe,readonly1 expected Shared=1 but got 0
=== wvistau64 (32 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w8 (32 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w1064v1809_2scr (32 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w1064v1809_ar (32 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w1064v1809_he (32 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w1064v1809_ja (32 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w1064v1809_zh_CN (32 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== wvistau64 (64 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w2008s64 (64 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w864 (64 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w1064v1507 (64 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== w1064v1809 (64 bit report) ===
psapi: psapi_main.c:686: Test failed: got error 127
=== debian10 (32 bit report) ===
kernel32: comm.c:918: Test failed: OutQueue should not be empty debugger.c:320: Test failed: GetThreadContext failed: 5 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:3929: Test succeeded inside todo block: VirtualProtect error -559038737, map 0x2, view 0x2, requested prot 0x8 virtual.c:3931: Test succeeded inside todo block: got 0x2, expected 0x2 virtual.c:3937: Test succeeded inside todo block: VirtualProtect wrong prot, map 0x2, view 0x2, requested prot 0x8 got 0x8 virtual.c:3992: Test succeeded inside todo block: VirtualProtect error 5, map 0x2, view 0x2 Unhandled exception: page fault on write access to 0x00340000 in 32-bit code (0x00526b5b).
Report errors: kernel32:virtual crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
kernel32: virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:3929: Test succeeded inside todo block: VirtualProtect error -559038737, map 0x2, view 0x2, requested prot 0x8 virtual.c:3931: Test succeeded inside todo block: got 0x2, expected 0x2 virtual.c:3937: Test succeeded inside todo block: VirtualProtect wrong prot, map 0x2, view 0x2, requested prot 0x8 got 0x8 virtual.c:3992: Test succeeded inside todo block: VirtualProtect error 5, map 0x2, view 0x2 Unhandled exception: page fault on write access to 0x00340000 in 32-bit code (0x00526b5b).
Report errors: kernel32:virtual crashed (c0000005)
=== debian10 (32 bit WoW report) ===
kernel32: virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:3929: Test succeeded inside todo block: VirtualProtect error -559038737, map 0x2, view 0x2, requested prot 0x8 virtual.c:3931: Test succeeded inside todo block: got 0x2, expected 0x2 virtual.c:3937: Test succeeded inside todo block: VirtualProtect wrong prot, map 0x2, view 0x2, requested prot 0x8 got 0x8 virtual.c:3992: Test succeeded inside todo block: VirtualProtect error 5, map 0x2, view 0x2 Unhandled exception: page fault on write access to 0x00340000 in 32-bit code (0x00526b5b).
ntdll: pipe.c:1557: Test failed: pipe is not signaled pipe.c:1557: Test failed: pipe is not signaled
Report errors: kernel32:virtual crashed (c0000005)
=== debian10 (64 bit WoW report) ===
kernel32: debugger.c:320: Test failed: GetThreadContext failed: 5 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x4, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x8, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x20, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x4 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x40, view 0x40 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x8 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x2 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x80 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x80, view 0x20 got 0x8 virtual.c:4000: Test succeeded inside todo block: wrong region size 0x1000 after write, map 0x2, view 0x8 got 0x8 virtual.c:3929: Test succeeded inside todo block: VirtualProtect error -559038737, map 0x2, view 0x2, requested prot 0x8 virtual.c:3931: Test succeeded inside todo block: got 0x2, expected 0x2 virtual.c:3937: Test succeeded inside todo block: VirtualProtect wrong prot, map 0x2, view 0x2, requested prot 0x8 got 0x8 virtual.c:3992: Test succeeded inside todo block: VirtualProtect error 5, map 0x2, view 0x2 Unhandled exception: page fault on write access to 0x00340000 in 32-bit code (0x00526b5b).
Report errors: kernel32:virtual crashed (c0000005)
On Dec 17, 2019, at 6:34 PM, Andrew Wesie awesie@gmail.com wrote:
A stub for bug 45667 has been sitting in staging for a while. It is sufficient for League of Legends, but it is not correct by any definition.
The challenge with MemoryWorkingSetExInformation is that it requires information that is not exposed by the Linux kernel.
Are the semantics of the fields of MEMORY_WORKING_SET_EX_BLOCK documented or explained somewhere? It's hard to comment intelligently without that.
-Ken
On Tue, Dec 17, 2019 at 8:07 PM Ken Thomases ken@codeweavers.com wrote:
Are the semantics of the fields of MEMORY_WORKING_SET_EX_BLOCK documented or explained somewhere? It's hard to comment intelligently without that.
Not really. My knowledge is limited to what my test has shown: - Demand-zero page is "Invalid" - Once you read from a demand-zero page (or write to it), it is now "Valid" - If you change a page protection to NOACCESS or GUARD, it is "Invalid" - If you change a page protection from NOACCESS or GUARD to READ_ONLY, READWRITE, ... without GUARD, it is still "Invalid" - If you then read from that page (or write to it), it is now "Valid"
Those are the semantics that I am having a difficult time replicating on Linux without causing additional faults. /proc/pid/pagemap lets us handle the demand-zero page, which is most the common case.
-Andrew
On Tue, Dec 17, 2019 at 8:31 PM Andrew Wesie awesie@gmail.com wrote:
On Tue, Dec 17, 2019 at 8:07 PM Ken Thomases ken@codeweavers.com wrote:
Are the semantics of the fields of MEMORY_WORKING_SET_EX_BLOCK documented or explained somewhere? It's hard to comment intelligently without that.
Not really. My knowledge is limited to what my test has shown:
- Demand-zero page is "Invalid"
- Once you read from a demand-zero page (or write to it), it is now "Valid"
- If you change a page protection to NOACCESS or GUARD, it is "Invalid"
- If you change a page protection from NOACCESS or GUARD to
READ_ONLY, READWRITE, ... without GUARD, it is still "Invalid"
- If you then read from that page (or write to it), it is now "Valid"
One additional hint that I just found in VirtualQuery documentation is: "To detect whether copy-on-write has occurred for a specific page, either access the page or lock it using the VirtualLock function to make sure the page is resident in memory, then use the QueryWorkingSetEx function ...".
This seems to imply that when pages are mapped into a process, they are not resident (e.g. "Valid") until they are accessed or locked. Additionally, from my previous email, pages become non-resident when their protection changes to PAGE_NOACCESS or PAGE_GUARD. The page will then only become resident once it is accessed (read or write) again.
The Linux kernel supports the concept of a "soft dirty" bit in the PTE that is accessible to user space with pagemaps. This is almost what we need, except it only handles writes and we need it to mark pages on read as well.
-Andrew
On Dec 17, 2019, at 10:21 PM, Andrew Wesie awesie@gmail.com wrote:
On Tue, Dec 17, 2019 at 8:31 PM Andrew Wesie awesie@gmail.com wrote:
On Tue, Dec 17, 2019 at 8:07 PM Ken Thomases ken@codeweavers.com wrote:
Are the semantics of the fields of MEMORY_WORKING_SET_EX_BLOCK documented or explained somewhere? It's hard to comment intelligently without that.
Not really. My knowledge is limited to what my test has shown:
- Demand-zero page is "Invalid"
- Once you read from a demand-zero page (or write to it), it is now "Valid"
- If you change a page protection to NOACCESS or GUARD, it is "Invalid"
- If you change a page protection from NOACCESS or GUARD to
READ_ONLY, READWRITE, ... without GUARD, it is still "Invalid"
- If you then read from that page (or write to it), it is now "Valid"
One additional hint that I just found in VirtualQuery documentation is: "To detect whether copy-on-write has occurred for a specific page, either access the page or lock it using the VirtualLock function to make sure the page is resident in memory, then use the QueryWorkingSetEx function ...".
This seems to imply that when pages are mapped into a process, they are not resident (e.g. "Valid") until they are accessed or locked. Additionally, from my previous email, pages become non-resident when their protection changes to PAGE_NOACCESS or PAGE_GUARD. The page will then only become resident once it is accessed (read or write) again.
The Linux kernel supports the concept of a "soft dirty" bit in the PTE that is accessible to user space with pagemaps. This is almost what we need, except it only handles writes and we need it to mark pages on read as well.
I wonder if it wouldn't be good enough to just use the current page protection. If a page allows access, you have to assume another thread could access it at any time. So, we could just pretend one has.
NOACCESS or GUARD -> invalid anything else -> valid
Do you happen to know if that would satisfy League of Legends?
-Ken
On Wed, Dec 18, 2019 at 4:24 PM Ken Thomases ken@codeweavers.com wrote:
I wonder if it wouldn't be good enough to just use the current page protection. If a page allows access, you have to assume another thread could access it at any time. So, we could just pretend one has.
It is not true that you have to assume another thread could access it at any time. If a thread allocates a page of memory, and does not share the pointer to that memory, then it should be able to assume no other threads will access it. When this assumption breaks on Windows, it is usually because of anti-virus or similar programs and that is why these are not supported by some anti-cheat systems.
NOACCESS or GUARD -> invalid anything else -> valid
Do you happen to know if that would satisfy League of Legends?
I did some more research and found some public research that discusses this anti-debugging technique (e.g. http://everdox.blogspot.com/2013/03/utilizing-paged-virtual-memory-as-anti.h...). And to quote the blog of someone involved with League of Legends:
"Our trick relies on the fact that Windows, as an optimization, will not commit virtual memory to physical RAM unless it absolutely needs it. [...] So, we can detect the memory read on this adjacent page by inspecting the corresponding PTE (Page Table Entry) using the QueryWorkingSetEx API. If the page is resident in our process' working set (e.g. mapped into our process by the debugger), the Valid bit in the _PSAPI_WORKING_SET_EX_BLOCK will be set."
However, I agree that we can probably relax the semantics that I described previously. I will still use /proc/pid/pagemaps to determine if a page has been accessed (if not then it is "Invalid"). I will ignore the complex case of modifying the page protections to NOACCESS and back. I'm hoping this will be sufficient for both bug 45667 and bug 48268.
-Andrew
On 12/18/19 05:07, Ken Thomases wrote:
On Dec 17, 2019, at 6:34 PM, Andrew Wesie awesie@gmail.com wrote:
A stub for bug 45667 has been sitting in staging for a while. It is sufficient for League of Legends, but it is not correct by any definition.
The challenge with MemoryWorkingSetExInformation is that it requires information that is not exposed by the Linux kernel.
Are the semantics of the fields of MEMORY_WORKING_SET_EX_BLOCK documented or explained somewhere? It's hard to comment intelligently without that.
-Ken
.
There is some basic description of the fields here in MS docs: https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-psapi_work...
It is referenced from QueryWorkingSetEx description: https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-queryworki...
The patchset is also related for https://bugs.winehq.org/show_bug.cgi?id=48268, but the thing in that bug is not going to work anyway, working set info is just a minor issue for that rootkit (the bigger include, but not limited to, minifilter FS driver and exhaustive execution environment check / intervention; the thing is not going to work even under VMs or in any sane native Windows installation which does not disable every possible malware protection).
Andrew Wesie awesie@gmail.com writes:
If someone has an alternative approach, or there is appetite using the staging stub in upstream Wine, that would be very welcome feedback.
If the partial stub is enough to make the application happy, that's good enough for now. Adding a more correct but more expensive solution can wait until we find an app that requires it.
On Wed, Dec 18, 2019 at 3:28 PM Alexandre Julliard julliard@winehq.org wrote:
If the partial stub is enough to make the application happy, that's good enough for now. Adding a more correct but more expensive solution can wait until we find an app that requires it.
The reason I revisited this issue is because bug 48268 requires behavior that conflicts with the stub that fixes bug 45667. Unfortunately, both of these bugs are related to anti-cheat systems. I will attempt to pull together an implementation that is a bit simpler, but only handles the corner cases that these systems exercise. I'll leave the other tests as todo_wine.
-Andrew
On 12/19/19 00:28, Alexandre Julliard wrote:
Andrew Wesie awesie@gmail.com writes:
If someone has an alternative approach, or there is appetite using the staging stub in upstream Wine, that would be very welcome feedback.
If the partial stub is enough to make the application happy, that's good enough for now. Adding a more correct but more expensive solution can wait until we find an app that requires it.
Just for consideration, I would like to point out that there is a set of native API functions most of DRM / anticheats calling these days (various NtQuery... functions at the first place). Many of their information classes are not implemented or implemented as simplistic stubs in various out of tree patches. Every time you test such a stuff in the applications you hit a number of these stubs and always have to suspect that this can have something to do with the problem. Sometimes it is, often not. Sorting this out takes a lot of time. So even if there is no application we currently know for sure depending on a correct implementation, still having the correct implementation for (some more) information classes would help greatly in this aspect. It seems to me that NtQueryVirtualMemory() and NtQueryInformationProcess(..., SystemModuleInformation / SystemModuleInformationEx) are currently the top hits.