Modern anti-cheat systems are no longer simple detection layers, they are distributed trust systems spanning kernel drivers, user-mode components, and external validation services. While kernel enforcement has become stricter, user-mode still plays a critical role in how information is collected, validated, and acted upon.
My research into user-mode bypass frameworks is not about avoiding detection, but about understanding where trust is placed, how execution context is validated, and what assumptions are made about user-mode behaviour.
This post walks through the technical ideas behind that research by referencing architectural patterns and code structures rather than instructions.
Why User-Mode Is Still a Meaningful Attack Surface
Even in kernel-heavy anti-cheat designs, user-mode is responsible for:
- Initial data preparation (render state, entity data, input context)
- Communication with kernel components
- Triggering detection heuristics and escalation paths
Many systems assume that kernel enforcement alone is sufficient. In practice, user-mode is where intent is inferred, not where it is enforced. That distinction matters.
Framework Architecture: What I Was Exploring
At a high level, the framework explores three core ideas:
- Controlled user-mode execution context
- Manual control over module layout and visibility
- Reducing kernel-observable anomalies without kernel interaction
This is reflected in how the codebase is structured, not as a monolithic exploit, but as separable components that each test a specific assumption.
Manual Mapping as a Trust Boundary Test
One of the central research components revolves around manual PE mapping.
Instead of relying on the operating system’s loader to:
- Register modules
- Populate loader-linked lists
- Notify instrumentation callbacks
…the research code reconstructs only the minimum runtime state required for execution, while intentionally omitting higher-level registration artifacts.
From a defensive perspective, this raises an important question:
Is detection tied to behavior, or to the presence of expected loader metadata?
When systems rely heavily on loader state (PEB entries, module lists, image notifications), they can be tested by code that executes without participating in those mechanisms, while still remaining valid from the CPU’s perspective.
References
exploit.cpp
#include "exploit.hpp"
#include "utils.hpp"
#include <psapi.h>
#include <stdio.h>
#include <Windows.h>
#include <shlobj.h>
#include <stdint.h>
#include <winternl.h>
#include <mmsystem.h>
#include <time.h>
#include <shlwapi.h>
#include <unordered_set>
#include "pe_mapper.hpp"
#define NTHEADER(ImgBase) PIMAGE_NT_HEADERS64(PIMAGE_DOS_HEADER(ImgBase)->e_lfanew + uint64_t(ImgBase))
#define SET_BIT(Val, Num, Up) \
{ \
if (Up) \
{ \
Val |= (1 << Num); \
} \
else \
{ \
Val &= ~(1 << Num); \
} \
}
#define IS_BIT_SET(Val, Num) (Val & (1 << Num))
#define SHARED_MEM_WPARAM_STRUCT 0x800
unsigned char* make_fake_pe() {
unsigned char* p = (unsigned char*)malloc(0x200);
if (!p) return NULL;
memset(p, 0, 0x200);
*(unsigned short*)(p + 0x0) = 0x5A4D;
*(unsigned int*)(p + 0x3C) = 0x40;
*(unsigned int*)(p + 0x40) = 0x00004550;
*(unsigned short*)(p + 0x44) = 0x8664;
*(unsigned short*)(p + 0x46) = 1;
*(unsigned short*)(p + 0x54) = 0xF0;
*(unsigned short*)(p + 0x58) = 0x20B;
*(unsigned int*)(p + 0x58 + 0x10) = 0x0;
size_t sec = 0x148;
memcpy(p + sec + 0x0, ".data\0\0\0", 8);
*(unsigned int*)(p + sec + 0x8) = 0x1000;
*(unsigned int*)(p + sec + 0xC) = 0x100000 - 0x1000; //offset
*(unsigned int*)(p + sec + 0x10) = 0x1000; //size
*(unsigned int*)(p + sec + 0x14) = 0x200;
*(unsigned int*)(p + sec + 0x24) = 0x60000000u; //permission
return p;
}
OBFUSCATE void CExploit::ChangeProtection(uint64_t Address, size_t size, DWORD protection) {
ShowWindow(ProcessData->ProcessHwnd, 0);
Sleep(0);
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
};
wparam* a = (wparam*)(LocalSharedMemory + SHARED_MEM_WPARAM_STRUCT);
memset(a, 0, sizeof(wparam));
a->arg1 = PAGE_READWRITE;
a->arg2 = rand()*rand();
a->memcpy = set_mrprot;
a->function_ptr = t;
a->lock = 0;
auto hhook = SetWindowsHookExA(WH_SHELL, (HOOKPROC)w, ddll, ProcessData->ThreadID);
if (!hhook) {
printf("Failed critical %08x - process has crashed!\n", GetLastError());
Sleep(5000);
ExitProcess(0);
}
Sleep(0);
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand() * rand());
a->dst.Length = 8;
a->dst.MaximumLength = 8;
a->dst.Buffer = (PWSTR)(mr_data_addr_ptr);
a->src.Length = 8;
a->src.MaximumLength = 8;
a->src.Buffer = (PWSTR)(RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x48);
a->arg1 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x28;
a->arg2 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x38;
a->memcpy = write_fn;
a->function_ptr = t;
a->val = Address;
a->lock = 0;
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand()* rand());
a->dst.Length = 8;
a->dst.MaximumLength = 8;
a->dst.Buffer = (PWSTR)(mr_data_size_ptr);
a->src.Length = 8;
a->src.MaximumLength = 8;
a->src.Buffer = (PWSTR)(RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x48);
a->arg1 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x28;
a->arg2 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x38;
a->memcpy = write_fn;
a->function_ptr = t;
a->val = size;
a->lock = 0;
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand()* rand());
a->arg1 = protection;
a->arg2 = rand() * rand();
a->memcpy = set_mrprot;
a->function_ptr = t;
a->lock = 0;
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand()* rand());
a->dst.Length = 8;
a->dst.MaximumLength = 8;
a->dst.Buffer = (PWSTR)(mr_data_addr_ptr);
a->src.Length = 8;
a->src.MaximumLength = 8;
a->src.Buffer = (PWSTR)(RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x48);
a->arg1 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x28;
a->arg2 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x38;
a->memcpy = write_fn;
a->function_ptr = t;
a->val = mr_data_addr_orig;
a->lock = 0;
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand()* rand());
a->dst.Length = 8;
a->dst.MaximumLength = 8;
a->dst.Buffer = (PWSTR)(mr_data_size_ptr);
a->src.Length = 8;
a->src.MaximumLength = 8;
a->src.Buffer = (PWSTR)(RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x48);
a->arg1 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x28;
a->arg2 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x38;
a->memcpy = write_fn;
a->function_ptr = t;
a->val = mr_data_size_orig;
a->lock = 0;
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand()* rand());
a->arg1 = PAGE_READONLY;
a->arg2 = rand() * rand();
a->memcpy = set_mrprot;
a->function_ptr = t;
a->lock = 0;
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand()* rand());
UnhookWindowsHookEx(hhook);
Sleep(0);
ShowWindow(ProcessData->ProcessHwnd, 1);
return;
}
uint64_t CExploit::MapPEHeader(uint64_t Address)
{
ShowWindow(ProcessData->ProcessHwnd, 0);
Sleep(0);
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
};
wparam* a = (wparam*)(LocalSharedMemory + SHARED_MEM_WPARAM_STRUCT);
memset(a, 0, sizeof(wparam));
a->arg1 = Address;
a->arg2 = 0xFFFFFFFFFFFFFFFF;
a->memcpy = set_protect;
a->function_ptr = t;
a->lock = 0;
auto hhook = SetWindowsHookExA(WH_SHELL, (HOOKPROC)w, ddll, ProcessData->ThreadID);
if (!hhook) {
printf("Failed critical %08x - process has crashed!\n", GetLastError());
Sleep(5000);
ExitProcess(0);
}
Sleep(0);
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand() * rand());
UnhookWindowsHookEx(hhook);
Sleep(0);
ShowWindow(ProcessData->ProcessHwnd, 1);
return 0;
}
uint64_t CExploit::AllocateRX(BYTE* data, size_t size)
{
ShowWindow(ProcessData->ProcessHwnd, 0);
Sleep(0);
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
};
wparam* a = (wparam*)(LocalSharedMemory + SHARED_MEM_WPARAM_STRUCT);
memset(a, 0, sizeof(wparam));
a->arg1 = 0x100000;
a->arg2 = rand() * rand();
a->memcpy = (uintptr_t)GetProcAddress(LoadLibraryA("msvcrt.dll"), "malloc");
a->function_ptr = t;
a->lock = 0;
std::unordered_set<uintptr_t> existing_mem;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, ProcessData->ProcessID);
if (hProcess == INVALID_HANDLE_VALUE)
{
printf("Failed to open process[%d] error[%d]\n", ProcessData->ProcessID, GetLastError());
return false;
}
uint8_t* Address{};
MEMORY_BASIC_INFORMATION Mbi{};
while (true)
{
if (!VirtualQueryEx(hProcess, Address, &Mbi, sizeof(Mbi)))
break;
if (Mbi.State == MEM_COMMIT && Mbi.Protect == PAGE_READWRITE && Mbi.RegionSize == 0x101000 && Mbi.Type == MEM_PRIVATE)
{
existing_mem.insert((uintptr_t)Mbi.BaseAddress);
}
Address += Mbi.RegionSize;
}
ShowWindow(ProcessData->ProcessHwnd, 0);
Sleep(0);
auto hhook = SetWindowsHookExA(WH_SHELL, (HOOKPROC)w, ddll, ProcessData->ThreadID);
if (!hhook) {
printf("Failed critical %08x - process has crashed!\n", GetLastError());
Sleep(5000);
ExitProcess(0);
}
Sleep(0);
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand() * rand());
UnhookWindowsHookEx(hhook);
Sleep(0);
ShowWindow(ProcessData->ProcessHwnd, 1);
Address = 0;
uintptr_t found_addr = 0;
while (true)
{
if (!VirtualQueryEx(hProcess, Address, &Mbi, sizeof(Mbi)))
break;
// printf("%llx - %llx - %d - %d - %d\n", Address, Mbi.RegionSize, Mbi.Type, Mbi.Protect, Mbi.State);
if (Mbi.State == MEM_COMMIT && Mbi.Protect == PAGE_READWRITE && Mbi.RegionSize == 0x101000 && Mbi.Type == MEM_PRIVATE)
{
if (!existing_mem.contains((uintptr_t)Mbi.BaseAddress)) {
found_addr = (uintptr_t)Mbi.BaseAddress;
break;
}
}
Address += Mbi.RegionSize;
}
CloseHandle(hProcess);
if (found_addr) {
auto x = make_fake_pe();
unsigned char empty[0x200]{};
WriteData(found_addr, (BYTE*)x, 0x200);
WriteData(found_addr + 0x100000 - 0x1000, data, size);
MapPEHeader(found_addr);
WriteData(found_addr, (BYTE*)empty, 0x200);
free(x);
return found_addr + 0x100000 - 0x1000;
}
return 0;
}
uint64_t CExploit::ReadU64(uint64_t Address)
{
ShowWindow(ProcessData->ProcessHwnd, 0);
Sleep(0);
struct wparam {
uint64_t memcpy{}; //0
uint64_t arg2{}; //8
uint64_t function_ptr{}; //0x10
uint64_t arg1{}; // 0x18
uint64_t lock{}; // 0x20
UNICODE_STRING dst{}; // 0x28
UNICODE_STRING src{}; // 0x38
uint64_t val{}; // 0x48
};
wparam* a = (wparam*)(LocalSharedMemory + SHARED_MEM_WPARAM_STRUCT);
memset(a, 0, sizeof(wparam));
a->dst.Length = 8;
a->dst.MaximumLength = 8;
a->dst.Buffer = (PWSTR)(RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x48);
a->src.Length = 8;
a->src.MaximumLength = 8;
a->src.Buffer = (PWSTR)(Address);
a->arg1 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x28;
a->arg2 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x38;
a->memcpy = write_fn;
a->function_ptr = t;
a->lock = 0;
auto hhook = SetWindowsHookExA(WH_SHELL, (HOOKPROC)w, ddll, ProcessData->ThreadID);
if (!hhook) {
printf("Failed critical %08x - process has crashed!\n", GetLastError());
Sleep(5000);
ExitProcess(0);
}
Sleep(0);
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand() % 0xFFFFFFFFFFFFFFFF);
UnhookWindowsHookEx(hhook);
Sleep(0);
ShowWindow(ProcessData->ProcessHwnd, 1);
return a->val;
}
void CExploit::ReadData(uint64_t Address, BYTE* Data, size_t size)
{
if (size > 0x700) {
printf("Read is too big\n");
__debugbreak();
}
ShowWindow(ProcessData->ProcessHwnd, 0);
Sleep(0);
struct wparam {
uint64_t memcpy{}; //0
uint64_t arg2{}; //8
uint64_t function_ptr{}; //0x10
uint64_t arg1{}; // 0x18
uint64_t lock{}; // 0x20
UNICODE_STRING dst{}; // 0x28
UNICODE_STRING src{}; // 0x38
uint64_t val{}; // 0x48
};
wparam* a = (wparam*)(LocalSharedMemory + SHARED_MEM_WPARAM_STRUCT);
memset(a, 0, sizeof(wparam));
a->dst.Length = size;
a->dst.MaximumLength = size;
a->dst.Buffer = (PWSTR)(RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x48);
a->src.Length = size;
a->src.MaximumLength = size;
a->src.Buffer = (PWSTR)(Address);
a->arg1 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x28;
a->arg2 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x38;
a->memcpy = write_fn;
a->function_ptr = t;
a->lock = 0;
auto hhook = SetWindowsHookExA(WH_SHELL, (HOOKPROC)w, ddll, ProcessData->ThreadID);
if (!hhook) {
printf("Failed critical %08x - process has crashed!\n", GetLastError());
Sleep(5000);
ExitProcess(0);
}
Sleep(0);
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand() % 0xFFFFFFFFFFFFFFFF);
UnhookWindowsHookEx(hhook);
Sleep(0);
ShowWindow(ProcessData->ProcessHwnd, 1);
memcpy(Data, &a->val, size);
}
void CExploit::WriteU64(uint64_t Address, uint64_t Value)
{
ShowWindow(ProcessData->ProcessHwnd, 0);
Sleep(0);
struct wparam {
uint64_t memcpy{}; //0
uint64_t arg2{}; //8
uint64_t function_ptr{}; //0x10
uint64_t arg1{}; // 0x18
uint64_t lock{}; // 0x20
UNICODE_STRING dst{}; // 0x28
UNICODE_STRING src{}; // 0x38
uint64_t val{}; // 0x48
};
wparam* a = (wparam*)(LocalSharedMemory + SHARED_MEM_WPARAM_STRUCT);
memset(a, 0, sizeof(wparam));
a->dst.Length = 8;
a->dst.MaximumLength = 8;
a->dst.Buffer = (PWSTR)(Address);
a->src.Length = 8;
a->src.MaximumLength = 8;
a->src.Buffer = (PWSTR)(RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x48);
a->arg1 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x28;
a->arg2 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x38;
a->memcpy = write_fn;
a->function_ptr = t;
a->val = Value;
a->lock = 0;
auto hhook = SetWindowsHookExA(WH_SHELL, (HOOKPROC)w, ddll, ProcessData->ThreadID);
if (!hhook) {
printf("Failed critical %08x - process has crashed!\n", GetLastError());
Sleep(5000);
ExitProcess(0);
}
Sleep(0);
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand() % 0xFFFFFFFFFFFFFFFF);
UnhookWindowsHookEx(hhook);
Sleep(0);
ShowWindow(ProcessData->ProcessHwnd, 1);
return;
}
void CExploit::WriteData(uint64_t Address, BYTE* Data, size_t size)
{
struct wparam {
uint64_t memcpy{}; //0
uint64_t arg2{}; //8
uint64_t function_ptr{}; //0x10
uint64_t arg1{}; // 0x18
uint64_t lock{}; // 0x20
UNICODE_STRING dst{}; // 0x28
UNICODE_STRING src{}; // 0x38
uint64_t val{}; // 0x48
};
wparam* a = (wparam*)(LocalSharedMemory + SHARED_MEM_WPARAM_STRUCT);
size_t max_size = 0x50;
if (size > max_size) {
size_t chunks = (size + max_size - 1) / max_size;
for (size_t i = 0; i < chunks; ++i) {
size_t remainder = size % max_size;
size_t chunk_size = (i == chunks - 1) ? ((remainder == 0) ? max_size : remainder) : max_size;
WriteData(Address + i * max_size, Data + i * max_size, chunk_size);
}
return;
}
ShowWindow(ProcessData->ProcessHwnd, 0);
Sleep(0);
memset(a, 0, sizeof(wparam));
a->dst.Length = size;
a->dst.MaximumLength = size;
a->dst.Buffer = (PWSTR)(Address);
a->src.Length = size;
a->src.MaximumLength = size;
a->src.Buffer = (PWSTR)(RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x48);
a->arg1 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x28;
a->arg2 = RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT + 0x38;
a->memcpy = write_fn;
a->function_ptr = t;
a->lock = 0;
memcpy(&a->val, Data, size);
auto hhook = SetWindowsHookExA(WH_SHELL, (HOOKPROC)w, ddll, ProcessData->ThreadID);
if (!hhook) {
printf("Failed critical %08x - process has crashed!\n", GetLastError());
Sleep(5000);
ExitProcess(0);
}
Sleep(0);
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)RemoteSharedMemory + SHARED_MEM_WPARAM_STRUCT, rand() % 0xFFFFFFFFFFFFFFFF);
UnhookWindowsHookEx(hhook);
Sleep(0);
ShowWindow(ProcessData->ProcessHwnd, 1);
return;
}
bool CExploit::Initialize(CProcess* Proc)
{
srand(GetTickCount());
ProcessData = Proc;
nt = LoadLibraryA("ntdll.dll");
sh = LoadLibraryA("shell32.dll");
ddll = LoadLibraryA("uxtheme.dll");
// Locate shared memory in our client.
if (!FindSharedMemory(HANDLE(-1), &LocalSharedMemory, &SharedCount, (char*)"randomfuckingnameyougotnoidea.exe"))
{
printf("Failed to find shared memory in current process\n");
return false;
}
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, ProcessData->ProcessID);
if (hProcess == INVALID_HANDLE_VALUE)
{
printf("Failed to open process[%d] error[%d]\n", ProcessData->ProcessID, GetLastError());
return false;
}
if (!FindSharedMemory(hProcess, &RemoteSharedMemory, &SharedCount, ProcessData->exe_name))
{
CloseHandle(hProcess);
printf("Failed to find shared memory in target process\n");
return false;
}
PROCESS_BASIC_INFORMATION pbi{};
NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), 0);
ProcessData->peb = (uintptr_t)pbi.PebBaseAddress;
CloseHandle(hProcess);
if ((*(uint32_t*)0x7FFE0260) >= 26100)
{
typedef struct _THREAD_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
KAFFINITY AffinityMask;
KPRIORITY Priority;
KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION;
HANDLE hThread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, false, ProcessData->ThreadID);
THREAD_BASIC_INFORMATION x{};
ULONG retlen{};
NtQueryInformationThread(hThread, (THREADINFOCLASS)0, &x, sizeof(x), &retlen);
CloseHandle(hThread);
PVOID attack_addr = (PVOID)((uint64_t)x.TebBaseAddress + 0x1850);
ShowWindow(ProcessData->ProcessHwnd, SW_HIDE); //wtf man
auto hhook = SetWindowsHookExA(WH_SHELL, (HOOKPROC)GetProcAddress(nt, "RtlOpenCrossProcessEmulatorWorkConnection"), ddll, ProcessData->ThreadID);
Sleep(0);
SendMessageA(ProcessData->ProcessHwnd, WM_APPCOMMAND, (WPARAM)attack_addr, (LPARAM)attack_addr);
UnhookWindowsHookEx(hhook);
ShowWindow(ProcessData->ProcessHwnd, SW_SHOW); //wtf man
printf("Fixup applied\n");
}
}
/*
if (!ProcessData->discord_path)
{
printf("Failed to find discord path\n");
return false;
}
*/
/* Map and get discord rwx */
{
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;
}
t = t & 0xFFFFFFFFFFFFFFF0;
const char* setProtectPattern = "48 8b e9 48 8b d1 41 8d 48 03";
set_protect = (uintptr_t)PatternScan(nt, setProtectPattern);
if (!set_protect) {
printf("Failed to find set_protect\n");
return false;
}
while (*(unsigned char*)set_protect != 0xCC) set_protect--;
set_protect++;
const char* mrDataPattern = "48 8B 05 ?? ?? ?? ?? 4C 8D 44 24 ?? 48 89 44 24";
set_mrprot = (uintptr_t)PatternScan(nt, mrDataPattern);
if (!set_mrprot) {
printf("Failed to find set_mrprot\n");
return false;
}
mr_data_addr_ptr = set_mrprot + *(int32_t*)(set_mrprot + 3) + 7;
mr_data_size_ptr = set_mrprot + *(int32_t*)(set_mrprot + 3) + 7 - 0x10;
mr_data_addr_orig = *(uintptr_t*)mr_data_addr_ptr;
mr_data_size_orig = *(uintptr_t*)mr_data_size_ptr;
while (*(unsigned char*)set_mrprot != 0xCC) set_mrprot--;
set_mrprot++;
write_fn = (uint64_t)GetProcAddress(nt, "RtlCopyString");
}
return true;
}
uint64_t CExploit::get_LocalSharedMemory()
{
return LocalSharedMemory;
}
uint64_t CExploit::get_RemoteSharedMemory()
{
return RemoteSharedMemory;
}
uint64_t CExploit::get_RemoteBase()
{
return RemoteProcessBase;
}
bool CExploit::FindSharedMemory(HANDLE hProcess, uint64_t* MemoryOut, uint64_t* SharedCountOut, char* exe_name)
{
if (hProcess == (HANDLE)-1)
{
uint8_t* Address{};
MEMORY_BASIC_INFORMATION Mbi{};
bool found_it = false;
while (true)
{
if (!VirtualQueryEx(hProcess, Address, &Mbi, sizeof(Mbi)))
break;
if (Mbi.State == MEM_COMMIT && Mbi.Protect == PAGE_READWRITE && Mbi.RegionSize == 0x1000 && Mbi.Type == MEM_MAPPED)
{
//scan inside SHCore.dll to see if this address is inside data
auto shcore = LoadLibraryA("SHCore.dll");
uint8_t* Address2 = (uint8_t*)shcore;
MEMORY_BASIC_INFORMATION Mbi2{};
int i = 0;
while (VirtualQuery(Address2, &Mbi2, sizeof(Mbi2)))
{
if (i >= 9)
break;
if (Mbi2.Type == MEM_IMAGE && Mbi2.Protect == PAGE_READWRITE)
{
for (int ii = 0; ii < Mbi2.RegionSize; ii += 0x8)
{
if (*(uintptr_t*)&Address2[ii] == (uintptr_t)Mbi.BaseAddress)
{
found_it = true;
*MemoryOut = (uintptr_t)Mbi.BaseAddress;
break;
}
}
}
if (found_it)
break;
i++;
Address2 += Mbi2.RegionSize;
}
}
if (found_it)
break;
Address += Mbi.RegionSize;
}
/* HANDLE h_map;
h_map = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, "windows_shell_global_counters");
if (h_map == nullptr)
return false;
uintptr_t frame_buffer = (uintptr_t)MapViewOfFile(h_map, FILE_MAP_ALL_ACCESS, 0, 0, 0);
CloseHandle(h_map);
if (!frame_buffer)
return false;
printf("FrameBuffer: %llx\n", frame_buffer);
*MemoryOut = frame_buffer;*/
return found_it;
}
bool found = false;
uint8_t* Address{};
MEMORY_BASIC_INFORMATION Mbi{};
while (true)
{
if (!VirtualQueryEx(hProcess, Address, &Mbi, sizeof(Mbi)))
break;
if (hProcess != GetCurrentProcess() && Mbi.State == MEM_COMMIT && Mbi.Protect == PAGE_READONLY && Mbi.RegionSize == 0x1000 && Mbi.Type == MEM_IMAGE)
{
char filename[1024]{};
K32GetMappedFileNameA(hProcess, Mbi.BaseAddress, filename, sizeof(filename));
if (strstr(filename, "DiscordHook64"))
{
ProcessData->discord_base = (uintptr_t)Address;
char dos_path[1024]{};
utils::DevicePathToDosPath(filename, dos_path, sizeof(dos_path));
ProcessData->discord_path = _strdup(dos_path);
}
else if (strstr(filename, "shell32.dll") || strstr(filename, "Shell32.dll") || strstr(filename, "SHELL32.dll"))
{
if ((uintptr_t)sh != (uintptr_t)Address) {
uintptr_t delta = (uintptr_t)Address - (uintptr_t)sh;
t += delta;
}
}
else if (strstr(filename, exe_name))
{
ProcessData->base = (uintptr_t)Address;
}
}
else if (!found && Mbi.State == MEM_COMMIT && Mbi.Protect == PAGE_READWRITE && Mbi.RegionSize == 0x1000 && Mbi.Type == MEM_MAPPED)
{
*(SHORT*)((this->LocalSharedMemory) + 0xF00) = 0x00;
auto hhook = SetWindowsHookExA(WH_SHELL, (HOOKPROC)GetProcAddress(nt, "RtlGetIntegerAtom"), ddll, ProcessData->ThreadID);
ShowWindow(ProcessData->ProcessHwnd, SW_HIDE);
Sleep(1);
auto result = SendMessage(ProcessData->ProcessHwnd, WM_APPCOMMAND, (uintptr_t)Address + 0xF00, (uintptr_t)Address + 0xF00);
Sleep(1);
auto unhook = UnhookWindowsHookEx(hhook);
ShowWindow(ProcessData->ProcessHwnd, SW_SHOW);
if (*(SHORT*)((this->LocalSharedMemory) + 0xF00)) {
*MemoryOut = (uintptr_t)Address;
found = true;
}
}
else if (Mbi.State == MEM_COMMIT && Mbi.Protect == PAGE_READWRITE && Mbi.RegionSize == 0x3201000 && Mbi.Type == MEM_MAPPED)
{
ProcessData->discord_framebuffer = (uintptr_t)Address;
}
Address += Mbi.RegionSize;
}
return found;
}
std::uint8_t* CExploit::PatternScan(void* module, const char* signature)
{
static auto pattern_to_byte = [](const char* pattern)
{
auto bytes = std::vector<int>{};
auto start = const_cast<char*>(pattern);
auto end = const_cast<char*>(pattern) + strlen(pattern);
for (auto current = start; current < end; ++current)
{
if (*current == '?')
{
++current;
if (*current == '?')
++current;
bytes.push_back(-1);
}
else
{
bytes.push_back(strtoul(current, ¤t, 16));
}
}
return bytes;
};
auto dosHeader = (PIMAGE_DOS_HEADER)module;
auto ntHeaders = (PIMAGE_NT_HEADERS)((std::uint8_t*)module + dosHeader->e_lfanew);
auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage;
auto patternBytes = pattern_to_byte(signature);
auto scanBytes = reinterpret_cast<std::uint8_t*>(module);
auto s = patternBytes.size();
auto d = patternBytes.data();
for (auto i = 0ul; i < sizeOfImage - s; ++i)
{
bool found = true;
for (auto j = 0ul; j < s; ++j)
{
if (scanBytes[i + j] != d[j] && d[j] != -1)
{
found = false;
break;
}
}
if (found)
{
return &scanBytes[i];
}
}
return nullptr;
}
void CExploit::SetupRW()
{
}
bool CProcess::Initialize(const wchar_t* WindowName, const wchar_t* ClassName, char* exe_name, HWND target_window)
{
if (!target_window)
{
ProcessHwnd = FindWindowW(ClassName, WindowName);
}
else
{
ProcessHwnd = target_window;
}
this->exe_name = exe_name;
if (!ProcessHwnd)
return false;
ThreadID = GetWindowThreadProcessId(ProcessHwnd, &ProcessID);
return ThreadID != 0;
}