diff --git a/AntiHooking/AntiHooking.pro b/AntiHooking/AntiHooking.pro new file mode 100644 index 00000000..d7d684db --- /dev/null +++ b/AntiHooking/AntiHooking.pro @@ -0,0 +1,23 @@ +QT -= core gui + +TARGET = AntiHooking +TEMPLATE = lib + +# Support debug and release builds from command line for CI +CONFIG += debug_and_release + +# Ensure symbols are always generated +CONFIG += force_debug_info + +INCLUDEPATH += $$PWD/../libs/windows/include +contains(QT_ARCH, i386) { + LIBS += -L$$PWD/../libs/windows/lib/x86 +} +contains(QT_ARCH, x86_64) { + LIBS += -L$$PWD/../libs/windows/lib/x64 +} + +LIBS += -lNktHookLib +DEFINES += ANTIHOOKING_LIBRARY +SOURCES += antihookingprotection.cpp +HEADERS += antihookingprotection.h diff --git a/AntiHooking/antihookingprotection.cpp b/AntiHooking/antihookingprotection.cpp new file mode 100644 index 00000000..e6807cef --- /dev/null +++ b/AntiHooking/antihookingprotection.cpp @@ -0,0 +1,161 @@ +#include "antihookingprotection.h" + +#include + +typedef HMODULE (WINAPI *LoadLibraryAFunc)(LPCSTR lpLibFileName); +typedef HMODULE (WINAPI *LoadLibraryWFunc)(LPCWSTR lpLibFileName); +typedef HMODULE (WINAPI *LoadLibraryExAFunc)(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); +typedef HMODULE (WINAPI *LoadLibraryExWFunc)(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags); + +class AntiHookingProtection +{ +public: + static void enable() + { + #ifdef QT_DEBUG + s_HookManager.SetEnableDebugOutput(true); + #endif + + HINSTANCE kernel32Handle = NktHookLibHelpers::GetModuleBaseAddress(L"kernel32.dll"); + SIZE_T hookId; + + s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryA, + NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryA"), + (LPVOID)AntiHookingProtection::LoadLibraryAHook); + s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryW, + NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryW"), + (LPVOID)AntiHookingProtection::LoadLibraryWHook); + s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryExA, + NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryExA"), + (LPVOID)AntiHookingProtection::LoadLibraryExAHook); + s_HookManager.Hook(&hookId, (LPVOID*)&s_RealLoadLibraryExW, + NktHookLibHelpers::GetProcedureAddress(kernel32Handle, "LoadLibraryExW"), + (LPVOID)AntiHookingProtection::LoadLibraryExWHook); + } + +private: + static bool isImageBlacklistedW(LPCWSTR lpLibFileName) + { + LPCWSTR dllName; + + // If the library has a path prefixed, remove it + dllName = wcsrchr(lpLibFileName, '\\'); + if (!dllName) { + // No prefix, so use the full name + dllName = lpLibFileName; + } + else { + // Advance past the backslash + dllName++; + } + + // FIXME: We don't currently handle LoadLibrary calls where the + // library name does not include a file extension and the loader + // automatically assumes .dll. + + for (int i = 0; i < ARRAYSIZE(k_BlacklistedDlls); i++) { + if (_wcsicmp(dllName, k_BlacklistedDlls[i]) == 0) { + return true; + } + } + + return false; + } + + static bool isImageBlacklistedA(LPCSTR lpLibFileName) + { + int uniChars = MultiByteToWideChar(CP_THREAD_ACP, 0, lpLibFileName, -1, nullptr, 0); + if (uniChars > 0) { + PWCHAR wideBuffer = new WCHAR[uniChars]; + uniChars = MultiByteToWideChar(CP_THREAD_ACP, 0, + lpLibFileName, -1, + wideBuffer, uniChars * sizeof(WCHAR)); + if (uniChars > 0) { + bool ret = isImageBlacklistedW(wideBuffer); + delete[] wideBuffer; + return ret; + } + else { + delete[] wideBuffer; + } + } + + // Error path + return false; + } + + static HMODULE LoadLibraryAHook(LPCSTR lpLibFileName) + { + if (lpLibFileName && isImageBlacklistedA(lpLibFileName)) { + SetLastError(ERROR_ACCESS_DISABLED_BY_POLICY); + return nullptr; + } + + return s_RealLoadLibraryA(lpLibFileName); + } + + static HMODULE LoadLibraryWHook(LPCWSTR lpLibFileName) + { + if (lpLibFileName && isImageBlacklistedW(lpLibFileName)) { + SetLastError(ERROR_ACCESS_DISABLED_BY_POLICY); + return nullptr; + } + + return s_RealLoadLibraryW(lpLibFileName); + } + + static HMODULE LoadLibraryExAHook(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) + { + if (lpLibFileName && isImageBlacklistedA(lpLibFileName)) { + SetLastError(ERROR_ACCESS_DISABLED_BY_POLICY); + return nullptr; + } + + return s_RealLoadLibraryExA(lpLibFileName, hFile, dwFlags); + } + + static HMODULE LoadLibraryExWHook(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) + { + if (lpLibFileName && isImageBlacklistedW(lpLibFileName)) { + SetLastError(ERROR_ACCESS_DISABLED_BY_POLICY); + return nullptr; + } + + return s_RealLoadLibraryExW(lpLibFileName, hFile, dwFlags); + } + + static CNktHookLib s_HookManager; + static LoadLibraryAFunc s_RealLoadLibraryA; + static LoadLibraryWFunc s_RealLoadLibraryW; + static LoadLibraryExAFunc s_RealLoadLibraryExA; + static LoadLibraryExWFunc s_RealLoadLibraryExW; + + static constexpr LPCWSTR k_BlacklistedDlls[] = { + // This DLL shipped with ASUS Sonic Radar 3 improperly handles + // D3D9 exclusive fullscreen in a way that causes CreateDeviceEx() + // to deadlock. https://github.com/moonlight-stream/moonlight-qt/issues/102 + L"NahimicOSD.dll" + }; +}; + +CNktHookLib AntiHookingProtection::s_HookManager; +LoadLibraryAFunc AntiHookingProtection::s_RealLoadLibraryA; +LoadLibraryWFunc AntiHookingProtection::s_RealLoadLibraryW; +LoadLibraryExAFunc AntiHookingProtection::s_RealLoadLibraryExA; +LoadLibraryExWFunc AntiHookingProtection::s_RealLoadLibraryExW; + +AH_EXPORT void AntiHookingDummyImport() {} + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + AntiHookingProtection::enable(); + DisableThreadLibraryCalls(hinstDLL); + break; + } + + return TRUE; +}; diff --git a/AntiHooking/antihookingprotection.h b/AntiHooking/antihookingprotection.h new file mode 100644 index 00000000..8931882b --- /dev/null +++ b/AntiHooking/antihookingprotection.h @@ -0,0 +1,10 @@ +#pragma once + +#ifdef ANTIHOOKING_LIBRARY +#define AH_EXPORT extern "C" __declspec(dllexport) +#else +#define AH_EXPORT extern "C" __declspec(dllimport) +#endif + +AH_EXPORT void AntiHookingDummyImport(); + diff --git a/app/app.pro b/app/app.pro index ba7508e9..00c5fb8c 100644 --- a/app/app.pro +++ b/app/app.pro @@ -265,6 +265,12 @@ else:unix: LIBS += -L$$OUT_PWD/../h264bitstream/ -lh264bitstream INCLUDEPATH += $$PWD/../h264bitstream/h264bitstream DEPENDPATH += $$PWD/../h264bitstream/h264bitstream +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 + +INCLUDEPATH += $$PWD/../AntiHooking +DEPENDPATH += $$PWD/../AntiHooking + unix:!macx: { isEmpty(PREFIX) { PREFIX = /usr/local diff --git a/app/main.cpp b/app/main.cpp index cd24938c..ee32c8fb 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -16,6 +16,10 @@ #include "streaming/video/ffmpeg.h" #endif +#ifdef Q_OS_WIN32 +#include "antihookingprotection.h" +#endif + #include "cli/startstream.h" #include "cli/commandlineparser.h" #include "path.h" @@ -263,6 +267,14 @@ int main(int argc, char *argv[]) SetUnhandledExceptionFilter(UnhandledExceptionHandler); #endif +#ifdef Q_OS_WIN32 + // Force AntiHooking.dll to be statically imported and loaded + // by ntdll by calling a dummy function. + AntiHookingDummyImport(); +#endif + + qWarning() << qgetenv("Path"); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // This avoids using the default keychain for SSL, which may cause diff --git a/libs/windows/include/NktHookLib.h b/libs/windows/include/NktHookLib.h new file mode 100644 index 00000000..e1295bd7 --- /dev/null +++ b/libs/windows/include/NktHookLib.h @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2010-2013 Nektra S.A., Buenos Aires, Argentina. + * All rights reserved. Contact: http://www.nektra.com + * + * + * This file is part of Deviare In-Proc + * + * + * Commercial License Usage + * ------------------------ + * Licensees holding valid commercial Deviare In-Proc licenses may use this + * file in accordance with the commercial license agreement provided with the + * Software or, alternatively, in accordance with the terms contained in + * a written agreement between you and Nektra. For licensing terms and + * conditions see http://www.nektra.com/licensing/. For further information + * use the contact form at http://www.nektra.com/contact/. + * + * + * GNU General Public License Usage + * -------------------------------- + * Alternatively, this file may be used under the terms of the GNU + * General Public License version 3.0 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. Please review the following information to + * ensure the GNU General Public License version 3.0 requirements will be + * met: http://www.gnu.org/copyleft/gpl.html. + * + **/ + +#ifndef _NKTHOOKLIB +#define _NKTHOOKLIB + +#include + +//----------------------------------------------------------- + +#define NKTHOOKLIB_DontSkipInitialJumps 0x0001 +#define NKTHOOKLIB_DontRemoveOnUnhook 0x0002 +#define NKTHOOKLIB_DontSkipAnyJumps 0x0004 +#define NKTHOOKLIB_SkipNullProcsToHook 0x0008 +#define NKTHOOKLIB_UseAbsoluteIndirectJumps 0x0010 +#define NKTHOOKLIB_DisallowReentrancy 0x0020 +#define NKTHOOKLIB_DontEnableHooks 0x0040 + +#define NKTHOOKLIB_ProcessPlatformX86 1 +#define NKTHOOKLIB_ProcessPlatformX64 2 + +#define NKTHOOKLIB_CurrentProcess ((HANDLE)(LONG_PTR)-1) +#define NKTHOOKLIB_CurrentThread ((HANDLE)(LONG_PTR)-2) + +//----------------------------------------------------------- + +class CNktHookLib +{ +public: + typedef struct tagHOOK_INFO { + SIZE_T nHookId; + LPVOID lpProcToHook; + LPVOID lpNewProcAddr; + //---- + LPVOID lpCallOriginal; + } HOOK_INFO, *LPHOOK_INFO; + + CNktHookLib(); + ~CNktHookLib(); + + DWORD Hook(__out SIZE_T *lpnHookId, __out LPVOID *lplpCallOriginal, __in LPVOID lpProcToHook, + __in LPVOID lpNewProcAddr, __in DWORD dwFlags=0); + DWORD Hook(__inout HOOK_INFO aHookInfo[], __in SIZE_T nCount, __in DWORD dwFlags=0); + DWORD Hook(__inout LPHOOK_INFO aHookInfo[], __in SIZE_T nCount, __in DWORD dwFlags = 0); + + DWORD RemoteHook(__out SIZE_T *lpnHookId, __out LPVOID *lplpCallOriginal, __in DWORD dwPid, + __in LPVOID lpProcToHook, __in LPVOID lpNewProcAddr, __in DWORD dwFlags); + DWORD RemoteHook(__inout HOOK_INFO aHookInfo[], __in SIZE_T nCount, __in DWORD dwPid, __in DWORD dwFlags); + DWORD RemoteHook(__inout LPHOOK_INFO aHookInfo[], __in SIZE_T nCount, __in DWORD dwPid, __in DWORD dwFlags); + + DWORD RemoteHook(__out SIZE_T *lpnHookId, __out LPVOID *lplpCallOriginal, __in HANDLE hProcess, + __in LPVOID lpProcToHook, __in LPVOID lpNewProcAddr, __in DWORD dwFlags); + DWORD RemoteHook(__inout HOOK_INFO aHookInfo[], __in SIZE_T nCount, __in HANDLE hProcess, __in DWORD dwFlags); + DWORD RemoteHook(__inout LPHOOK_INFO aHookInfo[], __in SIZE_T nCount, __in HANDLE hProcess, __in DWORD dwFlags); + + DWORD Unhook(__in SIZE_T nHookId); + DWORD Unhook(__in HOOK_INFO aHookInfo[], __in SIZE_T nCount); + DWORD Unhook(__in LPHOOK_INFO aHookInfo[], __in SIZE_T nCount); + VOID UnhookProcess(__in DWORD dwPid); + VOID UnhookAll(); + + //NOTE: The following 2 (two) methods will remove the hooks from the internal list of hooks but the original + // hook(s) will remain active. + DWORD RemoveHook(__in SIZE_T nHookId, BOOL bDisable); + DWORD RemoveHook(__in HOOK_INFO aHookInfo[], __in SIZE_T nCount, __in BOOL bDisable); + DWORD RemoveHook(__in LPHOOK_INFO aHookInfo[], __in SIZE_T nCount, __in BOOL bDisable); + + DWORD EnableHook(__in SIZE_T nHookId, __in BOOL bEnable); + DWORD EnableHook(__in HOOK_INFO aHookInfo[], __in SIZE_T nCount, __in BOOL bEnable); + DWORD EnableHook(__in LPHOOK_INFO aHookInfo[], __in SIZE_T nCount, __in BOOL bEnable); + + DWORD SetSuspendThreadsWhileHooking(__in BOOL bEnable); + BOOL GetSuspendThreadsWhileHooking(); + + DWORD SetEnableDebugOutput(__in BOOL bEnable); + BOOL GetEnableDebugOutput(); + + void* __cdecl operator new(__in size_t nSize); + void* __cdecl operator new[](__in size_t nSize); + void* __cdecl operator new(__in size_t nSize, __inout void* lpInPlace); + void __cdecl operator delete(__inout void* p); + void __cdecl operator delete[](__inout void* p); +#if _MSC_VER >= 1200 + void __cdecl operator delete(__inout void* p, __inout void* lpPlace); +#endif //_MSC_VER >= 1200 + +private: + DWORD HookCommon(__in LPVOID lpInfo, __in SIZE_T nCount, __in DWORD dwPid, __in DWORD dwFlags); + DWORD UnhookCommon(__in LPVOID lpInfo, __in SIZE_T nCount, __in DWORD dwFlags); + DWORD RemoveHookCommon(__in LPVOID lpInfo, __in SIZE_T nCount, __in BOOL bDisable, __in DWORD dwFlags); + DWORD EnableHookCommon(__in LPVOID lpInfo, __in SIZE_T nCount, __in BOOL bEnable, __in DWORD dwFlags); + +private: + LPVOID lpInternals; +}; + +//----------------------------------------------------------- + +namespace NktHookLibHelpers { + +//NOTE: See "BuildNtSysCalls" below +typedef struct tagSYSCALLDEF { + LPSTR szNtApiNameA; + SIZE_T nOffset; +} SYSCALLDEF, *LPSYSCALLDEF; + +//-------------------------------- + +//NOTE: See "SetApiResolverCallback" below +typedef LPVOID (__stdcall *lpfnInternalApiResolver)(__in_z LPCSTR szApiNameA, __in LPVOID lpUserParam); + +//-------------------------------- + +HINSTANCE GetModuleBaseAddress(__in_z LPCWSTR szDllNameW); +LPVOID GetProcedureAddress(__in HINSTANCE hDll, __in LPCSTR szProcNameA); + +HINSTANCE GetRemoteModuleBaseAddress(__in HANDLE hProcess, __in_z LPCWSTR szDllNameW, __in BOOL bScanMappedImages); +LPVOID GetRemoteProcedureAddress(__in HANDLE hProcess, __in HINSTANCE hDll, __in_z LPCSTR szProcNameA); + +//-------------------------------- + +int sprintf_s(__out_z char *lpDest, __in size_t nMaxCount, __in_z const char *szFormatA, ...); +int vsnprintf(__out_z char *lpDest, __in size_t nMaxCount, __in_z const char *szFormatA, __in va_list lpArgList); + +//only on XP or later +int swprintf_s(__out_z wchar_t *lpDest, __in size_t nMaxCount, __in_z const wchar_t *szFormatW, ...); +int vsnwprintf(__out_z wchar_t *lpDest, __in size_t nMaxCount, __in_z const wchar_t *szFormatW, __in va_list lpArgList); + +//-------------------------------- + +//Returns a PROCESSOR_ARCHITECTURE_xxx value or -1 on error. +LONG GetProcessorArchitecture(); + +HANDLE OpenProcess(__in DWORD dwDesiredAccess, __in BOOL bInheritHandle, __in DWORD dwProcessId); +HANDLE OpenThread(__in DWORD dwDesiredAccess, __in BOOL bInheritHandle, __in DWORD dwThreadId); + +LONG GetProcessPlatform(__in HANDLE hProcess); + +SIZE_T ReadMem(__in HANDLE hProcess, __out LPVOID lpDest, __in LPVOID lpSrc, __in SIZE_T nBytesCount); +BOOL WriteMem(__in HANDLE hProcess, __out LPVOID lpDest, __in LPVOID lpSrc, __in SIZE_T nBytesCount); + +LONG GetThreadPriority(__in HANDLE hThread, __out int *lpnPriority); +LONG SetThreadPriority(__in HANDLE hThread, __in int nPriority); + +DWORD GetCurrentThreadId(); +DWORD GetCurrentProcessId(); + +HANDLE GetProcessHeap(); +LPVOID MemAlloc(__in SIZE_T nSize); +VOID MemFree(__in LPVOID lpPtr); + +VOID MemSet(__out void *lpDest, __in int nVal, __in SIZE_T nCount); +VOID MemCopy(__out void *lpDest, __in const void *lpSrc, __in SIZE_T nCount); +SIZE_T TryMemCopy(__out void *lpDest, __in const void *lpSrc, __in SIZE_T nCount); +VOID MemMove(__out void *lpDest, __in const void *lpSrc, __in SIZE_T nCount); +int MemCompare(__in const void *lpBuf1, __in const void *lpBuf2, __in SIZE_T nCount); + +//-------------------------------- + +VOID DebugPrint(__in LPCSTR szFormatA, ...); +VOID DebugVPrint(__in LPCSTR szFormatA, __in va_list argptr); + +//-------------------------------- + +SIZE_T GetInstructionLength(__in LPVOID lpAddr, __in SIZE_T nSize, __in BYTE nPlatformBits, + __out_opt BOOL *lpbIsMemOp=NULL, __out_z_opt LPSTR szBufA=NULL, __in SIZE_T nBufLen=0); + +//NOTE: When NktHookLib is initialized, it tries to locate needed ntdll's apis by scanning process' modules. +// If you want to override an api call, use this method to set the resolver address. LPVOID returned by +// the callback must have the same definition and calling convention than the one in ntdll. Return NULL +// if you want NktHookLib to use the real ntdll api. +VOID SetInternalApiResolverCallback(__in lpfnInternalApiResolver fnInternalApiResolver, __in LPVOID lpUserParam); + +//This function generates a relocatable byte code with a copy of the original SysCall routine for each passes +//ntdll api. The code is created based on the original ntdll.dll image file on disk located on System32 or SysWow64, +//depending on the target platform. +// +//Useful for doing direct calls to low level apis bypassing third party hooks (like Chrome navigator does). Also, you +//can pass the generated code to another process. You can generate the code with this method, pass it to another +//process and then use SetApiResolverCallback above. +// +//NOTE: Not all NtXXX apis are SysCalls. Trying to generate code for a non-syscall api may generate an unexpected +// behavior. +// If 'lpCode' is NULL, the needed space is returned. Although syscalls uses less than 32 bytes, a maximum of 256 +// bytes are supported for each requested api. You can safety allocate a block of 256*nDefsCount bytes to hold +// the generated code. +DWORD BuildNtSysCalls(__in LPSYSCALLDEF lpDefs, __in SIZE_T nDefsCount, __in SIZE_T nPlatform, + __out_opt LPVOID lpCode, __out SIZE_T *lpnCodeSize); + +//-------------------------------- + +//NOTE: Return 0xFFFFFFFF if remote thread is not accessible +DWORD GetWin32LastError(__in_opt HANDLE hThread=NULL); +BOOL SetWin32LastError(__in DWORD dwErrorCode, __in_opt HANDLE hThread=NULL); + +//-------------------------------- + +BOOL GetOsVersion(__out_opt LPDWORD lpdwVerMajor=NULL, __out_opt LPDWORD lpdwVerMinor=NULL, + __out_opt LPDWORD lpdwBuildNumber=NULL); + +//-------------------------------- + +//NOTE: CreateProcessWithDllW and related functions returns the Win32 error code directly. NOERROR => Success. +// +// If "szDllNameW" string ends with 'x86.dll', 'x64.dll', '32.dll', '64.dll', the dll name will be adjusted +// in order to match the process platform. I.e.: "mydll_x86.dll" will become "mydll_x64.dll" on 64-bit processes. +DWORD CreateProcessWithDllW(__in_z_opt LPCWSTR lpApplicationName, __inout_z_opt LPWSTR lpCommandLine, + __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes, + __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes, __in BOOL bInheritHandles, + __in DWORD dwCreationFlags, __in_z_opt LPCWSTR lpEnvironment, + __in_z_opt LPCWSTR lpCurrentDirectory, __in LPSTARTUPINFOW lpStartupInfo, + __out LPPROCESS_INFORMATION lpProcessInformation, __in_z LPCWSTR szDllNameW, + __in_opt HANDLE hSignalCompleted=NULL, __in_z_opt LPCSTR szInitFunctionA=NULL, + __in_opt LPVOID lpInitFuncParams=NULL, __in_opt ULONG nInitFuncParamsSize=0); + +DWORD CreateProcessWithLogonAndDllW(__in_z LPCWSTR lpUsername, __in_z_opt LPCWSTR lpDomain, __in_z LPCWSTR lpPassword, + __in DWORD dwLogonFlags, __in_opt LPCWSTR lpApplicationName, + __inout_opt LPWSTR lpCommandLine, __in DWORD dwCreationFlags, + __in_z_opt LPCWSTR lpEnvironment, __in_z_opt LPCWSTR lpCurrentDirectory, + __in LPSTARTUPINFOW lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation, + __in_z LPCWSTR szDllNameW, __in_opt HANDLE hSignalCompleted=NULL, + __in_z_opt LPCSTR szInitFunctionA=NULL, __in_opt LPVOID lpInitFuncParams=NULL, + __in_opt ULONG nInitFuncParamsSize=0); + +DWORD CreateProcessWithTokenAndDllW(__in HANDLE hToken, __in DWORD dwLogonFlags, __in_z_opt LPCWSTR lpApplicationName, + __inout_opt LPWSTR lpCommandLine, __in DWORD dwCreationFlags, + __in_z_opt LPCWSTR lpEnvironment, __in_z_opt LPCWSTR lpCurrentDirectory, + __in LPSTARTUPINFOW lpStartupInfo, __out LPPROCESS_INFORMATION lpProcessInformation, + __in_z LPCWSTR szDllNameW, __in_opt HANDLE hSignalCompleted=NULL, + __in_z_opt LPCSTR szInitFunctionA=NULL, __in_opt LPVOID lpInitFuncParams=NULL, + __in_opt ULONG nInitFuncParamsSize=0); + +DWORD InjectDllByPidW(__in DWORD dwPid, __in_z LPCWSTR szDllNameW, __in_z_opt LPCSTR szInitFunctionA=NULL, + __in_opt DWORD dwProcessInitWaitTimeoutMs=5000, __out_opt LPHANDLE lphInjectorThread=NULL, + __in_opt LPVOID lpInitFuncParams=NULL, __in_opt ULONG nInitFuncParamsSize=0); + +DWORD InjectDllByHandleW(__in HANDLE hProcess, __in_z LPCWSTR szDllNameW, __in_z_opt LPCSTR szInitFunctionA=NULL, + __in_opt DWORD dwProcessInitWaitTimeoutMs=5000, __out_opt LPHANDLE lphInjectorThread=NULL, + __in_opt LPVOID lpInitFuncParams=NULL, __in_opt ULONG nInitFuncParamsSize=0); + +} //NktHookLibHelpers + +//----------------------------------------------------------- + +#endif //_NKTHOOKLIB diff --git a/libs/windows/lib/x64/NktHookLib.lib b/libs/windows/lib/x64/NktHookLib.lib new file mode 100644 index 00000000..64cbaa70 Binary files /dev/null and b/libs/windows/lib/x64/NktHookLib.lib differ diff --git a/libs/windows/lib/x64/NktHookLib.pdb b/libs/windows/lib/x64/NktHookLib.pdb new file mode 100644 index 00000000..09382cda Binary files /dev/null and b/libs/windows/lib/x64/NktHookLib.pdb differ diff --git a/libs/windows/lib/x86/NktHookLib.lib b/libs/windows/lib/x86/NktHookLib.lib new file mode 100644 index 00000000..279c3395 Binary files /dev/null and b/libs/windows/lib/x86/NktHookLib.lib differ diff --git a/libs/windows/lib/x86/NktHookLib.pdb b/libs/windows/lib/x86/NktHookLib.pdb new file mode 100644 index 00000000..b1cc3815 Binary files /dev/null and b/libs/windows/lib/x86/NktHookLib.pdb differ diff --git a/moonlight-qt.pro b/moonlight-qt.pro index 962e6b72..8a4ee680 100644 --- a/moonlight-qt.pro +++ b/moonlight-qt.pro @@ -8,6 +8,10 @@ SUBDIRS = \ # Build the dependencies in parallel before the final app app.depends = qmdnsengine moonlight-common-c soundio h264bitstream +win32 { + SUBDIRS += AntiHooking + app.depends += AntiHooking +} # Support debug and release builds from command line for CI CONFIG += debug_and_release diff --git a/scripts/generate-installers.bat b/scripts/generate-installers.bat index bc69de53..4df11c2c 100644 --- a/scripts/generate-installers.bat +++ b/scripts/generate-installers.bat @@ -92,6 +92,10 @@ echo Copying DLL dependencies copy %SOURCE_ROOT%\libs\windows\lib\%ARCH%\*.dll %DEPLOY_FOLDER% if !ERRORLEVEL! NEQ 0 goto Error +echo Copying AntiHooking.dll +copy %BUILD_FOLDER%\AntiHooking\%BUILD_CONFIG%\AntiHooking.dll %DEPLOY_FOLDER% +if !ERRORLEVEL! NEQ 0 goto Error + echo Copying GC mapping list copy %SOURCE_ROOT%\app\SDL_GameControllerDB\gamecontrollerdb.txt %DEPLOY_FOLDER% if !ERRORLEVEL! NEQ 0 goto Error