diff --git a/Cobalt/Cobalt.vcxproj b/Cobalt/Cobalt.vcxproj
index 765507c..500f3f8 100644
--- a/Cobalt/Cobalt.vcxproj
+++ b/Cobalt/Cobalt.vcxproj
@@ -113,11 +113,14 @@
Use
pch.h
stdcpplatest
+ ../vendor
Windows
true
false
+ ../vendor
+ MinHook/minhook.x64.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)
@@ -131,6 +134,7 @@
NotUsing
pch.h
stdcpplatest
+ ../vendor
Windows
@@ -138,6 +142,8 @@
true
true
false
+ ../vendor
+ MinHook/minhook.x64.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)
diff --git a/Cobalt/curlhook.h b/Cobalt/curlhook.h
index 6140e58..c1fe52b 100644
--- a/Cobalt/curlhook.h
+++ b/Cobalt/curlhook.h
@@ -9,8 +9,6 @@
#include "../vendor/cURL/curl.h"
#include "url.h"
-// #define HYBRID_ENABLED
-
inline CURLcode(*CurlSetOpt)(struct Curl_easy*, CURLoption, va_list) = nullptr;
inline CURLcode(*CurlEasySetOpt)(struct Curl_easy*, CURLoption, ...) = nullptr;
@@ -55,10 +53,12 @@ inline CURLcode CurlEasySetOptDetour(struct Curl_easy* data, CURLoption tag, ...
Uri uri = Uri::Parse(url);
- // std::cout << "URL: " << uri.Host << uri.Path << '\n';
+ std::cout << "URL: " << uri.Host << uri.Path << '\n';
-#ifdef URL_HOST
+#if defined(URL_HOST) && defined(URL_PROTOCOL) && defined(URL_PORT)
if (uri.Host.ends_with(XOR("ol.epicgames.com"))
+ || uri.Host.ends_with(XOR("epicgames.dev")) // wooo eos
+ || uri.Host.ends_with(XOR("ol.epicgames.net")) // i forgor what endpoint this was for
|| uri.Host.ends_with(XOR(".akamaized.net"))
|| uri.Host.ends_with(XOR("on.epicgames.com"))
|| uri.Host.ends_with(XOR("game-social.epicgames.com"))
@@ -71,25 +71,23 @@ inline CURLcode CurlEasySetOptDetour(struct Curl_easy* data, CURLoption tag, ...
}
else if (CobaltUsage == ECobaltUsage::Hybrid)
{
- if (CobaltUsage == ECobaltUsage::Hybrid) {
- if (uri.Path.contains("/fortnite/api/v2/versioncheck/")) {
- url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
- }
- else if (uri.Path.contains("/fortnite/api/game/v2/profile")) {
- url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
- }
- else if (uri.Path.contains("/content/api/pages/fortnite-game")) {
- url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
- }
- else if (uri.Path.contains("/affiliate/api/public/affiliates/slug")) {
- url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
- }
- else if (uri.Path.contains("/socialban/api/public/v1")) {
- url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
- }
- else if (uri.Path.contains("/fortnite/api/cloudstorage/system")) {
- url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
- }
+ if (uri.Path.contains("/fortnite/api/v2/versioncheck/")) {
+ url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
+ }
+ else if (uri.Path.contains("/fortnite/api/game/v2/profile")) {
+ url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
+ }
+ else if (uri.Path.contains("/content/api/pages/fortnite-game")) {
+ url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
+ }
+ else if (uri.Path.contains("/affiliate/api/public/affiliates/slug")) {
+ url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
+ }
+ else if (uri.Path.contains("/socialban/api/public/v1")) {
+ url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
+ }
+ else if (uri.Path.contains("/fortnite/api/cloudstorage/system")) {
+ url = Uri::CreateUri(URL_PROTOCOL, URL_HOST, URL_PORT, uri.Path, uri.QueryString);
}
}
}
diff --git a/Cobalt/dllmain.cpp b/Cobalt/dllmain.cpp
index 8036ba6..913b8bd 100644
--- a/Cobalt/dllmain.cpp
+++ b/Cobalt/dllmain.cpp
@@ -3,6 +3,7 @@
#include
#include "curlhook.h"
#include "exithook.h"
+#include
#define DetoursEasy(address, hook) \
DetourTransactionBegin(); \
@@ -10,9 +11,44 @@
DetourAttach(reinterpret_cast(&address), hook); \
DetourTransactionCommit();
+void returnNone() { return; }
+
auto FindPushWidget()
{
- return sigscan("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 30 48 8B E9 49 8B D9 48 8D 0D ? ? ? ? 49 8B F8 48 8B F2 E8 ? ? ? ? 4C 8B CF 48 89 5C 24 ? 4C 8B C6 48 8B D5 48 8B 48 78");
+ // OnlinePresence call
+ auto pattern = sigscan("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 30 48 8B E9 49 8B D9 48 8D 0D ? ? ? ? 49 8B F8 48 8B F2 E8 ? ? ? ? 4C 8B CF 48 89 5C 24 ? 4C 8B C6 48 8B D5 48 8B 48 78");
+
+ if (!pattern)
+ pattern = sigscan("48 8B C4 4C 89 40 18 48 89 50 10 48 89 48 08 55 53 56 57 41 54 41 55 41 56 41 57 48 8D 68 B8 48 81 EC ? ? ? ? 65 48 8B 04 25"); // 26.00+ or sum
+
+ return pattern;
+}
+
+void Hook(void* Target, void* Detour)
+{
+#ifdef USE_MINHOOK
+ MH_CreateHook(Target, Detour, nullptr);
+ MH_EnableHook(Target);
+#else
+ Memcury::VEHHook::AddHook(Target, Detour);
+#endif
+}
+
+bool FixMemoryLeak() // 8.51
+{
+ auto memoryleak = sigscan("4C 8B DC 55 57 41 56 49 8D AB ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 48 8B 01 41 B6");
+
+ if (!memoryleak)
+ {
+ return false;
+ }
+
+ Hook((void*)memoryleak, returnNone);
+ return true;
+}
+
+void InitializeEOSCurlHook()
+{
}
bool InitializeCurlHook()
@@ -59,7 +95,7 @@ bool InitializeCurlHook()
{
// TODO find a better way to "bypass" UAC (aka switch off VEH hooks)
- Memcury::VEHHook::AddHook(CurlEasySetOpt, CurlEasySetOptDetour);
+ Hook(CurlEasySetOpt, CurlEasySetOptDetour);
}
return true;
@@ -68,7 +104,38 @@ bool InitializeCurlHook()
void InitializeExitHook()
{
if (!FindPushWidget())
+ {
+ std::cout << "Failed to find PushWidget (This may be fine)!\n";
+
+ /*
+ auto RequestExitWithStatusAddr = sigscan("40 53 48 83 EC 40 80 3D ? ? ? ? ? 0F B6 D9 72 3A 48 8B 05"); // S9
+
+ std::cout << "RequestExitWithStatusAddr: " << RequestExitWithStatusAddr << '\n';
+
+ RequestExitWithStatus = decltype(RequestExitWithStatus)(RequestExitWithStatusAddr);
+ Memcury::VEHHook::AddHook(RequestExitWithStatus, RequestExitWithStatusHook);
+
+ auto UnsafeEnvironmentPopupAddr = sigscan("4C 8B DC 55 49 8D AB ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 49 89 73 E8 33 F6 49 89 7B E0 0F B6 FA"); // S9
+
+ std::cout << "UnsafeEnvironmentPopupAddr: " << UnsafeEnvironmentPopupAddr << '\n';
+
+ UnsafeEnvironmentPopup = decltype(UnsafeEnvironmentPopup)(UnsafeEnvironmentPopupAddr);
+ Memcury::VEHHook::AddHook(UnsafeEnvironmentPopup, UnsafeEnvironmentPopupHook);
+
+ auto RequestExitAddrs = Memcury::Scanner::FindPatterns("40 53 48 83 EC 30 80 3D ? ? ? ? ? 0F B6 D9 72 33 48 8B 05 ? ? ? ? 4C 8D 44 24 ? 48 89 44 24 ? 41 B9 ? ? ? ? 0F"); // S9
+
+ std::cout << "RequestExitAddrs: " << RequestExitAddrs.size() << '\n';
+
+ for (auto RequestExitAddr : RequestExitAddrs)
+ {
+ RequestExit = decltype(RequestExit)(Memcury::Scanner(RequestExitAddr).Get());
+ Memcury::VEHHook::AddHook(RequestExit, RequestExitHook);
+ }
+ */
+
+
return;
+ }
auto UnsafeEnvironmentPopupAddr = sigscan("4C 8B DC 55 49 8D AB ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 49 89 73 F0 49 89 7B E8 48 8B F9 4D 89 63 E0 4D 8B E0 4D 89 6B D8");
@@ -77,11 +144,21 @@ void InitializeExitHook()
UnsafeEnvironmentPopupAddr = sigscan("4C 8B DC 55 49 8D AB ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ?");
}
+ if (!UnsafeEnvironmentPopupAddr)
+ {
+ std::cout << "Failed to find UnsafeEnvironmentPopupAddr (This may be fine)!\n";
+ }
+
auto RequestExitWithStatusAddr = sigscan("48 89 5C 24 ? 57 48 83 EC 40 41 B9 ? ? ? ? 0F B6 F9 44 38 0D ? ? ? ? 0F B6 DA 72 24 89 5C 24 30 48 8D 05 ? ? ? ? 89 7C 24 28 4C 8D 05 ? ? ? ? 33 D2 48 89 44 24 ? 33 C9 E8 ? ? ? ?");
if (!RequestExitWithStatusAddr)
{
- RequestExitWithStatusAddr = sigscan("48 8B C4 48 89 58 18 88 50 10 88 48 08 57 48 83 EC 30");
+ RequestExitWithStatusAddr = sigscan("48 8B C4 48 89 58 18 88 50 10 88 48 08 57 48 83 EC 30"); // wrong on latest but idgaf
+ }
+
+ if (!RequestExitWithStatusAddr)
+ {
+ std::cout << "Failed to find RequestExitWithStatusAddr (This may be fine)!\n";
}
DetoursEasy(UnsafeEnvironmentPopupAddr, UnsafeEnvironmentPopupHook);
@@ -97,7 +174,7 @@ DWORD WINAPI Main(LPVOID)
freopen_s(&fptr, "CONOUT$", "w+", stdout);
#endif SHOW_WINDOWS_CONSOLE
-#ifndef URL_HOST
+#ifndef URL_HOST // todo staticassert?
std::cout << "\n\n\n!!!!!!! URL_HOST IS NOT DEFINED !!!!!!!\n\n\n\n";
#else
std::cout << "Redirecting to " << URL_PROTOCOL << "://" << URL_HOST << ":" << URL_PORT << '\n';
@@ -105,14 +182,19 @@ DWORD WINAPI Main(LPVOID)
std::cout << "Initializing Cobalt (made by Milxnor#3531).\n";
- std::cout << "Credits\n\n";
+ std::cout << "Credits:\n\n";
std::cout << "Memcury - https://github.com/kem0x/Memcury\n";
- std::cout << "Neonite++ for the signatures and curl hook - https://github.com/PeQuLeaks/NeonitePP-Fixed/tree/1.4\n\n";
+ std::cout << "Neonite++ for most of the signatures and curl hook - https://github.com/PeQuLeaks/NeonitePP-Fixed/tree/1.4\n\n";
+#ifdef USE_MINHOOK
+ MH_Initialize();
+#else
Memcury::VEHHook::Init();
+#endif
bool curlResult = InitializeCurlHook();
+ InitializeEOSCurlHook();
InitializeExitHook();
bool result = curlResult;
@@ -126,6 +208,19 @@ DWORD WINAPI Main(LPVOID)
MessageBoxA(0, "Failed to initialize!", "Cobalt", MB_ICONERROR);
}
+#if 0
+ Sleep(3000);
+
+ if (!FixMemoryLeak())
+ {
+ std::cout << "Failed to apply memory leak fix (this may be fine)!\n";
+ }
+ else
+ {
+ std::cout << "Applied memory leak fix!\n";
+ }
+#endif
+
return 0;
}
diff --git a/Cobalt/exithook.h b/Cobalt/exithook.h
index 4485dbe..ed68e22 100644
--- a/Cobalt/exithook.h
+++ b/Cobalt/exithook.h
@@ -1,11 +1,19 @@
#pragma once
+#include
+
void (*RequestExitWithStatus)(bool Force, unsigned char Code);
void RequestExitWithStatusHook(bool Force, unsigned char Code)
{
// printf("[VEH] RequestExitWithStatus Call Forced: %i ReturnCode: %u\n", Force, Code);
}
+void (*RequestExit)(int Code);
+void RequestExitHook(int Code)
+{
+ std::cout << "REQUEST EXIT CODE: " << Code << '\n';
+}
+
void (*UnsafeEnvironmentPopup)(wchar_t** unknown1, unsigned __int8 _case, __int64 unknown2, char unknown3);
void UnsafeEnvironmentPopupHook(wchar_t** unknown1, unsigned __int8 _case, __int64 unknown2, char unknown3)
diff --git a/Cobalt/memcury.h b/Cobalt/memcury.h
index 882db5a..eac2b10 100644
--- a/Cobalt/memcury.h
+++ b/Cobalt/memcury.h
@@ -711,6 +711,41 @@ namespace Memcury
return FindPatternEx(handle, pattern, mask, module, module + Memcury::PE::GetNTHeaders()->OptionalHeader.SizeOfImage);
}
+ static std::vector FindPatterns(const char* signature)
+ {
+ const auto sizeOfImage = PE::GetNTHeaders()->OptionalHeader.SizeOfImage;
+ auto patternBytes = ASM::pattern2bytes(signature);
+ const auto scanBytes = reinterpret_cast(PE::GetModuleBase());
+
+ const auto s = patternBytes.size();
+ const auto d = patternBytes.data();
+
+ std::vector addresses;
+
+ 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)
+ {
+ addresses.push_back(reinterpret_cast(&scanBytes[i]));
+ // break;
+ }
+ }
+
+ // MemcuryAssertM(add != 0, "FindPattern return nullptr");
+
+ return addresses;
+ }
+
static auto FindPattern(const char* signature) -> Scanner
{
PE::Address add{ nullptr };
diff --git a/Cobalt/settings.h b/Cobalt/settings.h
index 7dae26e..2fdca58 100644
--- a/Cobalt/settings.h
+++ b/Cobalt/settings.h
@@ -10,6 +10,7 @@ enum class ECobaltUsage
#define URL_PROTOCOL "http"
#define URL_HOST "127.0.0.1"
#define URL_PORT "3551"
+// #define USE_MINHOOK // ONLY USE IF U INJECT LATE
#define SHOW_WINDOWS_CONSOLE
diff --git a/vendor/MinHook/MinHook.h b/vendor/MinHook/MinHook.h
new file mode 100644
index 0000000..15c0a87
--- /dev/null
+++ b/vendor/MinHook/MinHook.h
@@ -0,0 +1,186 @@
+/*
+ * MinHook - The Minimalistic API Hooking Library for x64/x86
+ * Copyright (C) 2009-2017 Tsuda Kageyu.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__)
+ #error MinHook supports only x86 and x64 systems.
+#endif
+
+#include
+
+// MinHook Error Codes.
+typedef enum MH_STATUS
+{
+ // Unknown error. Should not be returned.
+ MH_UNKNOWN = -1,
+
+ // Successful.
+ MH_OK = 0,
+
+ // MinHook is already initialized.
+ MH_ERROR_ALREADY_INITIALIZED,
+
+ // MinHook is not initialized yet, or already uninitialized.
+ MH_ERROR_NOT_INITIALIZED,
+
+ // The hook for the specified target function is already created.
+ MH_ERROR_ALREADY_CREATED,
+
+ // The hook for the specified target function is not created yet.
+ MH_ERROR_NOT_CREATED,
+
+ // The hook for the specified target function is already enabled.
+ MH_ERROR_ENABLED,
+
+ // The hook for the specified target function is not enabled yet, or already
+ // disabled.
+ MH_ERROR_DISABLED,
+
+ // The specified pointer is invalid. It points the address of non-allocated
+ // and/or non-executable region.
+ MH_ERROR_NOT_EXECUTABLE,
+
+ // The specified target function cannot be hooked.
+ MH_ERROR_UNSUPPORTED_FUNCTION,
+
+ // Failed to allocate memory.
+ MH_ERROR_MEMORY_ALLOC,
+
+ // Failed to change the memory protection.
+ MH_ERROR_MEMORY_PROTECT,
+
+ // The specified module is not loaded.
+ MH_ERROR_MODULE_NOT_FOUND,
+
+ // The specified function is not found.
+ MH_ERROR_FUNCTION_NOT_FOUND
+}
+MH_STATUS;
+
+// Can be passed as a parameter to MH_EnableHook, MH_DisableHook,
+// MH_QueueEnableHook or MH_QueueDisableHook.
+#define MH_ALL_HOOKS NULL
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ // Initialize the MinHook library. You must call this function EXACTLY ONCE
+ // at the beginning of your program.
+ MH_STATUS WINAPI MH_Initialize(VOID);
+
+ // Uninitialize the MinHook library. You must call this function EXACTLY
+ // ONCE at the end of your program.
+ MH_STATUS WINAPI MH_Uninitialize(VOID);
+
+ // Creates a Hook for the specified target function, in disabled state.
+ // Parameters:
+ // pTarget [in] A pointer to the target function, which will be
+ // overridden by the detour function.
+ // pDetour [in] A pointer to the detour function, which will override
+ // the target function.
+ // ppOriginal [out] A pointer to the trampoline function, which will be
+ // used to call the original target function.
+ // This parameter can be NULL.
+ MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);
+
+ // Creates a Hook for the specified API function, in disabled state.
+ // Parameters:
+ // pszModule [in] A pointer to the loaded module name which contains the
+ // target function.
+ // pszTarget [in] A pointer to the target function name, which will be
+ // overridden by the detour function.
+ // pDetour [in] A pointer to the detour function, which will override
+ // the target function.
+ // ppOriginal [out] A pointer to the trampoline function, which will be
+ // used to call the original target function.
+ // This parameter can be NULL.
+ MH_STATUS WINAPI MH_CreateHookApi(
+ LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal);
+
+ // Creates a Hook for the specified API function, in disabled state.
+ // Parameters:
+ // pszModule [in] A pointer to the loaded module name which contains the
+ // target function.
+ // pszTarget [in] A pointer to the target function name, which will be
+ // overridden by the detour function.
+ // pDetour [in] A pointer to the detour function, which will override
+ // the target function.
+ // ppOriginal [out] A pointer to the trampoline function, which will be
+ // used to call the original target function.
+ // This parameter can be NULL.
+ // ppTarget [out] A pointer to the target function, which will be used
+ // with other functions.
+ // This parameter can be NULL.
+ MH_STATUS WINAPI MH_CreateHookApiEx(
+ LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget);
+
+ // Removes an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);
+
+ // Enables an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ // If this parameter is MH_ALL_HOOKS, all created hooks are
+ // enabled in one go.
+ MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);
+
+ // Disables an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ // If this parameter is MH_ALL_HOOKS, all created hooks are
+ // disabled in one go.
+ MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);
+
+ // Queues to enable an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ // If this parameter is MH_ALL_HOOKS, all created hooks are
+ // queued to be enabled.
+ MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);
+
+ // Queues to disable an already created hook.
+ // Parameters:
+ // pTarget [in] A pointer to the target function.
+ // If this parameter is MH_ALL_HOOKS, all created hooks are
+ // queued to be disabled.
+ MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
+
+ // Applies all queued changes in one go.
+ MH_STATUS WINAPI MH_ApplyQueued(VOID);
+
+ // Translates the MH_STATUS to its name as a string.
+ const char * WINAPI MH_StatusToString(MH_STATUS status);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/vendor/MinHook/minhook.x64.lib b/vendor/MinHook/minhook.x64.lib
new file mode 100644
index 0000000..09eb5f1
Binary files /dev/null and b/vendor/MinHook/minhook.x64.lib differ