From 66ae32402c839a53814e79f2b3ec1dc953918199 Mon Sep 17 00:00:00 2001 From: George Hahn Date: Mon, 12 May 2014 13:43:05 -0400 Subject: [PATCH] DPIMangler v1 - hook SetProcessDPIAware and magic calls to it into the ether --- build/MinHook.vcxproj | 172 +++++++++++++++++++++++++++++++ build/MinHookVC12.sln | 8 +- build/libMinHook.vcxproj | 142 ++++++++++++++++++++++++- build/libMinHook.vcxproj.filters | 4 +- dll_resources/MinHook.h | 129 +++++++++++++++++++++++ dll_resources/MinHook.rc | 2 +- dll_resources/dllmain.cpp | 69 ++++++++++++- 7 files changed, 518 insertions(+), 8 deletions(-) create mode 100644 dll_resources/MinHook.h diff --git a/build/MinHook.vcxproj b/build/MinHook.vcxproj index a9004b9..a067bcd 100644 --- a/build/MinHook.vcxproj +++ b/build/MinHook.vcxproj @@ -17,11 +17,28 @@ Release x64 + + x64 Debug + Win32 + + + x64 Debug + x64 + + + x86 Debug + Win32 + + + x86 Debug + x64 + {CA4EE302-D012-4826-86D6-80D23641AB4E} MinHook Win32Proj + DPIMangler @@ -35,6 +52,16 @@ Unicode v120_xp + + DynamicLibrary + Unicode + v120_xp + + + DynamicLibrary + Unicode + v120_xp + DynamicLibrary Unicode @@ -46,6 +73,16 @@ Unicode v120_xp + + DynamicLibrary + Unicode + v120_xp + + + DynamicLibrary + Unicode + v120_xp + @@ -55,33 +92,69 @@ + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 $(SolutionDir)\..\bin\ + $(SolutionDir)\..\bin\ + $(SolutionDir)\..\bin\ $(SolutionDir)\..\bin\ $(SolutionDir)\..\bin\ + $(SolutionDir)\..\bin\ + $(SolutionDir)\..\bin\ $(SolutionDir)\..\bin\ $(Configuration)\$(ProjectName)\ + $(Configuration)\$(ProjectName)\ + $(Configuration)\$(ProjectName)\ true + true + true $(Configuration)\$(ProjectName)\ false $(Platform)\$(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\$(ProjectName)\ true + true + true $(Platform)\$(Configuration)\$(ProjectName)\ false AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + AllRules.ruleset @@ -89,9 +162,13 @@ $(ProjectName).x86 + $(ProjectName).x86 + $(ProjectName).x86 $(ProjectName).x86 $(ProjectName).x64 $(ProjectName).x64 + $(ProjectName).x64 + $(ProjectName).x64 @@ -113,6 +190,46 @@ MachineX86 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + Use + Level3 + EditAndContinue + NoExtensions + + + ..\dll_resources\MinHook.def + true + Windows + 0x68000000 + MachineX86 + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + Use + Level3 + EditAndContinue + NoExtensions + + + ..\dll_resources\MinHook.def + true + Windows + 0x68000000 + MachineX86 + + MaxSpeed @@ -156,6 +273,48 @@ MachineX64 + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + Use + Level3 + ProgramDatabase + + + ..\dll_resources\MinHook.def + true + Windows + MachineX64 + + + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + Use + Level3 + ProgramDatabase + + + ..\dll_resources\MinHook.def + true + Windows + MachineX64 + + X64 @@ -184,10 +343,22 @@ + + + + false + false + false + + + + false + false + false false @@ -203,6 +374,7 @@ + diff --git a/build/MinHookVC12.sln b/build/MinHookVC12.sln index f3ea123..1cb1232 100644 --- a/build/MinHookVC12.sln +++ b/build/MinHookVC12.sln @@ -1,11 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 +VisualStudioVersion = 12.0.30324.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMinHook", "libMinHook.vcxproj", "{65021938-D251-46FA-BC3D-85C385D4C06D}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MinHook", "MinHook.vcxproj", "{CA4EE302-D012-4826-86D6-80D23641AB4E}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DPIMangler", "MinHook.vcxproj", "{CA4EE302-D012-4826-86D6-80D23641AB4E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -25,8 +25,8 @@ Global {65021938-D251-46FA-BC3D-85C385D4C06D}.Release|x64.Build.0 = Release|x64 {CA4EE302-D012-4826-86D6-80D23641AB4E}.Debug|Win32.ActiveCfg = Debug|Win32 {CA4EE302-D012-4826-86D6-80D23641AB4E}.Debug|Win32.Build.0 = Debug|Win32 - {CA4EE302-D012-4826-86D6-80D23641AB4E}.Debug|x64.ActiveCfg = Debug|Win32 - {CA4EE302-D012-4826-86D6-80D23641AB4E}.Debug|x64.Build.0 = Debug|Win32 + {CA4EE302-D012-4826-86D6-80D23641AB4E}.Debug|x64.ActiveCfg = Debug|x64 + {CA4EE302-D012-4826-86D6-80D23641AB4E}.Debug|x64.Build.0 = Debug|x64 {CA4EE302-D012-4826-86D6-80D23641AB4E}.Release|Win32.ActiveCfg = Release|Win32 {CA4EE302-D012-4826-86D6-80D23641AB4E}.Release|Win32.Build.0 = Release|Win32 {CA4EE302-D012-4826-86D6-80D23641AB4E}.Release|x64.ActiveCfg = Release|x64 diff --git a/build/libMinHook.vcxproj b/build/libMinHook.vcxproj index 0460d86..9209ebc 100644 --- a/build/libMinHook.vcxproj +++ b/build/libMinHook.vcxproj @@ -17,6 +17,22 @@ Release x64 + + x64 Debug + Win32 + + + x64 Debug + x64 + + + x86 Debug + Win32 + + + x86 Debug + x64 + {65021938-D251-46FA-BC3D-85C385D4C06D} @@ -35,6 +51,16 @@ Unicode v120_xp + + StaticLibrary + Unicode + v120_xp + + + StaticLibrary + Unicode + v120_xp + StaticLibrary Unicode @@ -46,6 +72,16 @@ Unicode v120_xp + + StaticLibrary + Unicode + v120_xp + + + StaticLibrary + Unicode + v120_xp + @@ -55,29 +91,61 @@ + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 $(SolutionDir)\..\lib\ + $(SolutionDir)\..\lib\ + $(SolutionDir)\..\lib\ $(Configuration)\$(ProjectName)\ + $(Configuration)\$(ProjectName)\ + $(Configuration)\$(ProjectName)\ $(SolutionDir)\..\lib\ + $(SolutionDir)\..\lib\ + $(SolutionDir)\..\lib\ $(Platform)\$(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(Platform)\$(Configuration)\$(ProjectName)\ $(SolutionDir)\..\lib\ $(Configuration)\$(ProjectName)\ $(SolutionDir)\..\lib\ $(Platform)\$(Configuration)\$(ProjectName)\ AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + AllRules.ruleset @@ -85,9 +153,13 @@ $(ProjectName).x86 + $(ProjectName).x86 + $(ProjectName).x86 $(ProjectName).x86 $(ProjectName).x64 $(ProjectName).x64 + $(ProjectName).x64 + $(ProjectName).x64 @@ -105,6 +177,38 @@ + + + Disabled + $(ProjectDir)\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + NoExtensions + + + + + + Disabled + $(ProjectDir)\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + NoExtensions + + + X64 @@ -123,6 +227,42 @@ + + + X64 + + + Disabled + $(ProjectDir)\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + + + + X64 + + + Disabled + $(ProjectDir)\..\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + MaxSpeed @@ -167,6 +307,7 @@ + @@ -176,7 +317,6 @@ - diff --git a/build/libMinHook.vcxproj.filters b/build/libMinHook.vcxproj.filters index 3cf0b3e..564fef5 100644 --- a/build/libMinHook.vcxproj.filters +++ b/build/libMinHook.vcxproj.filters @@ -68,7 +68,9 @@ src\Header Files - + + src + diff --git a/dll_resources/MinHook.h b/dll_resources/MinHook.h new file mode 100644 index 0000000..cfc602c --- /dev/null +++ b/dll_resources/MinHook.h @@ -0,0 +1,129 @@ +/* + * MinHook - Minimalistic API Hook Library + * Copyright (C) 2009 Tsuda Kageyu. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +// MinHook Error Codes. +typedef enum MH_STATUS +{ + // Unknown error. Should not be returned. + MH_UNKNOWN = -1, + + // Successful. + MH_OK = 0, + + // MinHook is already initialized. + MH_ERROR_ALREADY_INITIALIZED, + + // MinHook is not initialized yet, or already uninitialized. + MH_ERROR_NOT_INITIALIZED, + + // The hook for the specified target function is already created. + MH_ERROR_ALREADY_CREATED, + + // The hook for the specified target function is not created yet. + MH_ERROR_NOT_CREATED, + + // The hook for the specified target function is already enabled. + MH_ERROR_ENABLED, + + // The hook for the specified target function is not enabled yet, or already disabled. + MH_ERROR_DISABLED, + + // The specified pointer is invalid. It points the address of non-allocated and/or non-executable region. + MH_ERROR_NOT_EXECUTABLE, + + // The specified target function cannot be hooked. + MH_ERROR_UNSUPPORTED_FUNCTION, + + // Failed to allocate memory. + MH_ERROR_MEMORY_ALLOC, + + // Failed to change the memory protection. + MH_ERROR_MEMORY_PROTECT +} +MH_STATUS; + +// Can be passed as a parameter to MH_EnableHook, MH_DisableHook, MH_QueueEnableHook or MH_QueueDisableHook. +#define MH_ALL_HOOKS NULL + +#if defined __cplusplus +extern "C" { +#endif + + // Initialize the MinHook library. + MH_STATUS WINAPI MH_Initialize(); + + // Uninitialize the MinHook library. + MH_STATUS WINAPI MH_Uninitialize(); + + // Creates the Hook for the specified target function, in disabled state. + // Parameters: + // pTarget [in] A pointer to the target function, which will be overridden by the detour function. + // pDetour [in] A pointer to the detour function, which will override the target function. + // ppOriginal [out] A pointer to the trampoline function, which will be used to call the original target function. + MH_STATUS WINAPI MH_CreateHook(void* pTarget, void* const pDetour, void** ppOriginal); + + // Removes the already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + MH_STATUS WINAPI MH_RemoveHook(void* pTarget); + + // Enables the already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are enabled in one go. + MH_STATUS WINAPI MH_EnableHook(void* pTarget); + + // Disables the already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are disabled in one go. + MH_STATUS WINAPI MH_DisableHook(void* pTarget); + + // Queues to enable the already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are queued to be enabled. + MH_STATUS WINAPI MH_QueueEnableHook(void* pTarget); + + // Queues to disable the already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + // If this parameter is MH_ALL_HOOKS, all created hooks are queued to be disabled. + MH_STATUS WINAPI MH_QueueDisableHook(void* pTarget); + + // Applies all queued changes in one go. + MH_STATUS WINAPI MH_ApplyQueued(); + +#if defined __cplusplus +} +#endif + diff --git a/dll_resources/MinHook.rc b/dll_resources/MinHook.rc index e9d9d74..5bd854d 100644 --- a/dll_resources/MinHook.rc +++ b/dll_resources/MinHook.rc @@ -7,7 +7,7 @@ // // Generated from the TEXTINCLUDE 2 resource. // -#include "afxres.h" +#include "windows.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS diff --git a/dll_resources/dllmain.cpp b/dll_resources/dllmain.cpp index 6822b41..db84db0 100644 --- a/dll_resources/dllmain.cpp +++ b/dll_resources/dllmain.cpp @@ -1,7 +1,74 @@ #include +#include "MinHook.h" + +bool initialized = false; + +typedef int (WINAPI *SETPROCESSDPIAWARE)(VOID); +typedef int (WINAPI *SETPROCESSDPIAWARENESS)(VOID); // TODO: For W8.1 users, hook SetProcessDpiAwareness and nuke it too + +// Pointer for calling original SETPROCESSDPIAWARE. +SETPROCESSDPIAWARE fpSetProcessDPIAware = NULL; + +// New function which overrides SetProcessDPIAware. +int WINAPI NukeSetProcessDPIAware() +{ + return 0; +} BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + if (initialized == true) + break; + + initialized = true; + + //MessageBoxW(NULL, L"Hooking", L"DPIMangler", MB_OK); + + // Initialize MinHook. + if (MH_Initialize() != MH_OK) + { + MessageBoxW(NULL, L"Initialization error", L"DPIMangler", MB_OK); + return 1; + } + + // Create a hook for SetProcessDPIAware, in disabled state. + if (MH_CreateHook(&SetProcessDPIAware, &NukeSetProcessDPIAware, + reinterpret_cast(&fpSetProcessDPIAware)) != MH_OK) + { + MessageBoxW(NULL, L"Error creating hook", L"DPIMangler", MB_OK); + return 1; + } + + // Enable the hook for SetProcessDPIAware. + if (MH_EnableHook(&SetProcessDPIAware) != MH_OK) + { + MessageBoxW(NULL, L"Error enabling hook", L"DPIMangler", MB_OK); + return 1; + } + + //MessageBoxW(NULL, L"Hooked...", L"DPIManger", MB_OK); + + break; + case DLL_PROCESS_DETACH: + + // Disable the hook for SetProcessDPIAware. + if (MH_DisableHook(&SetProcessDPIAware) != MH_OK) + { + MessageBoxW(NULL, L"Error disabling hook", L"DPIMangler", MB_OK); + return 1; + } + + // Uninitialize MinHook. + if (MH_Uninitialize() != MH_OK) + { + MessageBoxW(NULL, L"Error uninitializing minhook", L"DPIMangler", MB_OK); + return 1; + } + break; + } + return TRUE; } -