diff --git a/variant/first_iteration_2021.cpp b/variant/first_iteration_2021.cpp new file mode 100644 index 0000000..3c7cbda --- /dev/null +++ b/variant/first_iteration_2021.cpp @@ -0,0 +1,355 @@ +/* +Rop using WNDPROC hook + */ + +#include +#include +#include +#include +#pragma comment(lib, "ntdll.lib") + +typedef struct _UNICODE_STRING +{ + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING; + +typedef enum _MEMORY_INFORMATION_CLASS +{ + MemoryBasicInformation, // q: MEMORY_BASIC_INFORMATION + MemoryWorkingSetInformation, // q: MEMORY_WORKING_SET_INFORMATION + MemoryMappedFilenameInformation, // q: UNICODE_STRING +} MEMORY_INFORMATION_CLASS; + +typedef struct _MEMORY_SECTION_NAME +{ + UNICODE_STRING SectionFileName; + WCHAR NameBuffer[ANYSIZE_ARRAY]; +} MEMORY_SECTION_NAME, * PMEMORY_SECTION_NAME; + +extern "C" NTSTATUS NTAPI NtQueryVirtualMemory( + HANDLE ProcessHandle, + PVOID BaseAddress, + MEMORY_INFORMATION_CLASS MemoryInformationClass, + PVOID MemoryInformation, + SIZE_T MemoryInformationLength, + PSIZE_T ReturnLength); + + +class TargetProcess { +private: + HWND t_hwnd; + DWORD t_pid; + DWORD t_tid; +public: + TargetProcess() { + t_hwnd = FindWindowW(L"Respawn001", L"Apex Legends"); + if (!t_hwnd) + return; + t_tid = GetWindowThreadProcessId(t_hwnd, &t_pid); + return; + } + + bool IsReady() { + return (t_hwnd && t_pid && t_tid); + } + + auto get_pid() const { + return t_pid; + } + auto get_tid() const { + return t_tid; + } + auto get_hwnd() const { + return t_hwnd; + } + +}; + + +class ExploitMem { +public: + inline static uintptr_t local_shared_memory = 0; + inline static uintptr_t remote_shared_memory = 0; + inline static char shared_count = 0; + + static void Init() { + char path[MAX_PATH]; + SHGetFolderPathA(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, path); + if (*path != 0) + ExploitMem::local_shared_memory = 0; + } + + static bool find_local_memory() { + MEMORY_BASIC_INFORMATION mbi{}; + char* pAddress = nullptr; + + while (true) { + if (VirtualQuery(pAddress, &mbi, sizeof(mbi)) == 0) { + break; + } + + if (isValidRegion(mbi)) { + PSAPI_WORKING_SET_EX_INFORMATION wsInfo{}; + wsInfo.VirtualAddress = mbi.BaseAddress; + QueryWorkingSetEx(GetCurrentProcess(), &wsInfo, sizeof(wsInfo)); + shared_count = wsInfo.VirtualAttributes.ShareCount; + local_shared_memory = (uintptr_t)mbi.BaseAddress; + return true; + } + + pAddress += mbi.RegionSize; + } + return false; + } + + static bool find_remote_memory(DWORD pid) { + HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pid); + if (!hProcess) { + return false; + } + + MEMORY_BASIC_INFORMATION mbi{}; + char* pAddress = nullptr; + + while (true) { + SIZE_T return_len{}; + NtQueryVirtualMemory(hProcess, pAddress, MemoryBasicInformation, &mbi, sizeof(mbi), &return_len); + if (return_len == 0) { + break; + } + + if (isValidRegion(mbi)) { + PSAPI_WORKING_SET_EX_INFORMATION wsInfo{}; + wsInfo.VirtualAddress = mbi.BaseAddress; + QueryWorkingSetEx(hProcess, &wsInfo, sizeof(wsInfo)); + if (shared_count == wsInfo.VirtualAttributes.ShareCount) { + remote_shared_memory = (uintptr_t)pAddress; + CloseHandle(hProcess); + return true; + } + } + + pAddress += mbi.RegionSize; + } + + CloseHandle(hProcess); + return false; + } + +private: + static bool isValidRegion(const MEMORY_BASIC_INFORMATION& mbi) { + return mbi.State == MEM_COMMIT && mbi.Protect == PAGE_READWRITE && + mbi.RegionSize == 4096 && mbi.Type == MEM_MAPPED; + } +}; + + +class Exploit { +private: + void* gadget_pop_rcx_ret{}; + void* gadget_pop_rdx_ret{}; + void* gadget_pop_rax_ret{}; + void* gadget_mov_ptr_rcx_rdx_ret{}; + void* gadget_mov_ptr_rdx_rcx_ret{}; + void* gadget_deref_rcx_rax{}; + void* gadget_align_stack{}; + void* gadget_swap_stack{}; + void* gadget_write_rax_to_rcx_ptr{}; + void* gadget_add_rbp_to_rax{}; + void* gadget_push_rax_pop_rsp{}; + + unsigned long long sh_ptr = 0; + + static void* FindSignature(HMODULE dll, const unsigned char* buffer, size_t size) { + if (dll == nullptr || buffer == nullptr || size == 0) { + return nullptr; + } + + MODULEINFO modInfo = { 0 }; + if (!GetModuleInformation(GetCurrentProcess(), dll, &modInfo, sizeof(MODULEINFO))) { + return nullptr; + } + + auto base = static_cast(modInfo.lpBaseOfDll); + auto maxAddress = base + modInfo.SizeOfImage; + MEMORY_BASIC_INFORMATION mbi; + + while (base < maxAddress && VirtualQuery(base, &mbi, sizeof(mbi))) { + if ((mbi.State == MEM_COMMIT) && (mbi.Protect & PAGE_EXECUTE_READ)) { + auto checkLimit = min(static_cast(mbi.BaseAddress) + mbi.RegionSize, maxAddress); + auto end = checkLimit - size; + + for (auto current = static_cast(mbi.BaseAddress); current <= end; ++current) { + if (memcmp(current, buffer, size) == 0) { + return current; + } + } + } + + base = static_cast(mbi.BaseAddress) + mbi.RegionSize; + } + + return nullptr; + } + + void* FindGadget(const char* dllName, const unsigned char* signature, size_t size) { + HMODULE dll = LoadLibraryA(dllName); + if (!dll) + return 0; + return FindSignature(dll, signature, size); + } + +public: + Exploit() { + // Gadgets signatures + unsigned char sig_pop_rcx_ret[] = "\x59\xC3"; + unsigned char sig_pop_rdx_ret[] = "\x5A\xC3"; + unsigned char sig_pop_rax_ret[] = "\x58\xC3"; + unsigned char sig_mov_ptr_rcx_rdx_ret[] = "\x48\x89\x11\xC3"; + unsigned char sig_mov_ptr_rdx_rcx_ret[] = "\x48\x89\x0A\xC3"; + unsigned char sig_deref_rcx_rax[] = "\x48\x8B\x01\xC3"; + unsigned char sig_write_rax_to_rcx_ptr[] = "\x48\x89\x01\xC3"; + unsigned char signature_gadget_align_stack[] = "\x48\x81\xC4\xE8\x00\x00\x00\xC3"; + unsigned char signature_gadget_swap_stack[] = "\x5C\xC3"; + unsigned char sig_add_rbp_to_rax[] = "\x48\x01\xE8\xC3"; + unsigned char sig_push_rax_pop_rsp[] = "\x50\x5c\xC3"; + + // Search order: ntdll, kernel32, user32 + const char* dlls[] = { "ntdll.dll", "kernel32.dll", "user32.dll", "ws2_32.dll", "shell32.dll", "dxgi.dll", "crypt32.dll", "advapi32.dll", "ole32.dll", "secur32.dll", "psapi.dll", "rasadhlp.dll", "msctf.dll", "ntasn1.dll", "SHCore.dll", "avifil32.dll", "cryptsp.dll", "wbemsvc.dll", "winmmbase.dll", "MpOAV.dll", "combase.dll", "dwmapi.dll", "powrprof.dll", "ncrypt.dll", "MMDevAPI.dll", "msvcp_win.dll", "propsys.dll", "CoreMessaging.dll", "cryptbase.dll", "IPHLPAPI.DLL", "drvstore.dll", "gdi32full.dll", "version.dll", "midimap.dll", "coloradapterclient.dll", "wininet.dll", "Windows.UI.dll", "cryptnet.dll", "wbemcomn.dll", "bcrypt.dll", "mscms.dll", "schannel.dll", "userenv.dll", "amsi.dll", "rsaenh.dll", "ucrtbase.dll", "msvfw32.dll", "d3d11.dll", "devobj.dll", "dhcpcsvc6.dll", "wintrust.dll", "xinput1_3.dll", "mswsock.dll", "wdmaud.drv", "sxs.dll", "bcryptprimitives.dll", "ncryptsslp.dll", "gdi32.dll", "normaliz.dll", "clbcatq.dll", "fastprox.dll", "profapi.dll", "win32u.dll", "avrt.dll", "NapiNSP.dll", "WinTypes.dll", "pnrpnsp.dll", "CoreUIComponents.dll", "D3DCompiler_43.dll", "umpdc.dll", "XAudio2_9.dll", "KernelBase.dll", "ntmarta.dll", "sspicli.dll", "kernel.appcore.dll", "steamclient64.dll", "dhcpcsvc.dll", "ksuser.dll", "InputHost.dll", "msvcrt.dll", "imm32.dll", "AudioSes.dll", "dnsapi.dll", "wshbth.dll", "cfgmgr32.dll", "mskeyprotect.dll", "msacm32.dll", "twinapi.appcore.dll", "wbemprox.dll", "oleaut32.dll", "msasn1.dll", "winrnr.dll", "hid.dll", "setupapi.dll", "dsound.dll", "windows.storage.dll", "dbghelp.dll", "WindowManagementAPI.dll", "vstdlib_s64.dll", "nlaapi.dll", "ResourcePolicyClient.dll", "comctl32.dll", "msacm32.drv", "dbgcore.dll", "imagehlp.dll", "rpcrt4.dll", "FWPUCLNT.DLL", "DXCore.dll", "uxtheme.dll", "TextInputFramework.dll", "winmm.dll", "Windows.Internal.Graphics.Display.DisplayColorManagement.dll", "Wldap32.dll", "shlwapi.dll", "wldp.dll", "sechost.dll", "nsi.dll" }; + for (const char* dll : dlls) { + if (!gadget_pop_rcx_ret) + gadget_pop_rcx_ret = FindGadget(dll, sig_pop_rcx_ret, sizeof(sig_pop_rcx_ret) - 1); + if (!gadget_pop_rax_ret) + gadget_pop_rax_ret = FindGadget(dll, sig_pop_rax_ret, sizeof(sig_pop_rax_ret) - 1); + + if (!gadget_pop_rdx_ret) + gadget_pop_rdx_ret = FindGadget(dll, sig_pop_rdx_ret, sizeof(sig_pop_rdx_ret) - 1); + if (!gadget_mov_ptr_rcx_rdx_ret) + gadget_mov_ptr_rcx_rdx_ret = FindGadget(dll, sig_mov_ptr_rcx_rdx_ret, sizeof(sig_mov_ptr_rcx_rdx_ret) - 1); + if (!gadget_mov_ptr_rdx_rcx_ret) + gadget_mov_ptr_rdx_rcx_ret = FindGadget(dll, sig_mov_ptr_rdx_rcx_ret, sizeof(sig_mov_ptr_rdx_rcx_ret) - 1); + if (!gadget_deref_rcx_rax) + gadget_deref_rcx_rax = FindGadget(dll, sig_deref_rcx_rax, sizeof(sig_deref_rcx_rax) - 1); + + if (!gadget_write_rax_to_rcx_ptr) + gadget_write_rax_to_rcx_ptr = FindGadget(dll, sig_write_rax_to_rcx_ptr, sizeof(sig_write_rax_to_rcx_ptr) - 1); + if (!gadget_align_stack) + gadget_align_stack = FindGadget(dll, signature_gadget_align_stack, sizeof(signature_gadget_align_stack) - 1); + if (!gadget_swap_stack) + gadget_swap_stack = FindGadget(dll, signature_gadget_swap_stack, sizeof(signature_gadget_swap_stack) - 1); + if (!gadget_add_rbp_to_rax) + gadget_add_rbp_to_rax = FindGadget(dll, sig_add_rbp_to_rax, sizeof(sig_add_rbp_to_rax) - 1); + + if (!gadget_push_rax_pop_rsp) + gadget_push_rax_pop_rsp = FindGadget(dll, sig_push_rax_pop_rsp, sizeof(sig_push_rax_pop_rsp) - 1); + + if (gadget_pop_rcx_ret && gadget_pop_rdx_ret && gadget_pop_rax_ret && gadget_mov_ptr_rcx_rdx_ret && gadget_mov_ptr_rdx_rcx_ret && + gadget_align_stack && gadget_swap_stack && gadget_deref_rcx_rax && gadget_write_rax_to_rcx_ptr && + gadget_add_rbp_to_rax && gadget_push_rax_pop_rsp) + break; // Exit if all gadgets are found + } + } + + bool IsReady() { + return (gadget_pop_rcx_ret && gadget_pop_rdx_ret && gadget_pop_rax_ret && gadget_mov_ptr_rcx_rdx_ret && gadget_mov_ptr_rdx_rcx_ret && + gadget_align_stack && gadget_swap_stack && gadget_deref_rcx_rax && gadget_write_rax_to_rcx_ptr && + gadget_add_rbp_to_rax && gadget_push_rax_pop_rsp); + } + + void set_rax(unsigned long long val) { + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = (unsigned long long)gadget_pop_rax_ret; + sh_ptr += sizeof(void*); + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = val; + sh_ptr += sizeof(void*); + } + + void set_rcx(unsigned long long val) { + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = (unsigned long long)gadget_pop_rcx_ret; + sh_ptr += sizeof(void*); + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = val; + sh_ptr += sizeof(void*); + } + + void set_rdx(unsigned long long val) { + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = (unsigned long long)gadget_pop_rdx_ret; + sh_ptr += sizeof(void*); + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = val; + sh_ptr += sizeof(void*); + } + + void fix_stack_and_return() { + set_rax(-0x80); + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = (unsigned long long)gadget_add_rbp_to_rax; + sh_ptr += sizeof(void*); + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = (unsigned long long)gadget_push_rax_pop_rsp; + sh_ptr += sizeof(void*); + } + + unsigned long long read_memory(TargetProcess& target, unsigned long long ptr_to_read) { +#define STACK_OFFSET 0x800 +#define READ_MEM 0x800 - sizeof(void*) + sh_ptr = STACK_OFFSET; + + set_rcx(ptr_to_read); + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = (unsigned long long)gadget_deref_rcx_rax; + sh_ptr += sizeof(void*); + set_rcx(ExploitMem::remote_shared_memory + READ_MEM); + *(unsigned long long*)(ExploitMem::local_shared_memory + sh_ptr) = (unsigned long long)gadget_write_rax_to_rcx_ptr; + sh_ptr += sizeof(void*); + fix_stack_and_return(); + + + ShowWindow(target.get_hwnd(), 0); + auto hhook = SetWindowsHookExA(WH_CALLWNDPROC, (HOOKPROC)gadget_align_stack, LoadLibraryA("ws2_32.dll"), target.get_tid()); + SendMessageA(target.get_hwnd(), WM_MOUSEACTIVATE, ExploitMem::remote_shared_memory + STACK_OFFSET, (LPARAM)gadget_swap_stack); + UnhookWindowsHookEx(hhook); + UnhookWindowsHookEx(hhook); + ShowWindow(target.get_hwnd(), 1); + + printf("Read : %llx\n", *(unsigned long long*)(ExploitMem::local_shared_memory + READ_MEM)); + + return 0; + } +}; + +int main() { + + + + + + auto target = TargetProcess(); + + + + auto exploit = Exploit(); + + if (!exploit.IsReady()) { + printf("Fail\n"); + return -1; + } + + + ExploitMem::Init(); + + if (!ExploitMem::find_local_memory()) { + printf("Didn't work\n"); + return -1; + } + + + if (!target.IsReady()) { + printf("Apex not open\n"); + return -1; + } + + if (!ExploitMem::find_remote_memory(target.get_pid())) { + printf("No Remote\n"); + } + + memset((void*)ExploitMem::local_shared_memory, 0, 0x1000); + exploit.read_memory(target, 0x7ffe0000); + return 0; +}