1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Log module path and offset for function hooks

This commit is contained in:
narzoul 2019-11-05 22:05:04 +01:00
parent 6aaf12b0a4
commit cb7a46cd5e
5 changed files with 42 additions and 28 deletions

View File

@ -1,9 +1,11 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <algorithm> #include <algorithm>
#include <filesystem>
#include <list> #include <list>
#include <map> #include <map>
#include <set> #include <set>
#include <sstream>
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -82,16 +84,25 @@ namespace
return ntHeaders; return ntHeaders;
} }
std::string getModuleBaseName(HMODULE module) std::filesystem::path getModulePath(HMODULE module)
{ {
char path[MAX_PATH] = {}; char path[MAX_PATH] = {};
GetModuleFileName(module, path, sizeof(path)); GetModuleFileName(module, path, sizeof(path));
const char* lastBackSlash = strrchr(path, '\\'); return path;
const char* baseName = lastBackSlash ? lastBackSlash + 1 : path;
return baseName;
} }
void hookFunction(const char* funcName, void*& origFuncPtr, void* newFuncPtr) std::string funcAddrToStr(void* funcPtr)
{
std::ostringstream oss;
HMODULE module = nullptr;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
static_cast<char*>(funcPtr), &module);
oss << getModulePath(module).string() << "+0x" << std::hex <<
reinterpret_cast<DWORD>(funcPtr) - reinterpret_cast<DWORD>(module);
return oss.str();
}
void hookFunction(void*& origFuncPtr, void* newFuncPtr, const char* funcName)
{ {
const auto it = findOrigFunc(origFuncPtr); const auto it = findOrigFunc(origFuncPtr);
if (it != g_hookedFunctions.end()) if (it != g_hookedFunctions.end())
@ -100,27 +111,29 @@ namespace
return; return;
} }
char origFuncPtrStr[20] = {};
if (!funcName)
{
sprintf_s(origFuncPtrStr, "%p", origFuncPtr);
funcName = origFuncPtrStr;
}
void* const hookedFuncPtr = origFuncPtr; void* const hookedFuncPtr = origFuncPtr;
HMODULE module = nullptr;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
static_cast<char*>(hookedFuncPtr), &module);
Compat::LogDebug() << "Hooking function: " << funcName << " (" << funcAddrToStr(hookedFuncPtr) << ')';
DetourTransactionBegin(); DetourTransactionBegin();
const bool attachSuccessful = NO_ERROR == DetourAttach(&origFuncPtr, newFuncPtr); const bool attachSuccessful = NO_ERROR == DetourAttach(&origFuncPtr, newFuncPtr);
const bool commitSuccessful = NO_ERROR == DetourTransactionCommit(); const bool commitSuccessful = NO_ERROR == DetourTransactionCommit();
if (!attachSuccessful || !commitSuccessful) if (!attachSuccessful || !commitSuccessful)
{ {
if (funcName) Compat::LogDebug() << "ERROR: Failed to hook a function: " << funcName;
{
Compat::LogDebug() << "ERROR: Failed to hook a function: " << funcName;
}
else
{
Compat::LogDebug() << "ERROR: Failed to hook a function: " << origFuncPtr;
}
return; return;
} }
HMODULE module = nullptr;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
reinterpret_cast<char*>(hookedFuncPtr), &module);
g_hookedFunctions.emplace( g_hookedFunctions.emplace(
std::make_pair(hookedFuncPtr, HookedFunctionInfo{ module, origFuncPtr, newFuncPtr })); std::make_pair(hookedFuncPtr, HookedFunctionInfo{ module, origFuncPtr, newFuncPtr }));
} }
@ -155,13 +168,13 @@ namespace Compat
continue; continue;
} }
std::string moduleBaseName(getModuleBaseName(module)); std::string moduleBaseName(getModulePath(module).filename().string());
if (0 != _stricmp(moduleBaseName.c_str(), moduleName)) if (0 != _stricmp(moduleBaseName.c_str(), moduleName))
{ {
Compat::Log() << "Disabling external hook to " << funcName << " in " << moduleBaseName; Compat::Log() << "Disabling external hook to " << funcName << " in " << moduleBaseName;
static std::list<void*> origFuncs; static std::list<void*> origFuncs;
origFuncs.push_back(hookFunc); origFuncs.push_back(hookFunc);
hookFunction(origFuncs.back(), newFunc); hookFunction(origFuncs.back(), newFunc, funcName);
} }
} }
} }
@ -293,9 +306,9 @@ namespace Compat
return proc ? *proc : nullptr; return proc ? *proc : nullptr;
} }
void hookFunction(void*& origFuncPtr, void* newFuncPtr) void hookFunction(void*& origFuncPtr, void* newFuncPtr, const char* funcName)
{ {
::hookFunction(nullptr, origFuncPtr, newFuncPtr); ::hookFunction(origFuncPtr, newFuncPtr, funcName);
} }
void hookFunction(HMODULE module, const char* funcName, void*& origFuncPtr, void* newFuncPtr) void hookFunction(HMODULE module, const char* funcName, void*& origFuncPtr, void* newFuncPtr)
@ -308,7 +321,7 @@ namespace Compat
} }
origFuncPtr = procAddr; origFuncPtr = procAddr;
::hookFunction(funcName, origFuncPtr, newFuncPtr); ::hookFunction(origFuncPtr, newFuncPtr, funcName);
} }
void hookFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr) void hookFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr)
@ -327,7 +340,7 @@ namespace Compat
FARPROC* func = findProcAddressInIat(module, importedModuleName, funcName); FARPROC* func = findProcAddressInIat(module, importedModuleName, funcName);
if (func) if (func)
{ {
Compat::LogDebug() << "Hooking function via IAT: " << funcName; Compat::LogDebug() << "Hooking function via IAT: " << funcName << " (" << funcAddrToStr(*func) << ')';
DWORD oldProtect = 0; DWORD oldProtect = 0;
VirtualProtect(func, sizeof(func), PAGE_READWRITE, &oldProtect); VirtualProtect(func, sizeof(func), PAGE_READWRITE, &oldProtect);
*func = static_cast<FARPROC>(newFuncPtr); *func = static_cast<FARPROC>(newFuncPtr);

View File

@ -10,7 +10,7 @@
Compat::hookFunction<decltype(&func), &func>(#module, #func, &newFunc) Compat::hookFunction<decltype(&func), &func>(#module, #func, &newFunc)
#define HOOK_SHIM_FUNCTION(func, newFunc) \ #define HOOK_SHIM_FUNCTION(func, newFunc) \
Compat::hookFunction( \ Compat::hookFunction( \
reinterpret_cast<void*&>(Compat::getOrigFuncPtr<decltype(&func), &func>()), newFunc); reinterpret_cast<void*&>(Compat::getOrigFuncPtr<decltype(&func), &func>()), newFunc, #func);
namespace Compat namespace Compat
@ -27,7 +27,7 @@ namespace Compat
FARPROC* findProcAddressInIat(HMODULE module, const char* importedModuleName, const char* procName); FARPROC* findProcAddressInIat(HMODULE module, const char* importedModuleName, const char* procName);
FARPROC getProcAddress(HMODULE module, const char* procName); FARPROC getProcAddress(HMODULE module, const char* procName);
FARPROC getProcAddressFromIat(HMODULE module, const char* importedModuleName, const char* procName); FARPROC getProcAddressFromIat(HMODULE module, const char* importedModuleName, const char* procName);
void hookFunction(void*& origFuncPtr, void* newFuncPtr); void hookFunction(void*& origFuncPtr, void* newFuncPtr, const char* funcName);
void hookFunction(HMODULE module, const char* funcName, void*& origFuncPtr, void* newFuncPtr); void hookFunction(HMODULE module, const char* funcName, void*& origFuncPtr, void* newFuncPtr);
void hookFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr); void hookFunction(const char* moduleName, const char* funcName, void*& origFuncPtr, void* newFuncPtr);
void hookIatFunction(HMODULE module, const char* importedModuleName, const char* funcName, void* newFuncPtr); void hookIatFunction(HMODULE module, const char* importedModuleName, const char* funcName, void* newFuncPtr);

View File

@ -42,9 +42,9 @@ public:
m_origVtable.*ptr = m_srcVtable.*ptr; m_origVtable.*ptr = m_srcVtable.*ptr;
if (m_origVtable.*ptr && s_compatVtable.*ptr) if (m_origVtable.*ptr && s_compatVtable.*ptr)
{ {
Compat::LogDebug() << "Hooking function: " << FuncNameVisitor<Vtable>::getFuncName<MemberDataPtr, ptr>();
Compat::hookFunction(reinterpret_cast<void*&>(m_origVtable.*ptr), Compat::hookFunction(reinterpret_cast<void*&>(m_origVtable.*ptr),
getThreadSafeFuncPtr<MemberDataPtr, ptr>(s_compatVtable.*ptr)); getThreadSafeFuncPtr<MemberDataPtr, ptr>(s_compatVtable.*ptr),
FuncNameVisitor<Vtable>::getFuncName<MemberDataPtr, ptr>());
} }
} }

View File

@ -74,7 +74,7 @@ namespace DDraw
if ((flags & DDSCL_FULLSCREEN) && !isDdWndProcHooked) if ((flags & DDSCL_FULLSCREEN) && !isDdWndProcHooked)
{ {
g_origDdWndProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWLP_WNDPROC)); g_origDdWndProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(hwnd, GWLP_WNDPROC));
Compat::hookFunction(reinterpret_cast<void*&>(g_origDdWndProc), ddWndProc); Compat::hookFunction(reinterpret_cast<void*&>(g_origDdWndProc), ddWndProc, "ddWndProc");
isDdWndProcHooked = true; isDdWndProcHooked = true;
} }
} }

View File

@ -86,7 +86,8 @@ namespace
g_currentUser32WndProc->oldWndProc = wndProc; g_currentUser32WndProc->oldWndProc = wndProc;
g_currentUser32WndProc->oldWndProcTrampoline = wndProc; g_currentUser32WndProc->oldWndProcTrampoline = wndProc;
Compat::hookFunction(reinterpret_cast<void*&>(g_currentUser32WndProc->oldWndProcTrampoline), Compat::hookFunction(reinterpret_cast<void*&>(g_currentUser32WndProc->oldWndProcTrampoline),
g_currentUser32WndProc->newWndProc); g_currentUser32WndProc->newWndProc,
g_currentUser32WndProc->procName.c_str());
} }
} }
} }