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