From 5af5b9fd3240911289d922aa16fae217628a6201 Mon Sep 17 00:00:00 2001 From: weak1337 <57501119+weak1337@users.noreply.github.com> Date: Tue, 18 Jan 2022 23:02:53 +0100 Subject: [PATCH] Add files via upload --- BattleyePresentCheck.sln | 31 +++ .../BattleyePresentCheck.vcxproj | 153 ++++++++++++++ .../BattleyePresentCheck.vcxproj.filters | 30 +++ .../BattleyePresentCheck.vcxproj.user | 4 + BattleyePresentCheck/main.cpp | 200 ++++++++++++++++++ BattleyePresentCheck/utils.cpp | 44 ++++ BattleyePresentCheck/utils.h | 10 + 7 files changed, 472 insertions(+) create mode 100644 BattleyePresentCheck.sln create mode 100644 BattleyePresentCheck/BattleyePresentCheck.vcxproj create mode 100644 BattleyePresentCheck/BattleyePresentCheck.vcxproj.filters create mode 100644 BattleyePresentCheck/BattleyePresentCheck.vcxproj.user create mode 100644 BattleyePresentCheck/main.cpp create mode 100644 BattleyePresentCheck/utils.cpp create mode 100644 BattleyePresentCheck/utils.h diff --git a/BattleyePresentCheck.sln b/BattleyePresentCheck.sln new file mode 100644 index 0000000..5aba264 --- /dev/null +++ b/BattleyePresentCheck.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BattleyePresentCheck", "BattleyePresentCheck\BattleyePresentCheck.vcxproj", "{0F058B8C-C17E-4F73-868B-F3262614F584}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0F058B8C-C17E-4F73-868B-F3262614F584}.Debug|x64.ActiveCfg = Debug|x64 + {0F058B8C-C17E-4F73-868B-F3262614F584}.Debug|x64.Build.0 = Debug|x64 + {0F058B8C-C17E-4F73-868B-F3262614F584}.Debug|x86.ActiveCfg = Debug|Win32 + {0F058B8C-C17E-4F73-868B-F3262614F584}.Debug|x86.Build.0 = Debug|Win32 + {0F058B8C-C17E-4F73-868B-F3262614F584}.Release|x64.ActiveCfg = Release|x64 + {0F058B8C-C17E-4F73-868B-F3262614F584}.Release|x64.Build.0 = Release|x64 + {0F058B8C-C17E-4F73-868B-F3262614F584}.Release|x86.ActiveCfg = Release|Win32 + {0F058B8C-C17E-4F73-868B-F3262614F584}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C706EC4F-E9D5-44D3-94CF-0AB19A3F744F} + EndGlobalSection +EndGlobal diff --git a/BattleyePresentCheck/BattleyePresentCheck.vcxproj b/BattleyePresentCheck/BattleyePresentCheck.vcxproj new file mode 100644 index 0000000..7b68ed8 --- /dev/null +++ b/BattleyePresentCheck/BattleyePresentCheck.vcxproj @@ -0,0 +1,153 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {0f058b8c-c17e-4f73-868b-f3262614f584} + BattleyePresentCheck + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreaded + + + Console + true + true + true + ntdll.lib;%(AdditionalDependencies) + + + + + + + + + + + + + \ No newline at end of file diff --git a/BattleyePresentCheck/BattleyePresentCheck.vcxproj.filters b/BattleyePresentCheck/BattleyePresentCheck.vcxproj.filters new file mode 100644 index 0000000..b319614 --- /dev/null +++ b/BattleyePresentCheck/BattleyePresentCheck.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Quelldateien + + + Headerdateien + + + + + Headerdateien + + + \ No newline at end of file diff --git a/BattleyePresentCheck/BattleyePresentCheck.vcxproj.user b/BattleyePresentCheck/BattleyePresentCheck.vcxproj.user new file mode 100644 index 0000000..0f14913 --- /dev/null +++ b/BattleyePresentCheck/BattleyePresentCheck.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/BattleyePresentCheck/main.cpp b/BattleyePresentCheck/main.cpp new file mode 100644 index 0000000..8075c46 --- /dev/null +++ b/BattleyePresentCheck/main.cpp @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#include +#include +#include "utils.h" + + +typedef HRESULT(__stdcall* D3D11PresentHook) (IDXGISwapChain* This, UINT SyncInterval, UINT Flags); +volatile static D3D11PresentHook oPresent = NULL; +uintptr_t** present_pointer; +IDXGISwapChain* globalchain; +extern "C" HRESULT __stdcall hookD3D11Present(IDXGISwapChain * This, UINT SyncInterval, UINT Flags) +{ + printf("[>] Handler called! Saving swapchain\n"); + globalchain = This; + *present_pointer = (uintptr_t*)oPresent; + return oPresent(This, SyncInterval, Flags); +} + + +std::unordered_map>modules{ + { "gameoverlayrenderer64.dll", std::tuple("33 F6 83 E5 F7 44 8B C5 8B D6 49 8B CE FF 15", 15) }, + { "DiscordHook64.dll", std::tuple("48 89 D9 89 FA 41 89 F0 FF 15", 10) }, + { "overlay64.dll", std::tuple("48 8B 5C 24 40 44 8B 44 24 30 8B 54 24 38 48 8B CB FF 15", 19) }, + { "DiscordHook64.dll", std::tuple("44 8B C7 8B D6 48 8B CB FF 15", 10) } +}; + +bool func_anomaly(uintptr_t& present) { + bool found_anomaly = false; + + while (true) { + + + while (true) { + while (*(BYTE*)present == 0xE9) { + if (*(DWORD*)(present + 5) == 0xCCCCCCCC) + found_anomaly = true; + present += *(signed int*)(present + 1) + 5; + } + if (*(WORD*)present != 0x25FF) + break; + present = *(uintptr_t*)(present + 6); + } + + if (*(WORD*)present != 0xB848 || *((WORD*)present + 5) != 0xE0FF) + break; + present = *(uintptr_t*)(present + 2); + found_anomaly = true; + } + return found_anomaly; +} + +bool find_memory_anomaly(uintptr_t present) { + bool found_anomaly = false; + MEMORY_BASIC_INFORMATION mbi = { 0 }; + MEMORY_BASIC_INFORMATION mbi2 = { 0 }; + NTSTATUS v27 = NtQueryVirtualMemory((HANDLE) - 1, (LPVOID)present, MemoryBasicInformation, &mbi, 48i64, 0) < 0; + NTSTATUS v7 = v27; + NTSTATUS v28; + bool v31 = v27 + || mbi.State != MEM_COMMIT + || mbi.Type != MEM_IMAGE + && (mbi.Type != MEM_PRIVATE + || mbi.State != MEM_FREE + || *((uintptr_t*)present + 20) != 0xEBFFFFFF41058D48ui64 + || (present = *((uintptr_t*)present - 3), + v28 = NtQueryVirtualMemory((HANDLE) - 1i64, (LPVOID)present, MemoryBasicInformation, &mbi2, 48i64, 0) < 0, + v7 = v28) + || mbi2.State != MEM_COMMIT + || mbi2.Type != MEM_IMAGE) + || mbi.Protect != 16 && mbi.Protect != 32 && mbi.Protect != 64 && mbi.Protect != 128 + || *(uintptr_t*)present == 0x74894808245C8948i64 + && (*((uintptr_t*)present + 1) == 0x4140EC8348571024i64 + || *((uintptr_t*)present + 1) == 0x5518247C89481024i64) + || *(uintptr_t*)present == 0x57565520245C8948i64 + || *(uintptr_t*)present == 0x4157551824748948i64 + || *(uintptr_t*)present == 0x8D48564157565540ui64 + || *(DWORD*)present == 1220840264 && *((WORD*)present + 2) == 22665 + || *(uintptr_t*)present == 0x5741564157565340i64 + || *(uintptr_t*)present == 0x5741564155C48B48i64 + || *(uintptr_t*)present == 0x4156415441575540i64; + found_anomaly = v31; + return found_anomaly; +} + +int main() { + bool reported = false; + int idx = 0; + for (auto pair : modules) { + if (uintptr_t base = (uintptr_t)GetModuleHandleA(pair.first.c_str())) { + present_pointer = 0; + PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)base; + PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)(base + dos->e_lfanew); + DWORD code_base = nt->OptionalHeader.BaseOfCode; + DWORD code_size = nt->OptionalHeader.SizeOfCode; + uintptr_t code_start = code_base + base; + + uintptr_t sig_base = utils::scanpattern(code_start, code_size, std::get<0>(pair.second).c_str()); + if (!sig_base) + continue; + printf("[>] Sig at %p\n", sig_base); + if (idx == 0) { //gameoverlayrenderer64.dll + uintptr_t jmp_dst = sig_base - 0x45; + if (*(BYTE*)jmp_dst == 0xE8 && + (jmp_dst += *(signed int*)(jmp_dst + 1) + 5, *(DWORD*)jmp_dst != 0x83485340)) { + present_pointer = (uintptr_t**)&jmp_dst; + } + + } + + + else if (idx == 1) { //DiscordHook64.dll + uintptr_t jmp_dst = sig_base - 0x13; + if (*(BYTE*)jmp_dst == 0xE8 && + (jmp_dst += *(signed int*)(jmp_dst + 1) + 5, *(BYTE*)jmp_dst == 0xE9) && + (jmp_dst += *(signed int*)(jmp_dst + 1) + 15, *(BYTE*)jmp_dst == 0xE9) && + (jmp_dst += *(signed int*)(jmp_dst + 1) + 5, *(BYTE*)jmp_dst != 0x56535540) + ) { + present_pointer = (uintptr_t**)&jmp_dst; + } + + else { + jmp_dst = sig_base - 0xA6; + if (*(BYTE*)jmp_dst == 0xE9 && + (jmp_dst += *(signed int*)(jmp_dst + 1) + 5, *(BYTE*)jmp_dst == 0xE9) && + (jmp_dst += *(signed int*)(jmp_dst + 1) + 6, **(uintptr_t**)jmp_dst == 0x2454891824448944) + ) { + present_pointer = (uintptr_t**)jmp_dst; + } + } + } + + if(!present_pointer) { //overlay64.dll or DiscordHook64.dll + present_pointer = (uintptr_t**)(sig_base + std::get<1>(pair.second)+ *(DWORD*)(sig_base + std::get<1>(pair.second)) + 4); + } + if (present_pointer && *present_pointer) { + + static MEMORY_BASIC_INFORMATION mbi = { 0 }; + NTSTATUS status = NtQueryVirtualMemory((HANDLE) - 1, *present_pointer, MemoryBasicInformation, (PVOID) & mbi, sizeof(mbi), 0); + if (status || mbi.State != MEM_COMMIT || mbi.Type != MEM_PRIVATE || mbi.Protect != PAGE_EXECUTE_READWRITE || *(DWORD*)(*present_pointer) == 0x50C03148) { //xor rax, rax push rax + printf("[!!!] Present is invalid memory! %p %p\n", status, &mbi); + reported = true; + + } + + printf("[>] Present pointer in %s at %p\n", pair.first.c_str(), present_pointer); + + oPresent = (D3D11PresentHook)*present_pointer; + *present_pointer = (uintptr_t*)hookD3D11Present; + + Sleep(1000); //Sleep and hope that present got called once + printf("[>] Found SwapChain at %p\n", globalchain); + static MEMORY_BASIC_INFORMATION mbi_globalchain = { 0 }; + NTSTATUS globalchainstatus = NtQueryVirtualMemory((HANDLE)-1, globalchain, MemoryBasicInformation, (PVOID)&mbi_globalchain, sizeof(mbi_globalchain), 0); + uintptr_t present_from_vtable = *(uintptr_t*)(*(uintptr_t*)(globalchain)+0x40); + if (globalchainstatus || func_anomaly(present_from_vtable)) { + reported = true; + printf("[!!!] Anomaly at: %p\n", present_from_vtable); + } + + else + { + printf("[>] No anomalys found jump chain ends at %p\n", present_from_vtable); + printf("[>] Verifying memory!\n"); + if (find_memory_anomaly(present_from_vtable)) { + printf("[!!!] Memory anomaly at destination!\n"); + reported = true; + } + + } + } + } + idx++; + } + if (reported) { + printf("[!!!] You received reports!\n"); + } + else { + printf("[>] No reports! You're good to go\n"); + } +} + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module + DWORD fdwReason, // reason for calling function + LPVOID lpReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: { + AllocConsole(); + FILE* f; + freopen_s(&f, "CONOUT$", "w", stdout); + main(); + break; + } + + } + return TRUE; +} \ No newline at end of file diff --git a/BattleyePresentCheck/utils.cpp b/BattleyePresentCheck/utils.cpp new file mode 100644 index 0000000..a07b67d --- /dev/null +++ b/BattleyePresentCheck/utils.cpp @@ -0,0 +1,44 @@ +#include "utils.h" + +uintptr_t utils::scanpattern(uintptr_t base, int size, const char* signature) +{ + static auto patternToByte = [](const char* pattern) + { + auto bytes = std::vector{}; + const auto start = const_cast(pattern); + const auto end = const_cast(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 patternBytes = patternToByte(signature); + const auto scanBytes = reinterpret_cast(base); + + const auto s = patternBytes.size(); + const auto d = patternBytes.data(); + + for (auto i = 0ul; i < size - 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 reinterpret_cast(&scanBytes[i]); } + } + return NULL; +} diff --git a/BattleyePresentCheck/utils.h b/BattleyePresentCheck/utils.h new file mode 100644 index 0000000..761b399 --- /dev/null +++ b/BattleyePresentCheck/utils.h @@ -0,0 +1,10 @@ +#pragma once +#include +#include +namespace utils { + uintptr_t scanpattern(uintptr_t base, int size, const char* signature); +} +using MEMORY_INFORMATION_CLASS = enum _MEMORY_INFORMATION_CLASS { + MemoryBasicInformation +}; +extern "C" NTSTATUS DECLSPEC_IMPORT NTAPI NtQueryVirtualMemory(HANDLE, PVOID, MEMORY_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T); \ No newline at end of file