Replace Deviare In-Proc with Microsoft Detours

This commit is contained in:
Cameron Gutman 2022-03-08 20:58:40 -06:00
parent e078a8b7b6
commit d6ef8945f5
6 changed files with 58 additions and 38 deletions

View file

@ -12,8 +12,11 @@ contains(QT_ARCH, i386) {
contains(QT_ARCH, x86_64) { contains(QT_ARCH, x86_64) {
LIBS += -L$$PWD/../libs/windows/lib/x64 LIBS += -L$$PWD/../libs/windows/lib/x64
} }
contains(QT_ARCH, arm64) {
LIBS += -L$$PWD/../libs/windows/lib/arm64
}
LIBS += -lNktHookLib LIBS += -ldetours
DEFINES += ANTIHOOKING_LIBRARY DEFINES += ANTIHOOKING_LIBRARY
SOURCES += antihookingprotection.cpp SOURCES += antihookingprotection.cpp
HEADERS += antihookingprotection.h HEADERS += antihookingprotection.h

View file

@ -1,6 +1,9 @@
#include "antihookingprotection.h" #include "antihookingprotection.h"
#include <NktHookLib.h> #define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <detours.h>
typedef HMODULE (WINAPI *LoadLibraryAFunc)(LPCSTR lpLibFileName); typedef HMODULE (WINAPI *LoadLibraryAFunc)(LPCSTR lpLibFileName);
typedef HMODULE (WINAPI *LoadLibraryWFunc)(LPCWSTR lpLibFileName); typedef HMODULE (WINAPI *LoadLibraryWFunc)(LPCWSTR lpLibFileName);
@ -12,25 +15,35 @@ class AntiHookingProtection
public: public:
static void enable() static void enable()
{ {
#ifdef QT_DEBUG DetourTransactionBegin();
s_HookManager.SetEnableDebugOutput(true); DetourUpdateThread(GetCurrentThread());
#endif
HINSTANCE kernel32Handle = NktHookLibHelpers::GetModuleBaseAddress(L"kernel32.dll"); s_RealLoadLibraryA = LoadLibraryA;
SIZE_T hookId; DetourAttach(&(PVOID&)s_RealLoadLibraryA, LoadLibraryAHook);
s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryA, s_RealLoadLibraryW = LoadLibraryW;
NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryA"), DetourAttach(&(PVOID&)s_RealLoadLibraryW, LoadLibraryWHook);
(LPVOID)AntiHookingProtection::LoadLibraryAHook);
s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryW, s_RealLoadLibraryExA = LoadLibraryExA;
NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryW"), DetourAttach(&(PVOID&)s_RealLoadLibraryExA, LoadLibraryExAHook);
(LPVOID)AntiHookingProtection::LoadLibraryWHook);
s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryExA, s_RealLoadLibraryExW = LoadLibraryExW;
NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryExA"), DetourAttach(&(PVOID&)s_RealLoadLibraryExW, LoadLibraryExWHook);
(LPVOID)AntiHookingProtection::LoadLibraryExAHook);
s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryExW, DetourTransactionCommit();
NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryExW"), }
(LPVOID)AntiHookingProtection::LoadLibraryExWHook);
static void disable()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)s_RealLoadLibraryA, LoadLibraryAHook);
DetourDetach(&(PVOID&)s_RealLoadLibraryW, LoadLibraryWHook);
DetourDetach(&(PVOID&)s_RealLoadLibraryExA, LoadLibraryExAHook);
DetourDetach(&(PVOID&)s_RealLoadLibraryExW, LoadLibraryExWHook);
DetourTransactionCommit();
} }
private: private:
@ -124,7 +137,6 @@ private:
return s_RealLoadLibraryExW(lpLibFileName, hFile, dwFlags); return s_RealLoadLibraryExW(lpLibFileName, hFile, dwFlags);
} }
static CNktHookLib s_HookManager;
static LoadLibraryAFunc s_RealLoadLibraryA; static LoadLibraryAFunc s_RealLoadLibraryA;
static LoadLibraryWFunc s_RealLoadLibraryW; static LoadLibraryWFunc s_RealLoadLibraryW;
static LoadLibraryExAFunc s_RealLoadLibraryExA; static LoadLibraryExAFunc s_RealLoadLibraryExA;
@ -209,7 +221,6 @@ private:
}; };
}; };
CNktHookLib AntiHookingProtection::s_HookManager;
LoadLibraryAFunc AntiHookingProtection::s_RealLoadLibraryA; LoadLibraryAFunc AntiHookingProtection::s_RealLoadLibraryA;
LoadLibraryWFunc AntiHookingProtection::s_RealLoadLibraryW; LoadLibraryWFunc AntiHookingProtection::s_RealLoadLibraryW;
LoadLibraryExAFunc AntiHookingProtection::s_RealLoadLibraryExA; LoadLibraryExAFunc AntiHookingProtection::s_RealLoadLibraryExA;
@ -218,14 +229,26 @@ LoadLibraryExWFunc AntiHookingProtection::s_RealLoadLibraryExW;
AH_EXPORT void AntiHookingDummyImport() {} AH_EXPORT void AntiHookingDummyImport() {}
extern "C" extern "C"
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{ {
if (DetourIsHelperProcess()) {
return TRUE;
}
switch (fdwReason) switch (fdwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
DetourRestoreAfterWith();
AntiHookingProtection::enable(); AntiHookingProtection::enable();
DisableThreadLibraryCalls(hinstDLL); DisableThreadLibraryCalls(hinstDLL);
break; break;
case DLL_PROCESS_DETACH:
// Ignore DLL_PROCESS_DETACH on process exit. No need to waste time
// unhooking everything if the whole process is being destroyed.
if (lpvReserved == NULL) {
AntiHookingProtection::disable();
}
break;
} }
return TRUE; return TRUE;

View file

@ -404,13 +404,11 @@ INCLUDEPATH += $$PWD/../h264bitstream/h264bitstream
DEPENDPATH += $$PWD/../h264bitstream/h264bitstream DEPENDPATH += $$PWD/../h264bitstream/h264bitstream
!winrt { !winrt {
contains(QT_ARCH, i386)|contains(QT_ARCH, x86_64) {
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../AntiHooking/release/ -lAntiHooking win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../AntiHooking/release/ -lAntiHooking
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../AntiHooking/debug/ -lAntiHooking else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../AntiHooking/debug/ -lAntiHooking
INCLUDEPATH += $$PWD/../AntiHooking INCLUDEPATH += $$PWD/../AntiHooking
DEPENDPATH += $$PWD/../AntiHooking DEPENDPATH += $$PWD/../AntiHooking
}
} }
unix:!macx: { unix:!macx: {

View file

@ -22,7 +22,7 @@
#include "streaming/video/ffmpeg.h" #include "streaming/video/ffmpeg.h"
#endif #endif
#if defined(Q_OS_WIN32) && defined(Q_PROCESSOR_X86) #if defined(Q_OS_WIN32)
#include "antihookingprotection.h" #include "antihookingprotection.h"
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
#include <openssl/ssl.h> #include <openssl/ssl.h>
@ -293,10 +293,9 @@ int main(int argc, char *argv[])
SetUnhandledExceptionFilter(UnhandledExceptionHandler); SetUnhandledExceptionFilter(UnhandledExceptionHandler);
#endif #endif
#if defined(Q_OS_WIN32) && defined(Q_PROCESSOR_X86) #if defined(Q_OS_WIN32)
// Force AntiHooking.dll to be statically imported and loaded // Force AntiHooking.dll to be statically imported and loaded
// by ntdll on x86/x64 platforms by calling a dummy function. // by ntdll on Win32 platforms by calling a dummy function.
// AntiHooking.dll is not currently built for ARM64.
AntiHookingDummyImport(); AntiHookingDummyImport();
#elif defined(Q_OS_LINUX) #elif defined(Q_OS_LINUX)
// Force libssl.so to be directly linked to our binary, so // Force libssl.so to be directly linked to our binary, so

2
libs

@ -1 +1 @@
Subproject commit 5ef8a666ebd9d47ec6dfbc2a59e9182cb6229af5 Subproject commit 6a7c1b244c4e15ee9272ee86625e6585931bcd11

View file

@ -8,11 +8,8 @@ SUBDIRS = \
# Build the dependencies in parallel before the final app # Build the dependencies in parallel before the final app
app.depends = qmdnsengine moonlight-common-c h264bitstream app.depends = qmdnsengine moonlight-common-c h264bitstream
win32:!winrt { win32:!winrt {
contains(QT_ARCH, i386)|contains(QT_ARCH, x86_64) {
# We don't build AntiHooking.dll for ARM64 (yet?)
SUBDIRS += AntiHooking SUBDIRS += AntiHooking
app.depends += AntiHooking app.depends += AntiHooking
}
} }
!winrt:win32|macx { !winrt:win32|macx {
SUBDIRS += soundio SUBDIRS += soundio