2021-07-08 16:33:31 +02:00
|
|
|
#include "pch.h"
|
2022-03-18 10:37:03 +01:00
|
|
|
#include "dedicated.h"
|
2021-07-08 16:33:31 +02:00
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
#include <iostream>
|
2021-07-08 16:33:31 +02:00
|
|
|
#include <wchar.h>
|
|
|
|
#include <iostream>
|
|
|
|
#include <vector>
|
2021-12-30 03:26:08 +01:00
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
2021-12-27 12:53:25 +01:00
|
|
|
#include <filesystem>
|
2022-10-18 00:26:07 +02:00
|
|
|
#include <Psapi.h>
|
2021-12-30 03:26:08 +01:00
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
AUTOHOOK_INIT()
|
2021-07-08 16:33:31 +02:00
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
// called from the ON_DLL_LOAD macros
|
|
|
|
__dllLoadCallback::__dllLoadCallback(
|
|
|
|
eDllLoadCallbackSide side, const std::string dllName, DllLoadCallbackFuncType callback, std::string uniqueStr, std::string reliesOn)
|
|
|
|
{
|
|
|
|
// parse reliesOn array from string
|
|
|
|
std::vector<std::string> reliesOnArray;
|
2021-07-08 16:33:31 +02:00
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
if (reliesOn.length() && reliesOn[0] != '(')
|
|
|
|
{
|
|
|
|
reliesOnArray.push_back(reliesOn);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// follows the format (tag, tag, tag)
|
|
|
|
std::string sCurrentTag;
|
|
|
|
for (int i = 1; i < reliesOn.length(); i++)
|
|
|
|
{
|
|
|
|
if (!isspace(reliesOn[i]))
|
|
|
|
{
|
|
|
|
if (reliesOn[i] == ',' || reliesOn[i] == ')')
|
|
|
|
{
|
|
|
|
reliesOnArray.push_back(sCurrentTag);
|
|
|
|
sCurrentTag = "";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sCurrentTag += reliesOn[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-30 02:58:19 +01:00
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
switch (side)
|
|
|
|
{
|
|
|
|
case eDllLoadCallbackSide::UNSIDED:
|
|
|
|
{
|
|
|
|
AddDllLoadCallback(dllName, callback, uniqueStr, reliesOnArray);
|
|
|
|
break;
|
|
|
|
}
|
2021-07-08 16:33:31 +02:00
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
case eDllLoadCallbackSide::CLIENT:
|
|
|
|
{
|
|
|
|
AddDllLoadCallbackForClient(dllName, callback, uniqueStr, reliesOnArray);
|
|
|
|
break;
|
|
|
|
}
|
2021-12-30 02:58:19 +01:00
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
case eDllLoadCallbackSide::DEDICATED_SERVER:
|
|
|
|
{
|
|
|
|
AddDllLoadCallbackForDedicatedServer(dllName, callback, uniqueStr, reliesOnArray);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-08 16:33:31 +02:00
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
void __fileAutohook::Dispatch()
|
2021-07-08 16:33:31 +02:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
for (__autohook* hook : hooks)
|
|
|
|
hook->Dispatch();
|
|
|
|
}
|
|
|
|
|
|
|
|
void __fileAutohook::DispatchForModule(const char* pModuleName)
|
|
|
|
{
|
|
|
|
const int iModuleNameLen = strlen(pModuleName);
|
|
|
|
|
|
|
|
for (__autohook* hook : hooks)
|
|
|
|
if ((hook->iAddressResolutionMode == __autohook::OFFSET_STRING && !strncmp(pModuleName, hook->pAddrString, iModuleNameLen)) ||
|
|
|
|
(hook->iAddressResolutionMode == __autohook::PROCADDRESS && !strcmp(pModuleName, hook->pModuleName)))
|
|
|
|
hook->Dispatch();
|
|
|
|
}
|
2022-02-04 02:09:08 +01:00
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
ManualHook::ManualHook(const char* funcName, LPVOID func) : pHookFunc(func), ppOrigFunc(nullptr)
|
|
|
|
{
|
|
|
|
const int iFuncNameStrlen = strlen(funcName);
|
|
|
|
pFuncName = new char[iFuncNameStrlen];
|
|
|
|
memcpy(pFuncName, funcName, iFuncNameStrlen);
|
2021-07-08 16:33:31 +02:00
|
|
|
}
|
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
ManualHook::ManualHook(const char* funcName, LPVOID* orig, LPVOID func) : pHookFunc(func), ppOrigFunc(orig)
|
|
|
|
{
|
|
|
|
const int iFuncNameStrlen = strlen(funcName);
|
|
|
|
pFuncName = new char[iFuncNameStrlen];
|
|
|
|
memcpy(pFuncName, funcName, iFuncNameStrlen);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ManualHook::Dispatch(LPVOID addr, LPVOID* orig)
|
|
|
|
{
|
|
|
|
if (orig)
|
|
|
|
ppOrigFunc = orig;
|
|
|
|
|
|
|
|
if (MH_CreateHook(addr, pHookFunc, ppOrigFunc) == MH_OK)
|
|
|
|
{
|
|
|
|
if (MH_EnableHook(addr) == MH_OK)
|
|
|
|
{
|
|
|
|
spdlog::info("Enabling hook {}", pFuncName);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
spdlog::error("MH_EnableHook failed for function {}", pFuncName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
spdlog::error("MH_CreateHook failed for function {}", pFuncName);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// dll load callback stuff
|
|
|
|
// this allows for code to register callbacks to be run as soon as a dll is loaded, mainly to allow for patches to be made on dll load
|
|
|
|
struct DllLoadCallback
|
|
|
|
{
|
|
|
|
std::string dll;
|
|
|
|
DllLoadCallbackFuncType callback;
|
|
|
|
std::string tag;
|
|
|
|
std::vector<std::string> reliesOn;
|
|
|
|
bool called;
|
|
|
|
};
|
|
|
|
|
|
|
|
// HACK: declaring and initialising this vector at file scope crashes on debug builds due to static initialisation order
|
|
|
|
// using a static var like this ensures that the vector is initialised lazily when it's used
|
|
|
|
std::vector<DllLoadCallback>& GetDllLoadCallbacks()
|
|
|
|
{
|
|
|
|
static std::vector<DllLoadCallback> vec = std::vector<DllLoadCallback>();
|
|
|
|
return vec;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::vector<std::string> reliesOn)
|
|
|
|
{
|
|
|
|
DllLoadCallback& callbackStruct = GetDllLoadCallbacks().emplace_back();
|
|
|
|
|
|
|
|
callbackStruct.dll = dll;
|
|
|
|
callbackStruct.callback = callback;
|
|
|
|
callbackStruct.tag = tag;
|
|
|
|
callbackStruct.reliesOn = reliesOn;
|
|
|
|
callbackStruct.called = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddDllLoadCallbackForDedicatedServer(
|
|
|
|
std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::vector<std::string> reliesOn)
|
|
|
|
{
|
|
|
|
if (!IsDedicatedServer())
|
|
|
|
return;
|
|
|
|
|
|
|
|
AddDllLoadCallback(dll, callback, tag, reliesOn);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddDllLoadCallbackForClient(std::string dll, DllLoadCallbackFuncType callback, std::string tag, std::vector<std::string> reliesOn)
|
|
|
|
{
|
|
|
|
if (IsDedicatedServer())
|
|
|
|
return;
|
|
|
|
|
|
|
|
AddDllLoadCallback(dll, callback, tag, reliesOn);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MakeHook(LPVOID pTarget, LPVOID pDetour, void* ppOriginal, const char* pFuncName)
|
|
|
|
{
|
|
|
|
char* pStrippedFuncName = (char*)pFuncName;
|
|
|
|
// strip & char from funcname
|
|
|
|
if (*pStrippedFuncName == '&')
|
|
|
|
pStrippedFuncName++;
|
|
|
|
|
|
|
|
if (MH_CreateHook(pTarget, pDetour, (LPVOID*)ppOriginal) == MH_OK)
|
|
|
|
{
|
|
|
|
if (MH_EnableHook(pTarget) == MH_OK)
|
|
|
|
spdlog::info("Enabling hook {}", pStrippedFuncName);
|
|
|
|
else
|
|
|
|
spdlog::error("MH_EnableHook failed for function {}", pStrippedFuncName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
spdlog::error("MH_CreateHook failed for function {}", pStrippedFuncName);
|
|
|
|
}
|
|
|
|
|
|
|
|
AUTOHOOK_ABSOLUTEADDR(_GetCommandLineA, GetCommandLineA, LPSTR, WINAPI, ())
|
2021-12-30 03:26:08 +01:00
|
|
|
{
|
2021-12-31 13:41:53 +01:00
|
|
|
static char* cmdlineModified;
|
2021-12-30 03:26:08 +01:00
|
|
|
static char* cmdlineOrg;
|
|
|
|
|
2021-12-31 13:41:53 +01:00
|
|
|
if (cmdlineOrg == nullptr || cmdlineModified == nullptr)
|
2021-12-30 03:26:08 +01:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
cmdlineOrg = _GetCommandLineA();
|
2021-12-30 03:26:08 +01:00
|
|
|
bool isDedi = strstr(cmdlineOrg, "-dedicated"); // well, this one has to be a real argument
|
2022-02-28 21:27:54 +01:00
|
|
|
bool ignoreStartupArgs = strstr(cmdlineOrg, "-nostartupargs");
|
2021-12-30 03:26:08 +01:00
|
|
|
|
|
|
|
std::string args;
|
|
|
|
std::ifstream cmdlineArgFile;
|
|
|
|
|
|
|
|
// it looks like CommandLine() prioritizes parameters apprearing first, so we want the real commandline to take priority
|
|
|
|
// not to mention that cmdlineOrg starts with the EXE path
|
|
|
|
args.append(cmdlineOrg);
|
|
|
|
args.append(" ");
|
|
|
|
|
|
|
|
// append those from the file
|
|
|
|
|
2022-02-28 21:27:54 +01:00
|
|
|
if (!ignoreStartupArgs)
|
2021-12-30 03:26:08 +01:00
|
|
|
{
|
2022-02-28 21:27:54 +01:00
|
|
|
|
|
|
|
cmdlineArgFile = std::ifstream(!isDedi ? "ns_startup_args.txt" : "ns_startup_args_dedi.txt");
|
|
|
|
|
|
|
|
if (cmdlineArgFile)
|
|
|
|
{
|
|
|
|
std::stringstream argBuffer;
|
|
|
|
argBuffer << cmdlineArgFile.rdbuf();
|
|
|
|
cmdlineArgFile.close();
|
|
|
|
|
|
|
|
// if some other command line option includes "-northstar" in the future then you have to refactor this check to check with
|
|
|
|
// both either space after or ending with
|
|
|
|
if (!isDedi && argBuffer.str().find("-northstar") != std::string::npos)
|
|
|
|
MessageBoxA(
|
|
|
|
NULL,
|
|
|
|
"The \"-northstar\" command line option is NOT supposed to go into ns_startup_args.txt file!\n\nThis option is "
|
|
|
|
"supposed to go into Origin/Steam game launch options, and then you are supposed to launch the original "
|
|
|
|
"Titanfall2.exe "
|
|
|
|
"rather than NorthstarLauncher.exe to make use of it.",
|
2022-04-14 00:29:44 +02:00
|
|
|
"Northstar Warning",
|
|
|
|
MB_ICONWARNING);
|
2022-02-28 21:27:54 +01:00
|
|
|
|
|
|
|
args.append(argBuffer.str());
|
|
|
|
}
|
2021-12-30 03:26:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
auto len = args.length();
|
2021-12-31 13:41:53 +01:00
|
|
|
cmdlineModified = new char[len + 1];
|
|
|
|
if (!cmdlineModified)
|
2021-12-30 03:26:08 +01:00
|
|
|
{
|
|
|
|
spdlog::error("malloc failed for command line");
|
|
|
|
return cmdlineOrg;
|
|
|
|
}
|
2021-12-31 13:41:53 +01:00
|
|
|
memcpy(cmdlineModified, args.c_str(), len + 1);
|
2022-02-04 02:09:08 +01:00
|
|
|
|
2021-12-31 13:41:53 +01:00
|
|
|
spdlog::info("Command line: {}", cmdlineModified);
|
2021-12-30 03:26:08 +01:00
|
|
|
}
|
|
|
|
|
2021-12-31 13:41:53 +01:00
|
|
|
return cmdlineModified;
|
2021-07-08 16:33:31 +02:00
|
|
|
}
|
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
std::vector<std::string> calledTags;
|
2021-12-30 02:58:19 +01:00
|
|
|
void CallLoadLibraryACallbacks(LPCSTR lpLibFileName, HMODULE moduleAddress)
|
2021-07-08 16:33:31 +02:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
CModule cModule(moduleAddress);
|
|
|
|
|
|
|
|
while (true)
|
2021-12-30 02:58:19 +01:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
bool bDoneCalling = true;
|
|
|
|
|
|
|
|
for (auto& callbackStruct : GetDllLoadCallbacks())
|
2021-12-30 02:58:19 +01:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
if (!callbackStruct.called && fs::path(lpLibFileName).filename() == fs::path(callbackStruct.dll).filename())
|
|
|
|
{
|
|
|
|
bool bShouldContinue = false;
|
|
|
|
|
|
|
|
if (!callbackStruct.reliesOn.empty())
|
|
|
|
{
|
|
|
|
for (std::string tag : callbackStruct.reliesOn)
|
|
|
|
{
|
|
|
|
if (std::find(calledTags.begin(), calledTags.end(), tag) == calledTags.end())
|
|
|
|
{
|
|
|
|
bDoneCalling = false;
|
|
|
|
bShouldContinue = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bShouldContinue)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
callbackStruct.callback(moduleAddress);
|
|
|
|
calledTags.push_back(callbackStruct.tag);
|
|
|
|
callbackStruct.called = true;
|
|
|
|
}
|
2021-12-30 02:58:19 +01:00
|
|
|
}
|
2022-10-18 00:26:07 +02:00
|
|
|
|
|
|
|
if (bDoneCalling)
|
|
|
|
break;
|
2021-12-30 02:58:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CallLoadLibraryWCallbacks(LPCWSTR lpLibFileName, HMODULE moduleAddress)
|
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
CModule cModule(moduleAddress);
|
|
|
|
|
|
|
|
while (true)
|
2021-12-30 02:58:19 +01:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
bool bDoneCalling = true;
|
|
|
|
|
|
|
|
for (auto& callbackStruct : GetDllLoadCallbacks())
|
2021-12-30 02:58:19 +01:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
if (!callbackStruct.called && fs::path(lpLibFileName).filename() == fs::path(callbackStruct.dll).filename())
|
|
|
|
{
|
|
|
|
bool bShouldContinue = false;
|
|
|
|
|
|
|
|
if (!callbackStruct.reliesOn.empty())
|
|
|
|
{
|
|
|
|
for (std::string tag : callbackStruct.reliesOn)
|
|
|
|
{
|
|
|
|
if (std::find(calledTags.begin(), calledTags.end(), tag) == calledTags.end())
|
|
|
|
{
|
|
|
|
bDoneCalling = false;
|
|
|
|
bShouldContinue = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bShouldContinue)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
callbackStruct.callback(moduleAddress);
|
|
|
|
calledTags.push_back(callbackStruct.tag);
|
|
|
|
callbackStruct.called = true;
|
|
|
|
}
|
2021-12-30 02:58:19 +01:00
|
|
|
}
|
2022-10-18 00:26:07 +02:00
|
|
|
|
|
|
|
if (bDoneCalling)
|
|
|
|
break;
|
2021-12-30 02:58:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-31 22:46:45 +01:00
|
|
|
void CallAllPendingDLLLoadCallbacks()
|
|
|
|
{
|
|
|
|
HMODULE hMods[1024];
|
|
|
|
HANDLE hProcess = GetCurrentProcess();
|
|
|
|
DWORD cbNeeded;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
// Get a list of all the modules in this process.
|
|
|
|
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
|
2021-07-08 16:33:31 +02:00
|
|
|
{
|
2021-12-31 22:46:45 +01:00
|
|
|
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
|
2021-07-08 16:33:31 +02:00
|
|
|
{
|
2021-12-31 22:46:45 +01:00
|
|
|
wchar_t szModName[MAX_PATH];
|
|
|
|
|
|
|
|
// Get the full path to the module's file.
|
|
|
|
if (GetModuleFileNameExW(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)))
|
2021-07-08 16:33:31 +02:00
|
|
|
{
|
2021-12-31 22:46:45 +01:00
|
|
|
CallLoadLibraryWCallbacks(szModName, hMods[i]);
|
2021-07-08 16:33:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-31 22:46:45 +01:00
|
|
|
}
|
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
// clang-format off
|
|
|
|
AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExA, LoadLibraryExA,
|
|
|
|
HMODULE, WINAPI, (LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags))
|
|
|
|
// clang-format on
|
2021-07-08 16:33:31 +02:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
HMODULE moduleAddress;
|
|
|
|
|
|
|
|
// replace xinput dll with one that has ASLR
|
2022-09-25 01:36:41 +02:00
|
|
|
if (!strncmp(lpLibFileName, "XInput1_3.dll", 14))
|
2021-07-08 16:33:31 +02:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
moduleAddress = _LoadLibraryExA("XInput9_1_0.dll", hFile, dwFlags);
|
|
|
|
|
|
|
|
if (!moduleAddress)
|
2022-09-25 01:36:41 +02:00
|
|
|
{
|
|
|
|
MessageBoxA(0, "Could not find XInput9_1_0.dll", "Northstar", MB_ICONERROR);
|
|
|
|
exit(-1);
|
2022-10-18 00:26:07 +02:00
|
|
|
|
|
|
|
return nullptr;
|
2022-09-25 01:36:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2022-10-18 00:26:07 +02:00
|
|
|
moduleAddress = _LoadLibraryExA(lpLibFileName, hFile, dwFlags);
|
|
|
|
|
|
|
|
if (moduleAddress)
|
|
|
|
CallLoadLibraryACallbacks(lpLibFileName, moduleAddress);
|
|
|
|
|
|
|
|
return moduleAddress;
|
2021-12-30 02:58:19 +01:00
|
|
|
}
|
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
// clang-format off
|
|
|
|
AUTOHOOK_ABSOLUTEADDR(_LoadLibraryA, LoadLibraryA,
|
|
|
|
HMODULE, WINAPI, (LPCSTR lpLibFileName))
|
|
|
|
// clang-format on
|
2021-12-30 02:58:19 +01:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
HMODULE moduleAddress = _LoadLibraryA(lpLibFileName);
|
2021-12-30 02:58:19 +01:00
|
|
|
|
|
|
|
if (moduleAddress)
|
|
|
|
CallLoadLibraryACallbacks(lpLibFileName, moduleAddress);
|
2021-07-08 16:33:31 +02:00
|
|
|
|
|
|
|
return moduleAddress;
|
|
|
|
}
|
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
// clang-format off
|
|
|
|
AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExW, LoadLibraryExW,
|
|
|
|
HMODULE, WINAPI, (LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags))
|
|
|
|
// clang-format on
|
2021-07-08 16:33:31 +02:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
HMODULE moduleAddress = _LoadLibraryExW(lpLibFileName, hFile, dwFlags);
|
2021-07-08 16:33:31 +02:00
|
|
|
|
|
|
|
if (moduleAddress)
|
2021-12-30 02:58:19 +01:00
|
|
|
CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress);
|
|
|
|
|
|
|
|
return moduleAddress;
|
|
|
|
}
|
|
|
|
|
2022-10-18 00:26:07 +02:00
|
|
|
// clang-format off
|
|
|
|
AUTOHOOK_ABSOLUTEADDR(_LoadLibraryW, LoadLibraryW,
|
|
|
|
HMODULE, WINAPI, (LPCWSTR lpLibFileName))
|
|
|
|
// clang-format on
|
2021-12-30 02:58:19 +01:00
|
|
|
{
|
2022-10-18 00:26:07 +02:00
|
|
|
HMODULE moduleAddress = _LoadLibraryW(lpLibFileName);
|
2021-12-30 02:58:19 +01:00
|
|
|
|
|
|
|
if (moduleAddress)
|
|
|
|
CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress);
|
2021-07-08 16:33:31 +02:00
|
|
|
|
|
|
|
return moduleAddress;
|
2022-08-08 12:12:11 +02:00
|
|
|
}
|
2022-10-18 00:26:07 +02:00
|
|
|
|
|
|
|
void InstallInitialHooks()
|
|
|
|
{
|
|
|
|
if (MH_Initialize() != MH_OK)
|
|
|
|
spdlog::error("MH_Initialize (minhook initialization) failed");
|
|
|
|
|
|
|
|
AUTOHOOK_DISPATCH()
|
|
|
|
}
|