July 10, 2026
Using Game Cheat PoC Code to Exploit Userland Processes. (Part 1).
Introduction

By Swifty
6 min read
Introduction
During early 2026, as it often does, some PoC code crossed my path. What stood out about this one however were several things; it was described on the original authors page as a 'Usermode exploit to bypass any AC using a 0day shatter attack.' which first of all peaked my interest, there is so much growing overlap between game cheats and the bypassing of anti-cheat software with malware development and its requirements to bypass EDR/AV that there was bound to be something interesting at play here.
Secondly, a quick scan of the code revealed none of the usual calls to stuff like WriteProcessMemory, ReadProcessMemory, or NtProtectVirtualMemory; most of which if used directly… will ensure your EDR/AV tooling will leap to attention faster than my pug hearing the fridge door open.
After some initial reviews of the PoC it became apparent that this exploit would also be somewhat tricky for MS to patch given it's clever use of legitimate Windows GUI functionality.
This came at a time when the world had just been exposed to the fact MS Edge browser was seemingly loading all it's password manager credentials into memory in plain text on startup [Link]. Their response to this at the time was to downplay the issue and claim it was some kind of 'feature'…which as you can imagine went down really well.
Later that same month the Microsoft VP for Edge Security wrote on LinkedIn 'We are addressing the originally reported issue immediately. We no longer load passwords into memory on startup.' in a remarkable but welcome backtrack. [Link]
This got me thinking about chaining together some of these 'features' in a term I am coining as 'Feature Orientated Exploitation'; I wondered if there was a way to use this game cheat PoC and all it's AC bypassing glory to silently target other GUI processes…like say a browser?
This article will explore in two parts firstly how the exploit works (to my understanding) and then part 2 will look at some similar yet not quite so bad 'features' of other browsers (chrome) and how we can use this PoC exploit code to extract interesting secrets directly from the browsers process memory.
What is this?
So let us start with the original PoC [Link]. The first thing to note is out the box, it is pretty bare bones, it's not going to magically exploit all the things on first compile.
Think of it almost as a framework or a method of exploitation that we can build upon for our own use cases of education and fun. (A huge shout to the original author for publishing).
The exploit itself operates in userland and achieves arbitrary read/write into another process without calling WriteProcessMemory or ReadProcessMemory. It abuses legitimate Windows message-passing and various code reuse gadgets inside trusted system DLLs that happen to be loaded into pretty much any and every GUI process in Windows.
How it works (In my head)
To wrap my head around this I broke it down into 3 main stages. I should say there are more..in particular relating to memory protection antics but I wanted to keep this focused on building understanding of the main mechanism.
Stage 1. Shared Memory Channel
Windows maintains a named shared memory section called windows_shell_global_counters (managed by the shell subsystem) that is mapped into virtually every GUI process. It's used by the Windows shell to track stuff like process-wide interface states, window animations, and global instance counters across running applications.
Because it is backed by the same physical pages in memory, anything written to it in one process is immediately visible in another and makes for a a nice way sharing data between processes while avoiding the ever noisy WriteProcessMemory.
The tricky part now is that each process will have it's own virtual addressing for this shared space; (spoilers) if we want to attack another process by dumping stuff into this shared space for it to read, we need first to know what the target processes virtual addressing for this space is.
The exploit first maps this section locally and then scans the target process's virtual address space to find where the same physical page appears there.
To do this, our attacking process uses a form of sentinel probe: a WH_SHELL hook is installed on the target process pointing to ntdll!RtlGetIntegerAtom.
The attacking process then sends a message to the target process using WM_APPCOMMAND; this is a method of notifying a window that the user generated an application command event.
In other words, we first install a hook on the target process to listen for events and then send a message to that process which triggers the event.
When the hook fires inside the target, RtlGetIntegerAtom writes the hook code (12) as a USHORT to whatever candidate address was passed as wParam inside our message. If the write is visible on the local side of the shared page, we have confirmed the correct mapping and now know the virtual address our target process is using.
Stage 2. Dispatch Struct
Understanding the anatomy of stage 1 is important because everything else pretty much follows the same workflow.
In stage 2 the main difference is we now start to make use of a couple of gadgets within ntdll.dll and shell32.dll; two dll's that are loaded by default into almost every windows GUI process.
The first of these gadgets/code stubs will be use to read a struct that we will place inside our shared memory location. The second is then used to call a function pointer that we store within the struct.
In more detail then, the two gadgets look like this:
win this case is a code stub that comes fromntdll.dlland is a hook callback that reads the struct and calls throught.ton the other hand comes fromshell32.dlland calls the function pointer from the dispatch struct.
The PoC uses some interesting pattern matching to find these w and t values:
const char* writeGadgetPattern = "?? 89 ?? ?? 08 57 ?? 83 ?? 20 ?? 8d ?? 20 ?? 8b ?? e8";
w = (uintptr_t)PatternScan(nt, writeGadgetPattern);
if (!w) {
printf("Failed to find W\n");
return false;
}
const char* trampPattern = "48 83 ec ?? 48 8b da 48 85 d2 74 ?? 83 7a ?? ?? 75 ?? 83 7a ?? ?? 75 ??";
t = (uintptr_t)PatternScan(sh, trampPattern);
if (!t) {
printf("Failed to find t\n");
return false;
}
const char* writeGadgetPattern = "?? 89 ?? ?? 08 57 ?? 83 ?? 20 ?? 8d ?? 20 ?? 8b ?? e8";
w = (uintptr_t)PatternScan(nt, writeGadgetPattern);
if (!w) {
printf("Failed to find W\n");
return false;
}
const char* trampPattern = "48 83 ec ?? 48 8b da 48 85 d2 74 ?? 83 7a ?? ?? 75 ?? 83 7a ?? ?? 75 ??";
t = (uintptr_t)PatternScan(sh, trampPattern);
if (!t) {
printf("Failed to find t\n");
return false;
}
Now we have a method of reading the struct, we should really talk about the actual anatomy of the struct!
The struct has a few things of note inside it:
- A
memcpyfield - the actual function to invoke (e.g.RtlCopyString) - A
function_ptrfield - set to the shell32 trampoline gadget (t) - Some arguments (
arg1,arg2) - A UNICODE_STRING pair (
dst/src) - A data slot (
val) used to pass or receive a value
In practice it looks a bit like this:
struct wparam {
uint64_t memcpy{};
uint64_t arg2{};
uint64_t function_ptr{};
uint64_t arg1{};
uint64_t lock{};
UNICODE_STRING dst{}; // 0x28
UNICODE_STRING src{}; // 0x38
uint64_t val{}; // 0x48
}; struct wparam {
uint64_t memcpy{};
uint64_t arg2{};
uint64_t function_ptr{};
uint64_t arg1{};
uint64_t lock{};
UNICODE_STRING dst{}; // 0x28
UNICODE_STRING src{}; // 0x38
uint64_t val{}; // 0x48
};Once this struct is populated, it is then written to a specific location within the shared memory space.
We then (as before) setup a WH_SHELL hook on the target process/thread once again. But this time the hook callback is set to w(our gadget inside ntdll.dll) that reads the dispatch struct from the shared page and calls function_ptr (the shell32 trampoline t).
The trampoline t then calls the memcpy field, the actual target function (e.g. RtlCopyString).
Now to trigger this string of events, we revert back to our WM_APPCOMMAND messaging, once again triggering our hook:
SendMessageA(hwnd, WM_APPCOMMAND, remote_shared_mem + 0x800, ...) is sent.
The message is then dispatched in the target process's own thread context, triggering the hook.
Now it's important to note at this stage that no code has been injected as such; the PoC is only making use of existing instructions inside trusted system DLLs and with our struct setup and a method to execute its contents, we are now ready to populate it with something a little more interesting!
Stage 3. Read/Write
The goal really of this entire thing is to achieve some form of read/write primitive which we can use for pretty much whatever we decide. As I mentioned at the start, my own goal with this was to use it as a method of reading critical areas of memory from within browsers to extract secrets; and this exploit method has the potential to help with dance around all sorts of protections and sandboxing.
If we go back once again to our struct, in order to read and write to memory we simply use ntdll's RtlCopyString as the function call along side populating a source and destination.
Read (ReadU64 / ReadData):
Sets write_fn = ntdll!RtlCopyString as the function to call. The UNICODE_STRING.Buffer src pointer is set to the target address to read, and dst is set to point back into the shared page (val slot). When the hook fires in the target, RtlCopyString copies specified bytes from the target address into the shared page, which the attacker then reads locally.
Write (WriteU64 / WriteData):
Same process but, reversed. The attacker writes the desired bytes into the val slot of the shared page, sets src to point to that slot, and sets dst to the target address to write. When the hook fires, RtlCopyString copies from the shared page into the target address.
There is obviously way more to the exploit than just this, but I wanted to get the key headlines across before we dive into part 2 where we will explore some quirks of Google Chrome's password manager and its handling of passwords in memory…and introduce some of my modifications to this exploit that enable extraction of secrets and the ability to investigate any GUI processes to hunt for hidden (or not so hidden…) secrets. See you in part 2!