diff options
Diffstat (limited to 'NorthstarDedicatedTest/hooks.cpp')
-rw-r--r-- | NorthstarDedicatedTest/hooks.cpp | 158 |
1 files changed, 140 insertions, 18 deletions
diff --git a/NorthstarDedicatedTest/hooks.cpp b/NorthstarDedicatedTest/hooks.cpp index 3de8d483..0e653d4e 100644 --- a/NorthstarDedicatedTest/hooks.cpp +++ b/NorthstarDedicatedTest/hooks.cpp @@ -5,15 +5,31 @@ #include <wchar.h> #include <iostream> #include <vector> +#include <fstream> +#include <sstream> +#include <filesystem> +#include <Psapi.h> + +typedef LPSTR(*GetCommandLineAType)(); +LPSTR GetCommandLineAHook(); typedef HMODULE(*LoadLibraryExAType)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); HMODULE LoadLibraryExAHook(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +typedef HMODULE(*LoadLibraryAType)(LPCSTR lpLibFileName); +HMODULE LoadLibraryAHook(LPCSTR lpLibFileName); + typedef HMODULE(*LoadLibraryExWType)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); HMODULE LoadLibraryExWHook(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +typedef HMODULE(*LoadLibraryWType)(LPCWSTR lpLibFileName); +HMODULE LoadLibraryWHook(LPCWSTR lpLibFileName); + +GetCommandLineAType GetCommandLineAOriginal; LoadLibraryExAType LoadLibraryExAOriginal; +LoadLibraryAType LoadLibraryAOriginal; LoadLibraryExWType LoadLibraryExWOriginal; +LoadLibraryWType LoadLibraryWOriginal; void InstallInitialHooks() { @@ -21,8 +37,57 @@ void InstallInitialHooks() spdlog::error("MH_Initialize failed"); HookEnabler hook; + ENABLER_CREATEHOOK(hook, &GetCommandLineA, &GetCommandLineAHook, reinterpret_cast<LPVOID*>(&GetCommandLineAOriginal)); ENABLER_CREATEHOOK(hook, &LoadLibraryExA, &LoadLibraryExAHook, reinterpret_cast<LPVOID*>(&LoadLibraryExAOriginal)); + ENABLER_CREATEHOOK(hook, &LoadLibraryA, &LoadLibraryAHook, reinterpret_cast<LPVOID*>(&LoadLibraryAOriginal)); ENABLER_CREATEHOOK(hook, &LoadLibraryExW, &LoadLibraryExWHook, reinterpret_cast<LPVOID*>(&LoadLibraryExWOriginal)); + ENABLER_CREATEHOOK(hook, &LoadLibraryW, &LoadLibraryWHook, reinterpret_cast<LPVOID*>(&LoadLibraryWOriginal)); +} + +LPSTR GetCommandLineAHook() +{ + static char* cmdlineModified; + static char* cmdlineOrg; + + if (cmdlineOrg == nullptr || cmdlineModified == nullptr) + { + cmdlineOrg = GetCommandLineAOriginal(); + bool isDedi = strstr(cmdlineOrg, "-dedicated"); // well, this one has to be a real argument + + 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 + + cmdlineArgFile = std::ifstream(!isDedi ? "ns_startup_args.txt" : "ns_startup_args_dedi.txt"); + + if (cmdlineArgFile) + { + std::stringstream argBuffer; + argBuffer << cmdlineArgFile.rdbuf(); + cmdlineArgFile.close(); + + args.append(argBuffer.str()); + } + + auto len = args.length(); + cmdlineModified = new char[len + 1]; + if (!cmdlineModified) + { + spdlog::error("malloc failed for command line"); + return cmdlineOrg; + } + memcpy(cmdlineModified, args.c_str(), len + 1); + + spdlog::info("Command line: {}", cmdlineModified); + } + + return cmdlineModified; } // dll load callback stuff @@ -46,21 +111,75 @@ void AddDllLoadCallback(std::string dll, DllLoadCallbackFuncType callback) dllLoadCallbacks.push_back(callbackStruct); } -HMODULE LoadLibraryExAHook(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +void CallLoadLibraryACallbacks(LPCSTR lpLibFileName, HMODULE moduleAddress) { - HMODULE moduleAddress = LoadLibraryExAOriginal(lpLibFileName, hFile, dwFlags); - - if (moduleAddress) + for (auto& callbackStruct : dllLoadCallbacks) + { + if (!callbackStruct->called && strstr(lpLibFileName + (strlen(lpLibFileName) - callbackStruct->dll.length()), callbackStruct->dll.c_str()) != nullptr) + { + callbackStruct->callback(moduleAddress); + callbackStruct->called = true; + } + } +} + +void CallLoadLibraryWCallbacks(LPCWSTR lpLibFileName, HMODULE moduleAddress) +{ + for (auto& callbackStruct : dllLoadCallbacks) + { + std::wstring wcharStrDll = std::wstring(callbackStruct->dll.begin(), callbackStruct->dll.end()); + const wchar_t* callbackDll = wcharStrDll.c_str(); + if (!callbackStruct->called && wcsstr(lpLibFileName + (wcslen(lpLibFileName) - wcharStrDll.length()), callbackDll) != nullptr) + { + callbackStruct->callback(moduleAddress); + callbackStruct->called = true; + } + } +} + +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)) { - for (auto& callbackStruct : dllLoadCallbacks) + for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { - if (!callbackStruct->called && strstr(lpLibFileName + (strlen(lpLibFileName) - strlen(callbackStruct->dll.c_str())), callbackStruct->dll.c_str()) != nullptr) + wchar_t szModName[MAX_PATH]; + + // Get the full path to the module's file. + if (GetModuleFileNameExW(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) { - callbackStruct->callback(moduleAddress); - callbackStruct->called = true; + CallLoadLibraryWCallbacks(szModName, hMods[i]); } } } +} + +HMODULE LoadLibraryExAHook(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) +{ + HMODULE moduleAddress = LoadLibraryExAOriginal(lpLibFileName, hFile, dwFlags); + + if (moduleAddress) + { + CallLoadLibraryACallbacks(lpLibFileName, moduleAddress); + } + + return moduleAddress; +} + +HMODULE LoadLibraryAHook(LPCSTR lpLibFileName) +{ + HMODULE moduleAddress = LoadLibraryAOriginal(lpLibFileName); + + if (moduleAddress) + { + CallLoadLibraryACallbacks(lpLibFileName, moduleAddress); + } return moduleAddress; } @@ -71,16 +190,19 @@ HMODULE LoadLibraryExWHook(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) if (moduleAddress) { - for (auto& callbackStruct : dllLoadCallbacks) - { - std::wstring wcharStrDll = std::wstring(callbackStruct->dll.begin(), callbackStruct->dll.end()); - const wchar_t* callbackDll = wcharStrDll.c_str(); - if (!callbackStruct->called && wcsstr(lpLibFileName + (wcslen(lpLibFileName) - wcslen(callbackDll)), callbackDll) != nullptr) - { - callbackStruct->callback(moduleAddress); - callbackStruct->called = true; - } - } + CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress); + } + + return moduleAddress; +} + +HMODULE LoadLibraryWHook(LPCWSTR lpLibFileName) +{ + HMODULE moduleAddress = LoadLibraryWOriginal(lpLibFileName); + + if (moduleAddress) + { + CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress); } return moduleAddress; |