[PATCH 0/3] RFC: Implement MemoryWorkingSetExInformation.

Andrew Wesie awesie at gmail.com
Wed Dec 18 18:14:04 CST 2019

On Wed, Dec 18, 2019 at 4:24 PM Ken Thomases <ken at 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.
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.


More information about the wine-devel mailing list