Add files via upload

This commit is contained in:
TALON SCHMELER
2025-11-26 01:46:55 +01:00
committed by GitHub
commit 24d0444837
7 changed files with 2396 additions and 0 deletions

901
exploit.cpp Normal file
View File

@@ -0,0 +1,901 @@
#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, &current, 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;
}

95
exploit.hpp Normal file
View File

@@ -0,0 +1,95 @@
#pragma once
#include <Windows.h>
#include <cstdint>
#define OBFUSCATE __attribute__((annotate("obfuscate")))
#define BAD_READ_VALUE 0xBACABACABACABACA
class CProcess
{
public:
DWORD ThreadID{};
DWORD ProcessID{};
HWND ProcessHwnd{};
uintptr_t peb{};
uintptr_t discord_base{};
uintptr_t discord_framebuffer{};
uintptr_t base{};
char* exe_name{};
char* discord_path{};
uintptr_t pmw_tramp_offset{};
uintptr_t pma_tramp_offset{};
uintptr_t gmw_tramp_offset{};
uintptr_t present_tramp_offset{};
uintptr_t spoofcall_offset{};
uintptr_t grid_offset{};
uintptr_t disable_input_offset{};
/// @brief Initializes the hwnd and process ID elements of the class
/// @param WindowName
/// @param ClassName
/// @param exe_name
/// @return Whether the initialization was successful
bool Initialize(const wchar_t* WindowName, const wchar_t* ClassName = nullptr, char* exe_name = (char*)"game.exe", HWND target_window = nullptr);
};
typedef struct ModuleListNode
{
char* moduleName;
uint64_t baseAddress;
struct ModuleListNode* next;
} ModuleListNode;
class CExploit
{
public:
OBFUSCATE uint64_t ReadU64(uint64_t Address);
OBFUSCATE void ReadData(uint64_t Address, BYTE* Data, size_t Size);
OBFUSCATE void WriteU64(uint64_t Address, uint64_t Value);
OBFUSCATE void WriteData(uint64_t Address, BYTE* Data, size_t Size);
OBFUSCATE uint64_t AllocateRX(BYTE* data, size_t size);
OBFUSCATE uint64_t MapPEHeader(uint64_t Address);
OBFUSCATE void ChangeProtection(uint64_t Address, size_t size, DWORD protection);
OBFUSCATE bool Initialize(CProcess* Proc);
OBFUSCATE uint64_t get_LocalSharedMemory();
OBFUSCATE uint64_t get_RemoteSharedMemory();
OBFUSCATE uint64_t get_RemoteBase();
private:
OBFUSCATE bool FindSharedMemory(HANDLE hProcess, uint64_t* MemoryOut, uint64_t* SharedCountOut, char* exe_name);
OBFUSCATE std::uint8_t* PatternScan(void* module, const char* signature);
OBFUSCATE void SetupRW();
private:
CProcess* ProcessData{};
uint64_t SharedCount{};
uint64_t LocalSharedMemory{};
uint64_t RemoteSharedMemory{};
uint64_t RemoteProcessBase{};
uintptr_t set_protect{};
uintptr_t mr_data_addr_ptr{};
uintptr_t mr_data_size_ptr{};
uintptr_t mr_data_addr_orig{};
uintptr_t mr_data_size_orig{};
uintptr_t set_mrprot{};
uintptr_t r{};
uintptr_t t{};
uintptr_t w{};
uint64_t read_fn{};
uint64_t write_fn{};
HMODULE nt{};
HMODULE sh{};
HMODULE ddll{};
};

1069
internal-render-hook.cpp Normal file

File diff suppressed because it is too large Load Diff

232
pe_mapper.cpp Normal file
View File

@@ -0,0 +1,232 @@
#include "pe_mapper.hpp"
#include <fstream>
PEMemoryMapper::PEMemoryMapper(const std::string& path)
{
/* Open file */
this->binary_.open(path, std::ios::binary);
/* Parse optional header */
IMAGE_DOS_HEADER dos_header;
binary_.seekg(0);
binary_.read(reinterpret_cast<char*>(&dos_header), sizeof(dos_header));
IMAGE_NT_HEADERS nt_headers;
binary_.seekg(dos_header.e_lfanew);
binary_.read(reinterpret_cast<char*>(&nt_headers), sizeof(nt_headers));
/* Set base address */
base_address_ = nt_headers.OptionalHeader.ImageBase;
/* Set memory size */
memory_size_ = nt_headers.OptionalHeader.SizeOfImage;
this->memory_.resize(memory_size_, 0);
binary_.seekg(0);
this->map_sections();
}
std::vector<uint8_t> PEMemoryMapper::read_from_va(uint64_t va, size_t size) const
{
uint64_t offset = va - this->base_address_;
if (offset + size > this->memory_size_)
{
return { };
}
return std::vector<uint8_t>(this->memory_.begin() + offset, this->memory_.begin() + offset + size);
}
void PEMemoryMapper::write_to_va(uint64_t va, const std::vector<uint8_t>& data)
{
uint64_t offset = va - this->base_address_;
if (offset + data.size() > this->memory_size_)
{
return;
}
std::copy(data.begin(), data.end(), this->memory_.begin() + offset);
}
bool PEMemoryMapper::is_va_mapped(uint64_t va) const
{
uint64_t offset = va - this->base_address_;
if (offset >= this->memory_.size())
{
return false;
}
return true;
}
uint8_t* PEMemoryMapper::get_data_pointer(uint64_t va)
{
uint64_t offset = va - this->base_address_;
if (offset >= this->memory_.size())
{
return nullptr;
}
return this->memory_.data() + offset;
}
std::vector<uint8_t>& PEMemoryMapper::get_memory()
{
return this->memory_;
}
uintptr_t PEMemoryMapper::sigscan(const char* pattern)
{
auto base = this->memory_.data();
std::string signature = this->hex_to_bytes(pattern);
u_char first = static_cast<u_char>(signature.at(0));
u_char* end = (base + memory_size_) - signature.length();
for (; base < end; ++base)
{
if (*base != first)
continue;
u_char* bytes = base;
auto sig = (u_char*)signature.c_str();
for (; *sig; ++sig, ++bytes)
{
if (*sig == '?')
continue;
if (*bytes != *sig)
goto end;
}
return (uintptr_t)base;
end:;
}
return NULL;
}
std::string PEMemoryMapper::hex_to_bytes(std::string hex)
{
std::string bytes;
std::erase_if(hex, isspace);
for (uint32_t i = 0; i < hex.length(); i += 2)
{
if (static_cast<u_char>(hex[i]) == '?')
{
bytes += '?';
i -= 1;
continue;
}
u_char byte = static_cast<u_char>(std::strtol(hex.substr(i, 2).c_str(), nullptr, 16));
bytes += byte;
}
return bytes;
}
void PEMemoryMapper::map_sections()
{
// Read DOS Header
IMAGE_DOS_HEADER dos_header = { };
if (!read_struct(dos_header, 0))
{
return;
}
if (dos_header.e_magic != IMAGE_DOS_SIGNATURE)
{
return;
}
// Read NT Headers
DWORD pe_offset = dos_header.e_lfanew;
DWORD signature = 0;
if (!read_struct(signature, pe_offset))
{
return;
}
if (signature != IMAGE_NT_SIGNATURE)
{
return;
}
// Read File Header
IMAGE_FILE_HEADER file_header = { };
if (!read_struct(file_header, pe_offset + sizeof(DWORD)))
{
return;
}
// Read and verify Optional Header
size_t optional_header_offset = pe_offset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
WORD magic = 0;
if (!read_struct(magic, optional_header_offset))
{
return;
}
// Handle PE32 vs PE32+
if (magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
{
IMAGE_OPTIONAL_HEADER32 optional_header = { };
if (!read_struct(optional_header, optional_header_offset))
{
return;
}
base_address_ = optional_header.ImageBase;
memory_size_ = optional_header.SizeOfImage;
}
else if (magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
{
IMAGE_OPTIONAL_HEADER64 optional_header = { };
if (!read_struct(optional_header, optional_header_offset))
{
return;
}
base_address_ = optional_header.ImageBase;
memory_size_ = optional_header.SizeOfImage;
}
else
{
return;
}
// Allocate memory with proper size checks
if (memory_size_ == 0 || memory_size_ > MAX_REASONABLE_SIZE)
{
return;
}
memory_.resize(memory_size_, 0);
// Calculate section headers offset
size_t section_headers_offset = pe_offset +
sizeof(DWORD) +
sizeof(IMAGE_FILE_HEADER) +
file_header.SizeOfOptionalHeader;
// Map each section
for (int i = 0; i < file_header.NumberOfSections; i++)
{
IMAGE_SECTION_HEADER section_header = { };
if (!read_struct(section_header, section_headers_offset + (i * sizeof(IMAGE_SECTION_HEADER))))
{
return;
}
// Validate section header
if (section_header.VirtualAddress >= memory_size_ ||
section_header.Misc.VirtualSize > memory_size_ ||
section_header.VirtualAddress + section_header.Misc.VirtualSize > memory_size_)
{
return;
}
// Calculate correct sizes
size_t virtual_size = section_header.Misc.VirtualSize;
if (virtual_size == 0)
{
virtual_size = section_header.SizeOfRawData;
}
size_t copy_size = min(static_cast<size_t>(section_header.SizeOfRawData), virtual_size);
// Validate raw data
if (section_header.PointerToRawData + copy_size > get_file_size())
{
return;
}
// Copy section data
binary_.seekg(section_header.PointerToRawData);
binary_.read(reinterpret_cast<char*>(memory_.data() + section_header.VirtualAddress),
copy_size);
}
}

48
pe_mapper.hpp Normal file
View File

@@ -0,0 +1,48 @@
#include <Windows.h>
#include <vector>
#include <string>
#include <fstream>
class PEMemoryMapper
{
public:
PEMemoryMapper( const std::string& path );
std::vector<uint8_t> read_from_va( uint64_t va, size_t size ) const;
void write_to_va( uint64_t va, const std::vector<uint8_t> &data );
bool is_va_mapped( uint64_t va ) const;
uint8_t* get_data_pointer( uint64_t va );
std::vector<uint8_t>& get_memory( );
uintptr_t sigscan( const char* pattern );
template<typename T>
bool read_struct(T& structure, size_t offset) {
binary_.seekg(offset);
binary_.read(reinterpret_cast<char*>(&structure), sizeof(T));
return binary_.good();
}
size_t get_file_size() {
auto current_pos = binary_.tellg();
binary_.seekg(0, std::ios::end);
size_t size = binary_.tellg();
binary_.seekg(current_pos);
return size;
}
template<typename T>
T read( uint64_t va ) const
{
return *reinterpret_cast<T *>( this->read_from_va( va, sizeof( T ) ).data( ) );
}
private:
static constexpr size_t MAX_REASONABLE_SIZE = 1ULL << 31;
std::ifstream binary_;
uint64_t base_address_;
uint64_t memory_size_;
std::vector<uint8_t> memory_;
std::string hex_to_bytes( std::string hex );
void map_sections( );
};

42
utils.cpp Normal file
View File

@@ -0,0 +1,42 @@
#include "utils.hpp"
#include <string>
#include <Windows.h>
bool utils::DevicePathToDosPath(const char *devicePath, char *dosPath, size_t dosPathSize)
{
char drive[3] = "A:";
char driveLetter[4];
char deviceName[MAX_PATH];
char path[MAX_PATH];
for (char letter = 'A'; letter <= 'Z'; ++letter)
{
drive[0] = letter;
if (QueryDosDeviceA(drive, deviceName, MAX_PATH))
{
size_t len = strlen(deviceName);
if (len < MAX_PATH && _strnicmp(devicePath, deviceName, len) == 0)
{
snprintf(dosPath, dosPathSize, "%c:%s", letter, devicePath + len);
return TRUE;
}
}
}
return FALSE;
}
void utils::swap(const char **a, const char **b)
{
const char *temp = *a;
*a = *b;
*b = temp;
}
void utils::shuffle(const char **arr, size_t n)
{
for (size_t i = n - 1; i > 0; --i)
{
size_t j = rand() % (i + 1);
swap(&arr[i], &arr[j]);
}
}

9
utils.hpp Normal file
View File

@@ -0,0 +1,9 @@
#pragma once
#include <cstdint>
namespace utils
{
bool DevicePathToDosPath( const char *devicePath, char *dosPath, size_t dosPathSize );
void swap( const char** a, const char** b );
void shuffle( const char** arr, size_t n );
}