diff --git a/Include/MinHook.h b/Include/MinHook.h new file mode 100644 index 0000000..8760ea0 --- /dev/null +++ b/Include/MinHook.h @@ -0,0 +1,146 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2014 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER + * OR CONTRIBUTORS 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 + +#if !(defined _M_IX86) && !(defined _M_X64) + #error MinHook supports only x86 and x64 systems. +#endif + +#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 + +#ifdef __cplusplus +extern "C" { +#endif + + // Initialize the MinHook library. You must call this function EXACTLY ONCE + // at the beginning of your program. + MH_STATUS WINAPI MH_Initialize(VOID); + + // Uninitialize the MinHook library. You must call this function EXACTLY + // ONCE at the end of your program. + MH_STATUS WINAPI MH_Uninitialize(VOID); + + // Creates a 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. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); + + // Removes an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); + + // Enables an 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(LPVOID pTarget); + + // Disables an 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(LPVOID pTarget); + + // Queues to enable an 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(LPVOID pTarget); + + // Queues to disable an 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(LPVOID pTarget); + + // Applies all queued changes in one go. + MH_STATUS WINAPI MH_ApplyQueued(VOID); + +#ifdef __cplusplus +} +#endif + diff --git a/Include/dxwnd.h b/Include/dxwnd.h index ddeacf0..f6ff34a 100644 --- a/Include/dxwnd.h +++ b/Include/dxwnd.h @@ -166,6 +166,8 @@ #define NORMALIZEPERFCOUNT 0x00020000 // Normalize Performance Counter to a Performance Frequency of 1MHz #define HYBRIDMODE 0x00040000 // ????? #define GDICOLORCONV 0x00080000 // do color conversion using GDI +#define INJECTSON 0x00100000 // when starting a son process, inject dxwnd.dll at the beginning of execution +#define ENABLESONHOOK 0x00200000 // forward hooking capability to son processes // logging Tflags DWORD: #define OUTTRACE 0x00000001 // enables tracing to dxwnd.log in general @@ -232,6 +234,7 @@ typedef struct int TimeShift; short CursorX, CursorY; PALETTEENTRY Palette[256]; + BOOL AllowMultiTask; } DXWNDSTATUS; extern DXWNDSTATUS DxWndStatus; @@ -244,6 +247,7 @@ int GetHookStatus(DXWNDSTATUS *); DXWNDSTATUS *GetHookInfo(); void HookInit(TARGETMAP *, HWND); +char *GetDxWndPath(); void *SetHook(void *, void *); void SetHook(void *, void *, void **, char *); void OutTrace(const char *, ...); diff --git a/MinHook_13_src/AUTHORS.txt b/MinHook_13_src/AUTHORS.txt new file mode 100644 index 0000000..ebef1a6 --- /dev/null +++ b/MinHook_13_src/AUTHORS.txt @@ -0,0 +1,8 @@ +Tsuda Kageyu + Creator, maintainer + +Michael Maltsev + Added "Queue" functions. A lot of bug fixes. + +Andrey Unis + Rewrote the hook engine in plain C. diff --git a/MinHook_13_src/LICENSE.txt b/MinHook_13_src/LICENSE.txt new file mode 100644 index 0000000..fa1acc1 --- /dev/null +++ b/MinHook_13_src/LICENSE.txt @@ -0,0 +1,81 @@ +MinHook - The Minimalistic API Hooking Library for x64/x86 +Copyright (C) 2009-2014 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. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"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 COPYRIGHT HOLDER +OR CONTRIBUTORS 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. + +================================================================================ +Portions of this software are Copyright (c) 2008-2009, Vyacheslav Patkov. +================================================================================ +Hacker Disassembler Engine 32 C +Copyright (c) 2008-2009, Vyacheslav Patkov. +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. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"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 REGENTS OR +CONTRIBUTORS 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. + +------------------------------------------------------------------------------- +Hacker Disassembler Engine 64 C +Copyright (c) 2008-2009, Vyacheslav Patkov. +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. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"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 REGENTS OR +CONTRIBUTORS 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. diff --git a/MinHook_13_src/build/VC10/MinHook.vcxproj b/MinHook_13_src/build/VC10/MinHook.vcxproj new file mode 100644 index 0000000..3944d80 --- /dev/null +++ b/MinHook_13_src/build/VC10/MinHook.vcxproj @@ -0,0 +1,189 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {027FAC75-3FDB-4044-8DD0-BC297BD4C461} + MinHook + Win32Proj + + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + DynamicLibrary + Unicode + true + + + DynamicLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + true + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + true + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + $(ProjectName).x86 + $(ProjectName).x86 + $(ProjectName).x64 + $(ProjectName).x64 + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + + + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + MachineX86 + $(SolutionDir)lib\$(Configuration)\libMinHook.x86.lib;%(AdditionalDependencies) + + + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + + + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + MachineX64 + $(SolutionDir)lib\$(Configuration)\libMinHook.x64.lib;%(AdditionalDependencies) + + + + + MinSpace + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + + + false + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + true + true + MachineX86 + $(SolutionDir)lib\$(Configuration)\libMinHook.x86.lib;%(AdditionalDependencies) + true + .CRT=.text + + + + + X64 + + + MinSpace + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + + + false + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + true + true + MachineX64 + $(SolutionDir)lib\$(Configuration)\libMinHook.x64.lib;%(AdditionalDependencies) + true + .CRT=.text + + + + + + + + + + + + \ No newline at end of file diff --git a/MinHook_13_src/build/VC10/MinHookVC10.sln b/MinHook_13_src/build/VC10/MinHookVC10.sln new file mode 100644 index 0000000..dcc1d5c --- /dev/null +++ b/MinHook_13_src/build/VC10/MinHookVC10.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMinHook", "libMinHook.vcxproj", "{F142A341-5EE0-442D-A15F-98AE9B48DBAE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MinHook", "MinHook.vcxproj", "{027FAC75-3FDB-4044-8DD0-BC297BD4C461}" + ProjectSection(ProjectDependencies) = postProject + {F142A341-5EE0-442D-A15F-98AE9B48DBAE} = {F142A341-5EE0-442D-A15F-98AE9B48DBAE} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Win32.Build.0 = Debug|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.ActiveCfg = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.Build.0 = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Win32.ActiveCfg = Release|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Win32.Build.0 = Release|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.ActiveCfg = Release|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.Build.0 = Release|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|Win32.ActiveCfg = Debug|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|Win32.Build.0 = Debug|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|x64.ActiveCfg = Debug|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|x64.Build.0 = Debug|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|Win32.ActiveCfg = Release|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|Win32.Build.0 = Release|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|x64.ActiveCfg = Release|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MinHook_13_src/build/VC10/libMinHook.vcxproj b/MinHook_13_src/build/VC10/libMinHook.vcxproj new file mode 100644 index 0000000..eb7cb9a --- /dev/null +++ b/MinHook_13_src/build/VC10/libMinHook.vcxproj @@ -0,0 +1,172 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F142A341-5EE0-442D-A15F-98AE9B48DBAE} + libMinHook + Win32Proj + + + + StaticLibrary + Unicode + true + + + StaticLibrary + Unicode + + + StaticLibrary + Unicode + true + + + StaticLibrary + Unicode + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(ProjectName).x86 + $(ProjectName).x86 + $(ProjectName).x64 + $(ProjectName).x64 + + + + Disabled + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + Level3 + + + false + + + + + + X64 + + + Disabled + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + Level3 + + + false + + + + + + MinSpace + true + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + false + MultiThreaded + true + Level3 + + + true + AnySuitable + + + + + + X64 + + + MinSpace + true + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + false + MultiThreaded + true + Level3 + + + true + AnySuitable + + + + + + + true + true + + + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MinHook_13_src/build/VC10/libMinHook.vcxproj.filters b/MinHook_13_src/build/VC10/libMinHook.vcxproj.filters new file mode 100644 index 0000000..f2d1d97 --- /dev/null +++ b/MinHook_13_src/build/VC10/libMinHook.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + Source Files + + + Source Files + + + Source Files + + + HDE + + + HDE + + + + + Header Files + + + Header Files + + + + HDE + + + HDE + + + HDE + + + HDE + + + HDE + + + + + {9d24b740-be2e-4cfd-b9a4-340a50946ee9} + + + {76381bc7-2863-4cc5-aede-926ec2c506e4} + + + {56ddb326-6179-430d-ae19-e13bfd767bfa} + + + \ No newline at end of file diff --git a/MinHook_13_src/build/VC11/MinHook.vcxproj b/MinHook_13_src/build/VC11/MinHook.vcxproj new file mode 100644 index 0000000..4c0e212 --- /dev/null +++ b/MinHook_13_src/build/VC11/MinHook.vcxproj @@ -0,0 +1,189 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {027FAC75-3FDB-4044-8DD0-BC297BD4C461} + MinHook + Win32Proj + + + + DynamicLibrary + Unicode + true + v110_xp + + + DynamicLibrary + Unicode + v110_xp + + + DynamicLibrary + Unicode + true + v110_xp + + + DynamicLibrary + Unicode + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + true + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + true + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + $(ProjectName).x86 + $(ProjectName).x86 + $(ProjectName).x64 + $(ProjectName).x64 + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + None + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + MachineX86 + $(SolutionDir)lib\$(Configuration)\libMinHook.x86.lib;%(AdditionalDependencies) + + + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + None + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + MachineX64 + $(SolutionDir)lib\$(Configuration)\libMinHook.x64.lib;%(AdditionalDependencies) + + + + + MinSpace + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + None + false + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + true + true + MachineX86 + $(SolutionDir)lib\$(Configuration)\libMinHook.x86.lib;%(AdditionalDependencies) + true + .CRT=.text + + + + + X64 + + + MinSpace + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + None + false + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + true + true + MachineX64 + $(SolutionDir)lib\$(Configuration)\libMinHook.x64.lib;%(AdditionalDependencies) + true + .CRT=.text + + + + + + + + + + + + \ No newline at end of file diff --git a/MinHook_13_src/build/VC11/MinHookVC11.sln b/MinHook_13_src/build/VC11/MinHookVC11.sln new file mode 100644 index 0000000..5b56553 --- /dev/null +++ b/MinHook_13_src/build/VC11/MinHookVC11.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMinHook", "libMinHook.vcxproj", "{F142A341-5EE0-442D-A15F-98AE9B48DBAE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MinHook", "MinHook.vcxproj", "{027FAC75-3FDB-4044-8DD0-BC297BD4C461}" + ProjectSection(ProjectDependencies) = postProject + {F142A341-5EE0-442D-A15F-98AE9B48DBAE} = {F142A341-5EE0-442D-A15F-98AE9B48DBAE} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Win32.Build.0 = Debug|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.ActiveCfg = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.Build.0 = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Win32.ActiveCfg = Release|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Win32.Build.0 = Release|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.ActiveCfg = Release|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.Build.0 = Release|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|Win32.ActiveCfg = Debug|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|Win32.Build.0 = Debug|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|x64.ActiveCfg = Debug|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|x64.Build.0 = Debug|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|Win32.ActiveCfg = Release|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|Win32.Build.0 = Release|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|x64.ActiveCfg = Release|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MinHook_13_src/build/VC11/libMinHook.vcxproj b/MinHook_13_src/build/VC11/libMinHook.vcxproj new file mode 100644 index 0000000..018886f --- /dev/null +++ b/MinHook_13_src/build/VC11/libMinHook.vcxproj @@ -0,0 +1,172 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F142A341-5EE0-442D-A15F-98AE9B48DBAE} + libMinHook + Win32Proj + + + + StaticLibrary + Unicode + true + v110_xp + + + StaticLibrary + Unicode + v110_xp + + + StaticLibrary + Unicode + true + v110_xp + + + StaticLibrary + Unicode + v110_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(ProjectName).x86 + $(ProjectName).x86 + $(ProjectName).x64 + $(ProjectName).x64 + + + + Disabled + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + Level3 + None + NoExtensions + + + + + + X64 + + + Disabled + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + Level3 + None + + + + + + MinSpace + true + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + false + MultiThreaded + true + Level3 + None + true + AnySuitable + NoExtensions + + + + + + X64 + + + MinSpace + true + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + false + MultiThreaded + true + Level3 + None + true + AnySuitable + + + + + + + true + true + + + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MinHook_13_src/build/VC11/libMinHook.vcxproj.filters b/MinHook_13_src/build/VC11/libMinHook.vcxproj.filters new file mode 100644 index 0000000..f2d1d97 --- /dev/null +++ b/MinHook_13_src/build/VC11/libMinHook.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + Source Files + + + Source Files + + + Source Files + + + HDE + + + HDE + + + + + Header Files + + + Header Files + + + + HDE + + + HDE + + + HDE + + + HDE + + + HDE + + + + + {9d24b740-be2e-4cfd-b9a4-340a50946ee9} + + + {76381bc7-2863-4cc5-aede-926ec2c506e4} + + + {56ddb326-6179-430d-ae19-e13bfd767bfa} + + + \ No newline at end of file diff --git a/MinHook_13_src/build/VC12/MinHook.vcxproj b/MinHook_13_src/build/VC12/MinHook.vcxproj new file mode 100644 index 0000000..40ec836 --- /dev/null +++ b/MinHook_13_src/build/VC12/MinHook.vcxproj @@ -0,0 +1,189 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {027FAC75-3FDB-4044-8DD0-BC297BD4C461} + MinHook + Win32Proj + + + + DynamicLibrary + Unicode + true + v120_xp + + + DynamicLibrary + Unicode + v120_xp + + + DynamicLibrary + Unicode + true + v120_xp + + + DynamicLibrary + Unicode + v120_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + true + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + true + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + $(SolutionDir)bin\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + false + $(ProjectName).x86 + $(ProjectName).x86 + $(ProjectName).x64 + $(ProjectName).x64 + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + None + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + MachineX86 + $(SolutionDir)lib\$(Configuration)\libMinHook.x86.lib;%(AdditionalDependencies) + + + + + X64 + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + + + Level3 + None + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + MachineX64 + $(SolutionDir)lib\$(Configuration)\libMinHook.x64.lib;%(AdditionalDependencies) + + + + + MinSpace + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + None + false + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + true + true + MachineX86 + $(SolutionDir)lib\$(Configuration)\libMinHook.x86.lib;%(AdditionalDependencies) + true + .CRT=.text + + + + + X64 + + + MinSpace + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MINHOOK_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + None + false + + + $(SolutionDir)..\..\dll_resources\MinHook.def + false + Windows + true + true + MachineX64 + $(SolutionDir)lib\$(Configuration)\libMinHook.x64.lib;%(AdditionalDependencies) + true + .CRT=.text + + + + + + + + + + + + \ No newline at end of file diff --git a/MinHook_13_src/build/VC12/MinHookVC12.sln b/MinHook_13_src/build/VC12/MinHookVC12.sln new file mode 100644 index 0000000..cfd928b --- /dev/null +++ b/MinHook_13_src/build/VC12/MinHookVC12.sln @@ -0,0 +1,41 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30501.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMinHook", "libMinHook.vcxproj", "{F142A341-5EE0-442D-A15F-98AE9B48DBAE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MinHook", "MinHook.vcxproj", "{027FAC75-3FDB-4044-8DD0-BC297BD4C461}" + ProjectSection(ProjectDependencies) = postProject + {F142A341-5EE0-442D-A15F-98AE9B48DBAE} = {F142A341-5EE0-442D-A15F-98AE9B48DBAE} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Win32.Build.0 = Debug|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.ActiveCfg = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.Build.0 = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Win32.ActiveCfg = Release|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Win32.Build.0 = Release|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.ActiveCfg = Release|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.Build.0 = Release|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|Win32.ActiveCfg = Debug|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|Win32.Build.0 = Debug|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|x64.ActiveCfg = Debug|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|x64.Build.0 = Debug|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|Win32.ActiveCfg = Release|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|Win32.Build.0 = Release|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|x64.ActiveCfg = Release|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MinHook_13_src/build/VC12/libMinHook.vcxproj b/MinHook_13_src/build/VC12/libMinHook.vcxproj new file mode 100644 index 0000000..7aa3e70 --- /dev/null +++ b/MinHook_13_src/build/VC12/libMinHook.vcxproj @@ -0,0 +1,174 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {F142A341-5EE0-442D-A15F-98AE9B48DBAE} + libMinHook + Win32Proj + + + + StaticLibrary + Unicode + true + v120_xp + + + StaticLibrary + Unicode + v120_xp + + + StaticLibrary + Unicode + true + v120_xp + + + StaticLibrary + Unicode + v120_xp + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(SolutionDir)lib\$(Configuration)\ + $(Platform)\$(Configuration)\$(ProjectName)\ + $(ProjectName).x86 + $(ProjectName).x86 + $(ProjectName).x64 + $(ProjectName).x64 + + + + Disabled + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + Level3 + None + NoExtensions + + + + + + X64 + + + Disabled + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + Level3 + None + NotSet + + + + + + MinSpace + true + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + false + MultiThreaded + true + Level3 + None + AnySuitable + CompileAsC + true + NoExtensions + + + + + + X64 + + + MinSpace + true + $(SolutionDir)..\..\include\;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + false + MultiThreaded + true + Level3 + None + true + AnySuitable + + + + + + + true + true + + + true + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MinHook_13_src/build/VC12/libMinHook.vcxproj.filters b/MinHook_13_src/build/VC12/libMinHook.vcxproj.filters new file mode 100644 index 0000000..f2d1d97 --- /dev/null +++ b/MinHook_13_src/build/VC12/libMinHook.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + Source Files + + + Source Files + + + Source Files + + + HDE + + + HDE + + + + + Header Files + + + Header Files + + + + HDE + + + HDE + + + HDE + + + HDE + + + HDE + + + + + {9d24b740-be2e-4cfd-b9a4-340a50946ee9} + + + {76381bc7-2863-4cc5-aede-926ec2c506e4} + + + {56ddb326-6179-430d-ae19-e13bfd767bfa} + + + \ No newline at end of file diff --git a/MinHook_13_src/build/VC9/MinHook.vcproj b/MinHook_13_src/build/VC9/MinHook.vcproj new file mode 100644 index 0000000..4bad257 --- /dev/null +++ b/MinHook_13_src/build/VC9/MinHook.vcproj @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MinHook_13_src/build/VC9/MinHookVC9.sln b/MinHook_13_src/build/VC9/MinHookVC9.sln new file mode 100644 index 0000000..869f5b6 --- /dev/null +++ b/MinHook_13_src/build/VC9/MinHookVC9.sln @@ -0,0 +1,39 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libMinHook", "libMinHook.vcproj", "{F142A341-5EE0-442D-A15F-98AE9B48DBAE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MinHook", "MinHook.vcproj", "{027FAC75-3FDB-4044-8DD0-BC297BD4C461}" + ProjectSection(ProjectDependencies) = postProject + {F142A341-5EE0-442D-A15F-98AE9B48DBAE} = {F142A341-5EE0-442D-A15F-98AE9B48DBAE} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Win32.ActiveCfg = Debug|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|Win32.Build.0 = Debug|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.ActiveCfg = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Debug|x64.Build.0 = Debug|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Win32.ActiveCfg = Release|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|Win32.Build.0 = Release|Win32 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.ActiveCfg = Release|x64 + {F142A341-5EE0-442D-A15F-98AE9B48DBAE}.Release|x64.Build.0 = Release|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|Win32.ActiveCfg = Debug|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|Win32.Build.0 = Debug|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|x64.ActiveCfg = Debug|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Debug|x64.Build.0 = Debug|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|Win32.ActiveCfg = Release|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|Win32.Build.0 = Release|Win32 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|x64.ActiveCfg = Release|x64 + {027FAC75-3FDB-4044-8DD0-BC297BD4C461}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/MinHook_13_src/build/VC9/MinHookVC9.suo b/MinHook_13_src/build/VC9/MinHookVC9.suo new file mode 100644 index 0000000..bf204d7 Binary files /dev/null and b/MinHook_13_src/build/VC9/MinHookVC9.suo differ diff --git a/MinHook_13_src/build/VC9/libMinHook.vcproj b/MinHook_13_src/build/VC9/libMinHook.vcproj new file mode 100644 index 0000000..ec1c9f7 --- /dev/null +++ b/MinHook_13_src/build/VC9/libMinHook.vcproj @@ -0,0 +1,410 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MinHook_13_src/dll_resources/MinHook.def b/MinHook_13_src/dll_resources/MinHook.def new file mode 100644 index 0000000..9bd1cd8 --- /dev/null +++ b/MinHook_13_src/dll_resources/MinHook.def @@ -0,0 +1,11 @@ +EXPORTS + MH_Initialize + MH_Uninitialize + + MH_CreateHook + MH_RemoveHook + MH_EnableHook + MH_DisableHook + MH_QueueEnableHook + MH_QueueDisableHook + MH_ApplyQueued diff --git a/MinHook_13_src/dll_resources/MinHook.rc b/MinHook_13_src/dll_resources/MinHook.rc new file mode 100644 index 0000000..c82d9a3 Binary files /dev/null and b/MinHook_13_src/dll_resources/MinHook.rc differ diff --git a/MinHook_13_src/include/MinHook.h b/MinHook_13_src/include/MinHook.h new file mode 100644 index 0000000..8760ea0 --- /dev/null +++ b/MinHook_13_src/include/MinHook.h @@ -0,0 +1,146 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2014 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER + * OR CONTRIBUTORS 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 + +#if !(defined _M_IX86) && !(defined _M_X64) + #error MinHook supports only x86 and x64 systems. +#endif + +#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 + +#ifdef __cplusplus +extern "C" { +#endif + + // Initialize the MinHook library. You must call this function EXACTLY ONCE + // at the beginning of your program. + MH_STATUS WINAPI MH_Initialize(VOID); + + // Uninitialize the MinHook library. You must call this function EXACTLY + // ONCE at the end of your program. + MH_STATUS WINAPI MH_Uninitialize(VOID); + + // Creates a 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. + // This parameter can be NULL. + MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal); + + // Removes an already created hook. + // Parameters: + // pTarget [in] A pointer to the target function. + MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget); + + // Enables an 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(LPVOID pTarget); + + // Disables an 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(LPVOID pTarget); + + // Queues to enable an 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(LPVOID pTarget); + + // Queues to disable an 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(LPVOID pTarget); + + // Applies all queued changes in one go. + MH_STATUS WINAPI MH_ApplyQueued(VOID); + +#ifdef __cplusplus +} +#endif + diff --git a/MinHook_13_src/src/HDE/hde32.c b/MinHook_13_src/src/HDE/hde32.c new file mode 100644 index 0000000..391bd79 --- /dev/null +++ b/MinHook_13_src/src/HDE/hde32.c @@ -0,0 +1,319 @@ +/* + * Hacker Disassembler Engine 32 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#include +#include "hde32.h" +#include "table32.h" + +unsigned int hde32_disasm(const void *code, hde32s *hs) +{ + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; + uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; + + // Avoid using memset to reduce the footprint. + __stosb((LPBYTE)hs, 0, sizeof(hde32s)); + + for (x = 16; x; x--) + switch (c = *p++) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } + pref_done: + + hs->flags = (uint32_t)pref << 23; + + if (!pref) + pref |= PRE_NONE; + + if ((hs->opcode = c) == 0x0f) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } else if (c >= 0xa0 && c <= 0xa3) { + if (pref & PRE_67) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht[ht[opcode / 4] + (opcode % 4)]; + + if (cflags == C_ERROR) { + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ((opcode & -3) == 0x24) + cflags++; + } + + x = 0; + if (cflags & C_GROUP) { + uint16_t t; + t = *(uint16_t *)(ht + (cflags & 0x7f)); + cflags = (uint8_t)t; + x = (uint8_t)(t >> 8); + } + + if (hs->opcode2) { + ht = hde32_table + DELTA_PREFIXES; + if (ht[ht[opcode / 4] + (opcode % 4)] & pref) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (cflags & C_MODRM) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = (c & 0x3f) >> 3; + + if (x && ((x << m_reg) & 0x80)) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { + uint8_t t = opcode - 0xd9; + if (m_mod == 3) { + ht = hde32_table + DELTA_FPU_MODRM + t*8; + t = ht[m_reg] << m_rm; + } else { + ht = hde32_table + DELTA_FPU_REG; + t = ht[t] << m_reg; + } + if (t & 0x80) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (pref & PRE_LOCK) { + if (m_mod == 3) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } else { + uint8_t *table_end, op = opcode; + if (hs->opcode2) { + ht = hde32_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } else { + ht = hde32_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for (; ht != table_end; ht++) + if (*ht++ == op) { + if (!((*ht << m_reg) & 0x80)) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if (hs->opcode2) { + switch (opcode) { + case 0x20: case 0x22: + m_mod = 3; + if (m_reg > 4 || m_reg == 1) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if (m_reg == 4 || m_reg == 5) + goto error_operand; + else + goto no_error_operand; + } + } else { + switch (opcode) { + case 0x8c: + if (m_reg > 5) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if (m_reg == 1 || m_reg > 5) + goto error_operand; + else + goto no_error_operand; + } + } + + if (m_mod == 3) { + uint8_t *table_end; + if (hs->opcode2) { + ht = hde32_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM; + } else { + ht = hde32_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for (; ht != table_end; ht += 2) + if (*ht++ == opcode) { + if (*ht++ & pref && !((*ht << m_reg) & 0x80)) + goto error_operand; + else + break; + } + goto no_error_operand; + } else if (hs->opcode2) { + switch (opcode) { + case 0x50: case 0xd7: case 0xf7: + if (pref & (PRE_NONE | PRE_66)) + goto error_operand; + break; + case 0xd6: + if (pref & (PRE_F2 | PRE_F3)) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if (m_reg <= 1) { + if (opcode == 0xf6) + cflags |= C_IMM8; + else if (opcode == 0xf7) + cflags |= C_IMM_P66; + } + + switch (m_mod) { + case 0: + if (pref & PRE_67) { + if (m_rm == 6) + disp_size = 2; + } else + if (m_rm == 5) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if (!(pref & PRE_67)) + disp_size <<= 1; + } + + if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = (c & 0x3f) >> 3; + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) + disp_size = 4; + } + + p--; + switch (disp_size) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *(uint16_t *)p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *(uint32_t *)p; + } + p += disp_size; + } else if (pref & PRE_LOCK) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if (cflags & C_IMM_P66) { + if (cflags & C_REL32) { + if (pref & PRE_66) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if (pref & PRE_66) { + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + } else { + hs->flags |= F_IMM32; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } + } + + if (cflags & C_IMM16) { + if (hs->flags & F_IMM32) { + hs->flags |= F_IMM16; + hs->disp.disp16 = *(uint16_t *)p; + } else if (hs->flags & F_IMM16) { + hs->flags |= F_2IMM16; + hs->disp.disp16 = *(uint16_t *)p; + } else { + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + } + p += 2; + } + if (cflags & C_IMM8) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if (cflags & C_REL32) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else if (cflags & C_REL8) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + + disasm_done: + + if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return (unsigned int)hs->len; +} diff --git a/MinHook_13_src/src/HDE/hde32.h b/MinHook_13_src/src/HDE/hde32.h new file mode 100644 index 0000000..1112450 --- /dev/null +++ b/MinHook_13_src/src/HDE/hde32.h @@ -0,0 +1,105 @@ +/* + * Hacker Disassembler Engine 32 + * Copyright (c) 2006-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde32.h: C/C++ header file + * + */ + +#ifndef _HDE32_H_ +#define _HDE32_H_ + +/* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_DISP8 0x00000020 +#define F_DISP16 0x00000040 +#define F_DISP32 0x00000080 +#define F_RELATIVE 0x00000100 +#define F_2IMM16 0x00000800 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_ANY 0x3f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde32s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { +#endif + +/* __cdecl */ +unsigned int hde32_disasm(const void *code, hde32s *hs); + +#ifdef __cplusplus +} +#endif + +#endif /* _HDE32_H_ */ diff --git a/MinHook_13_src/src/HDE/hde64.c b/MinHook_13_src/src/HDE/hde64.c new file mode 100644 index 0000000..68a5611 --- /dev/null +++ b/MinHook_13_src/src/HDE/hde64.c @@ -0,0 +1,330 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#include +#include "hde64.h" +#include "table64.h" + +unsigned int hde64_disasm(const void *code, hde64s *hs) +{ + uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0; + uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0; + uint8_t op64 = 0; + + // Avoid using memset to reduce the footprint. + __stosb((LPBYTE)hs, 0, sizeof(hde64s)); + + for (x = 16; x; x--) + switch (c = *p++) { + case 0xf3: + hs->p_rep = c; + pref |= PRE_F3; + break; + case 0xf2: + hs->p_rep = c; + pref |= PRE_F2; + break; + case 0xf0: + hs->p_lock = c; + pref |= PRE_LOCK; + break; + case 0x26: case 0x2e: case 0x36: + case 0x3e: case 0x64: case 0x65: + hs->p_seg = c; + pref |= PRE_SEG; + break; + case 0x66: + hs->p_66 = c; + pref |= PRE_66; + break; + case 0x67: + hs->p_67 = c; + pref |= PRE_67; + break; + default: + goto pref_done; + } + pref_done: + + hs->flags = (uint32_t)pref << 23; + + if (!pref) + pref |= PRE_NONE; + + if ((c & 0xf0) == 0x40) { + hs->flags |= F_PREFIX_REX; + if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8) + op64++; + hs->rex_r = (c & 7) >> 2; + hs->rex_x = (c & 3) >> 1; + hs->rex_b = c & 1; + if (((c = *p++) & 0xf0) == 0x40) { + opcode = c; + goto error_opcode; + } + } + + if ((hs->opcode = c) == 0x0f) { + hs->opcode2 = c = *p++; + ht += DELTA_OPCODES; + } else if (c >= 0xa0 && c <= 0xa3) { + op64++; + if (pref & PRE_67) + pref |= PRE_66; + else + pref &= ~PRE_66; + } + + opcode = c; + cflags = ht[ht[opcode / 4] + (opcode % 4)]; + + if (cflags == C_ERROR) { + error_opcode: + hs->flags |= F_ERROR | F_ERROR_OPCODE; + cflags = 0; + if ((opcode & -3) == 0x24) + cflags++; + } + + x = 0; + if (cflags & C_GROUP) { + uint16_t t; + t = *(uint16_t *)(ht + (cflags & 0x7f)); + cflags = (uint8_t)t; + x = (uint8_t)(t >> 8); + } + + if (hs->opcode2) { + ht = hde64_table + DELTA_PREFIXES; + if (ht[ht[opcode / 4] + (opcode % 4)] & pref) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (cflags & C_MODRM) { + hs->flags |= F_MODRM; + hs->modrm = c = *p++; + hs->modrm_mod = m_mod = c >> 6; + hs->modrm_rm = m_rm = c & 7; + hs->modrm_reg = m_reg = (c & 0x3f) >> 3; + + if (x && ((x << m_reg) & 0x80)) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + + if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { + uint8_t t = opcode - 0xd9; + if (m_mod == 3) { + ht = hde64_table + DELTA_FPU_MODRM + t*8; + t = ht[m_reg] << m_rm; + } else { + ht = hde64_table + DELTA_FPU_REG; + t = ht[t] << m_reg; + } + if (t & 0x80) + hs->flags |= F_ERROR | F_ERROR_OPCODE; + } + + if (pref & PRE_LOCK) { + if (m_mod == 3) { + hs->flags |= F_ERROR | F_ERROR_LOCK; + } else { + uint8_t *table_end, op = opcode; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_LOCK_OK; + table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; + } else { + ht = hde64_table + DELTA_OP_LOCK_OK; + table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; + op &= -2; + } + for (; ht != table_end; ht++) + if (*ht++ == op) { + if (!((*ht << m_reg) & 0x80)) + goto no_lock_error; + else + break; + } + hs->flags |= F_ERROR | F_ERROR_LOCK; + no_lock_error: + ; + } + } + + if (hs->opcode2) { + switch (opcode) { + case 0x20: case 0x22: + m_mod = 3; + if (m_reg > 4 || m_reg == 1) + goto error_operand; + else + goto no_error_operand; + case 0x21: case 0x23: + m_mod = 3; + if (m_reg == 4 || m_reg == 5) + goto error_operand; + else + goto no_error_operand; + } + } else { + switch (opcode) { + case 0x8c: + if (m_reg > 5) + goto error_operand; + else + goto no_error_operand; + case 0x8e: + if (m_reg == 1 || m_reg > 5) + goto error_operand; + else + goto no_error_operand; + } + } + + if (m_mod == 3) { + uint8_t *table_end; + if (hs->opcode2) { + ht = hde64_table + DELTA_OP2_ONLY_MEM; + table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM; + } else { + ht = hde64_table + DELTA_OP_ONLY_MEM; + table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; + } + for (; ht != table_end; ht += 2) + if (*ht++ == opcode) { + if (*ht++ & pref && !((*ht << m_reg) & 0x80)) + goto error_operand; + else + break; + } + goto no_error_operand; + } else if (hs->opcode2) { + switch (opcode) { + case 0x50: case 0xd7: case 0xf7: + if (pref & (PRE_NONE | PRE_66)) + goto error_operand; + break; + case 0xd6: + if (pref & (PRE_F2 | PRE_F3)) + goto error_operand; + break; + case 0xc5: + goto error_operand; + } + goto no_error_operand; + } else + goto no_error_operand; + + error_operand: + hs->flags |= F_ERROR | F_ERROR_OPERAND; + no_error_operand: + + c = *p++; + if (m_reg <= 1) { + if (opcode == 0xf6) + cflags |= C_IMM8; + else if (opcode == 0xf7) + cflags |= C_IMM_P66; + } + + switch (m_mod) { + case 0: + if (pref & PRE_67) { + if (m_rm == 6) + disp_size = 2; + } else + if (m_rm == 5) + disp_size = 4; + break; + case 1: + disp_size = 1; + break; + case 2: + disp_size = 2; + if (!(pref & PRE_67)) + disp_size <<= 1; + } + + if (m_mod != 3 && m_rm == 4) { + hs->flags |= F_SIB; + p++; + hs->sib = c; + hs->sib_scale = c >> 6; + hs->sib_index = (c & 0x3f) >> 3; + if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) + disp_size = 4; + } + + p--; + switch (disp_size) { + case 1: + hs->flags |= F_DISP8; + hs->disp.disp8 = *p; + break; + case 2: + hs->flags |= F_DISP16; + hs->disp.disp16 = *(uint16_t *)p; + break; + case 4: + hs->flags |= F_DISP32; + hs->disp.disp32 = *(uint32_t *)p; + } + p += disp_size; + } else if (pref & PRE_LOCK) + hs->flags |= F_ERROR | F_ERROR_LOCK; + + if (cflags & C_IMM_P66) { + if (cflags & C_REL32) { + if (pref & PRE_66) { + hs->flags |= F_IMM16 | F_RELATIVE; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + goto disasm_done; + } + goto rel32_ok; + } + if (op64) { + hs->flags |= F_IMM64; + hs->imm.imm64 = *(uint64_t *)p; + p += 8; + } else if (!(pref & PRE_66)) { + hs->flags |= F_IMM32; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else + goto imm16_ok; + } + + + if (cflags & C_IMM16) { + imm16_ok: + hs->flags |= F_IMM16; + hs->imm.imm16 = *(uint16_t *)p; + p += 2; + } + if (cflags & C_IMM8) { + hs->flags |= F_IMM8; + hs->imm.imm8 = *p++; + } + + if (cflags & C_REL32) { + rel32_ok: + hs->flags |= F_IMM32 | F_RELATIVE; + hs->imm.imm32 = *(uint32_t *)p; + p += 4; + } else if (cflags & C_REL8) { + hs->flags |= F_IMM8 | F_RELATIVE; + hs->imm.imm8 = *p++; + } + + disasm_done: + + if ((hs->len = (uint8_t)(p-(uint8_t *)code)) > 15) { + hs->flags |= F_ERROR | F_ERROR_LENGTH; + hs->len = 15; + } + + return (unsigned int)hs->len; +} diff --git a/MinHook_13_src/src/HDE/hde64.h b/MinHook_13_src/src/HDE/hde64.h new file mode 100644 index 0000000..ecbf4df --- /dev/null +++ b/MinHook_13_src/src/HDE/hde64.h @@ -0,0 +1,112 @@ +/* + * Hacker Disassembler Engine 64 + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + * hde64.h: C/C++ header file + * + */ + +#ifndef _HDE64_H_ +#define _HDE64_H_ + +/* stdint.h - C99 standard header + * http://en.wikipedia.org/wiki/stdint.h + * + * if your compiler doesn't contain "stdint.h" header (for + * example, Microsoft Visual C++), you can download file: + * http://www.azillionmonkeys.com/qed/pstdint.h + * and change next line to: + * #include "pstdint.h" + */ +#include "pstdint.h" + +#define F_MODRM 0x00000001 +#define F_SIB 0x00000002 +#define F_IMM8 0x00000004 +#define F_IMM16 0x00000008 +#define F_IMM32 0x00000010 +#define F_IMM64 0x00000020 +#define F_DISP8 0x00000040 +#define F_DISP16 0x00000080 +#define F_DISP32 0x00000100 +#define F_RELATIVE 0x00000200 +#define F_ERROR 0x00001000 +#define F_ERROR_OPCODE 0x00002000 +#define F_ERROR_LENGTH 0x00004000 +#define F_ERROR_LOCK 0x00008000 +#define F_ERROR_OPERAND 0x00010000 +#define F_PREFIX_REPNZ 0x01000000 +#define F_PREFIX_REPX 0x02000000 +#define F_PREFIX_REP 0x03000000 +#define F_PREFIX_66 0x04000000 +#define F_PREFIX_67 0x08000000 +#define F_PREFIX_LOCK 0x10000000 +#define F_PREFIX_SEG 0x20000000 +#define F_PREFIX_REX 0x40000000 +#define F_PREFIX_ANY 0x7f000000 + +#define PREFIX_SEGMENT_CS 0x2e +#define PREFIX_SEGMENT_SS 0x36 +#define PREFIX_SEGMENT_DS 0x3e +#define PREFIX_SEGMENT_ES 0x26 +#define PREFIX_SEGMENT_FS 0x64 +#define PREFIX_SEGMENT_GS 0x65 +#define PREFIX_LOCK 0xf0 +#define PREFIX_REPNZ 0xf2 +#define PREFIX_REPX 0xf3 +#define PREFIX_OPERAND_SIZE 0x66 +#define PREFIX_ADDRESS_SIZE 0x67 + +#pragma pack(push,1) + +typedef struct { + uint8_t len; + uint8_t p_rep; + uint8_t p_lock; + uint8_t p_seg; + uint8_t p_66; + uint8_t p_67; + uint8_t rex; + uint8_t rex_w; + uint8_t rex_r; + uint8_t rex_x; + uint8_t rex_b; + uint8_t opcode; + uint8_t opcode2; + uint8_t modrm; + uint8_t modrm_mod; + uint8_t modrm_reg; + uint8_t modrm_rm; + uint8_t sib; + uint8_t sib_scale; + uint8_t sib_index; + uint8_t sib_base; + union { + uint8_t imm8; + uint16_t imm16; + uint32_t imm32; + uint64_t imm64; + } imm; + union { + uint8_t disp8; + uint16_t disp16; + uint32_t disp32; + } disp; + uint32_t flags; +} hde64s; + +#pragma pack(pop) + +#ifdef __cplusplus +extern "C" { +#endif + +/* __cdecl */ +unsigned int hde64_disasm(const void *code, hde64s *hs); + +#ifdef __cplusplus +} +#endif + +#endif /* _HDE64_H_ */ diff --git a/MinHook_13_src/src/HDE/pstdint.h b/MinHook_13_src/src/HDE/pstdint.h new file mode 100644 index 0000000..46af329 --- /dev/null +++ b/MinHook_13_src/src/HDE/pstdint.h @@ -0,0 +1,39 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2014 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. + * + * 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 + +// Integer types for HDE. +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef INT32 int32_t; +typedef INT64 int64_t; +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; diff --git a/MinHook_13_src/src/HDE/table32.h b/MinHook_13_src/src/HDE/table32.h new file mode 100644 index 0000000..7b3e12e --- /dev/null +++ b/MinHook_13_src/src/HDE/table32.h @@ -0,0 +1,73 @@ +/* + * Hacker Disassembler Engine 32 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xf1 +#define DELTA_FPU_MODRM 0xf8 +#define DELTA_PREFIXES 0x130 +#define DELTA_OP_LOCK_OK 0x1a1 +#define DELTA_OP2_LOCK_OK 0x1b9 +#define DELTA_OP_ONLY_MEM 0x1cb +#define DELTA_OP2_ONLY_MEM 0x1da + +unsigned char hde32_table[] = { + 0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3,0xa8,0xa3, + 0xa8,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xac,0xaa,0xb2,0xaa,0x9f,0x9f, + 0x9f,0x9f,0xb5,0xa3,0xa3,0xa4,0xaa,0xaa,0xba,0xaa,0x96,0xaa,0xa8,0xaa,0xc3, + 0xc3,0x96,0x96,0xb7,0xae,0xd6,0xbd,0xa3,0xc5,0xa3,0xa3,0x9f,0xc3,0x9c,0xaa, + 0xaa,0xac,0xaa,0xbf,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0x90, + 0x82,0x7d,0x97,0x59,0x59,0x59,0x59,0x59,0x7f,0x59,0x59,0x60,0x7d,0x7f,0x7f, + 0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x9a,0x88,0x7d, + 0x59,0x50,0x50,0x50,0x50,0x59,0x59,0x59,0x59,0x61,0x94,0x61,0x9e,0x59,0x59, + 0x85,0x59,0x92,0xa3,0x60,0x60,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59,0x59, + 0x59,0x59,0x9f,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xcc,0x01,0xbc,0x03,0xf0, + 0x10,0x10,0x10,0x10,0x50,0x50,0x50,0x50,0x14,0x20,0x20,0x20,0x20,0x01,0x01, + 0x01,0x01,0xc4,0x02,0x10,0x00,0x00,0x00,0x00,0x01,0x01,0xc0,0xc2,0x10,0x11, + 0x02,0x03,0x11,0x03,0x03,0x04,0x00,0x00,0x14,0x00,0x02,0x00,0x00,0xc6,0xc8, + 0x02,0x02,0x02,0x02,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0xca, + 0x01,0x01,0x01,0x00,0x06,0x00,0x04,0x00,0xc0,0xc2,0x01,0x01,0x03,0x01,0xff, + 0xff,0x01,0x00,0x03,0xc4,0xc4,0xc6,0x03,0x01,0x01,0x01,0xff,0x03,0x03,0x03, + 0xc8,0x40,0x00,0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00, + 0x00,0x00,0x00,0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00, + 0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xff,0xff,0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x7f,0x00,0x00,0xff,0x4a,0x4a,0x4a,0x4a,0x4b,0x52,0x4a,0x4a,0x4a,0x4a,0x4f, + 0x4c,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x55,0x45,0x40,0x4a,0x4a,0x4a, + 0x45,0x59,0x4d,0x46,0x4a,0x5d,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a, + 0x4a,0x4a,0x4a,0x4a,0x4a,0x61,0x63,0x67,0x4e,0x4a,0x4a,0x6b,0x6d,0x4a,0x4a, + 0x45,0x6d,0x4a,0x4a,0x44,0x45,0x4a,0x4a,0x00,0x00,0x00,0x02,0x0d,0x06,0x06, + 0x06,0x06,0x0e,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x00,0x06,0x06,0x02,0x06, + 0x00,0x0a,0x0a,0x07,0x07,0x06,0x02,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x00,0x00,0x00,0x0e,0x05,0x06,0x06,0x06,0x01,0x06,0x00,0x00,0x08, + 0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01, + 0x86,0x00,0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba, + 0xf8,0xbb,0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00, + 0xc4,0xff,0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00, + 0x13,0x09,0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07, + 0xb2,0xff,0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf, + 0xe7,0x08,0x00,0xf0,0x02,0x00 +}; diff --git a/MinHook_13_src/src/HDE/table64.h b/MinHook_13_src/src/HDE/table64.h new file mode 100644 index 0000000..01d4541 --- /dev/null +++ b/MinHook_13_src/src/HDE/table64.h @@ -0,0 +1,74 @@ +/* + * Hacker Disassembler Engine 64 C + * Copyright (c) 2008-2009, Vyacheslav Patkov. + * All rights reserved. + * + */ + +#define C_NONE 0x00 +#define C_MODRM 0x01 +#define C_IMM8 0x02 +#define C_IMM16 0x04 +#define C_IMM_P66 0x10 +#define C_REL8 0x20 +#define C_REL32 0x40 +#define C_GROUP 0x80 +#define C_ERROR 0xff + +#define PRE_ANY 0x00 +#define PRE_NONE 0x01 +#define PRE_F2 0x02 +#define PRE_F3 0x04 +#define PRE_66 0x08 +#define PRE_67 0x10 +#define PRE_LOCK 0x20 +#define PRE_SEG 0x40 +#define PRE_ALL 0xff + +#define DELTA_OPCODES 0x4a +#define DELTA_FPU_REG 0xfd +#define DELTA_FPU_MODRM 0x104 +#define DELTA_PREFIXES 0x13c +#define DELTA_OP_LOCK_OK 0x1ae +#define DELTA_OP2_LOCK_OK 0x1c6 +#define DELTA_OP_ONLY_MEM 0x1d8 +#define DELTA_OP2_ONLY_MEM 0x1e7 + +unsigned char hde64_table[] = { + 0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5, + 0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1, + 0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea, + 0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0, + 0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab, + 0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92, + 0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90, + 0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b, + 0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b, + 0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc, + 0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20, + 0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff, + 0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00, + 0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01, + 0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10, + 0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00, + 0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,0x40,0x00, + 0x0a,0x00,0x04,0x00,0x00,0x00,0x00,0x7f,0x00,0x33,0x01,0x00,0x00,0x00,0x00, + 0x00,0x00,0xff,0xbf,0xff,0xff,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, + 0x00,0x00,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00, + 0xff,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43, + 0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, + 0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40, + 0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06, + 0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07, + 0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04, + 0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,0x00,0x00,0x08,0x00,0x10, + 0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x80,0x01,0x82,0x01,0x86,0x00, + 0xf6,0xcf,0xfe,0x3f,0xab,0x00,0xb0,0x00,0xb1,0x00,0xb3,0x00,0xba,0xf8,0xbb, + 0x00,0xc0,0x00,0xc1,0x00,0xc7,0xbf,0x62,0xff,0x00,0x8d,0xff,0x00,0xc4,0xff, + 0x00,0xc5,0xff,0x00,0xff,0xff,0xeb,0x01,0xff,0x0e,0x12,0x08,0x00,0x13,0x09, + 0x00,0x16,0x08,0x00,0x17,0x09,0x00,0x2b,0x09,0x00,0xae,0xff,0x07,0xb2,0xff, + 0x00,0xb4,0xff,0x00,0xb5,0xff,0x00,0xc3,0x01,0x00,0xc7,0xff,0xbf,0xe7,0x08, + 0x00,0xf0,0x02,0x00 +}; diff --git a/MinHook_13_src/src/buffer.c b/MinHook_13_src/src/buffer.c new file mode 100644 index 0000000..d4cf2e5 --- /dev/null +++ b/MinHook_13_src/src/buffer.c @@ -0,0 +1,229 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2014 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER + * OR CONTRIBUTORS 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. + */ + +#include +#include "buffer.h" + +// Size of each memory block. (= page size of VirtualAlloc) +#define MEMORY_BLOCK_SIZE 0x1000 + +// Max range for seeking a memory block. (= 32MB) +#define MAX_MEMORY_RANGE 0x02000000 + +// Memory protection flags to check the executable address. +#define PAGE_EXECUTE_FLAGS \ + (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) + +// Memory slot. +typedef struct _MEMORY_SLOT +{ + union + { + struct _MEMORY_SLOT *pNext; + UINT8 buffer[MEMORY_SLOT_SIZE]; + }; +} MEMORY_SLOT, *PMEMORY_SLOT; + +// Memory block info. Placed at the head of each block. +typedef struct _MEMORY_BLOCK +{ + struct _MEMORY_BLOCK *pNext; + PMEMORY_SLOT pFree; // First element of the free slot list. + UINT usedCount; +} MEMORY_BLOCK, *PMEMORY_BLOCK; + +//------------------------------------------------------------------------- +// Global Variables: +//------------------------------------------------------------------------- + +// First element of the memory block list. +PMEMORY_BLOCK g_pMemoryBlocks; + +//------------------------------------------------------------------------- +VOID InitializeBuffer(VOID) +{ + // Nothing to do for now. +} + +//------------------------------------------------------------------------- +VOID UninitializeBuffer(VOID) +{ + PMEMORY_BLOCK pBlock = g_pMemoryBlocks; + g_pMemoryBlocks = NULL; + + while (pBlock) + { + PMEMORY_BLOCK pNext = pBlock->pNext; + VirtualFree(pBlock, 0, MEM_RELEASE); + pBlock = pNext; + } +} + +//------------------------------------------------------------------------- +static PMEMORY_BLOCK GetMemoryBlock(LPVOID pOrigin) +{ + ULONG_PTR minAddr; + ULONG_PTR maxAddr; + PMEMORY_BLOCK pBlock; + + SYSTEM_INFO si; + GetSystemInfo(&si); + minAddr = (ULONG_PTR)si.lpMinimumApplicationAddress; + maxAddr = (ULONG_PTR)si.lpMaximumApplicationAddress; + +#ifdef _M_X64 + // pOrigin ± 16MB + if ((ULONG_PTR)pOrigin > MAX_MEMORY_RANGE) + minAddr = max(minAddr, (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE); + + maxAddr = min(maxAddr, (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE); +#endif + + // Look the registered blocks for a reachable one. + for (pBlock = g_pMemoryBlocks; pBlock != NULL; pBlock = pBlock->pNext) + { +#ifdef _M_X64 + // Ignore the blocks too far. + if ((ULONG_PTR)pBlock < minAddr || (ULONG_PTR)pBlock >= maxAddr) + continue; +#endif + // The block has at least one unused slot. + if (pBlock->pFree != NULL) + return pBlock; + } + + // Alloc a new block if not found. + { + ULONG_PTR pStart = ((ULONG_PTR)pOrigin / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE; + ULONG_PTR pAlloc; + for (pAlloc = pStart - MEMORY_BLOCK_SIZE; pAlloc >= minAddr; pAlloc -= MEMORY_BLOCK_SIZE) + { + pBlock = (PMEMORY_BLOCK)VirtualAlloc( + (LPVOID)pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (pBlock != NULL) + break; + } + if (pBlock == NULL) + { + for (pAlloc = pStart + MEMORY_BLOCK_SIZE; pAlloc < maxAddr; pAlloc += MEMORY_BLOCK_SIZE) + { + pBlock = (PMEMORY_BLOCK)VirtualAlloc( + (LPVOID)pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + if (pBlock != NULL) + break; + } + } + } + + if (pBlock != NULL) + { + // Build a linked list of all the slots. + PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBlock + 1; + pBlock->pFree = NULL; + pBlock->usedCount = 0; + do + { + pSlot->pNext = pBlock->pFree; + pBlock->pFree = pSlot; + pSlot++; + } while ((ULONG_PTR)pSlot - (ULONG_PTR)pBlock <= MEMORY_BLOCK_SIZE - MEMORY_SLOT_SIZE); + + pBlock->pNext = g_pMemoryBlocks; + g_pMemoryBlocks = pBlock; + } + + return pBlock; +} + +//------------------------------------------------------------------------- +LPVOID AllocateBuffer(LPVOID pOrigin) +{ + PMEMORY_SLOT pSlot; + PMEMORY_BLOCK pBlock = GetMemoryBlock(pOrigin); + if (pBlock == NULL) + return NULL; + + // Remove an unused slot from the list. + pSlot = pBlock->pFree; + pBlock->pFree = pSlot->pNext; + pBlock->usedCount++; +#ifdef _DEBUG + // Fill the slot with INT3 for debugging. + memset(pSlot, 0xCC, sizeof(MEMORY_SLOT)); +#endif + return pSlot; +} + +//------------------------------------------------------------------------- +VOID FreeBuffer(LPVOID pBuffer) +{ + PMEMORY_BLOCK pBlock = g_pMemoryBlocks; + PMEMORY_BLOCK pPrev = NULL; + ULONG_PTR pTargetBlock = ((ULONG_PTR)pBuffer / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE; + + while (pBlock != NULL) + { + if ((ULONG_PTR)pBlock == pTargetBlock) + { + PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBuffer; +#ifdef _DEBUG + // Clear the released slot for debugging. + memset(pSlot, 0x00, sizeof(MEMORY_SLOT)); +#endif + // Restore the released slot to the list. + pSlot->pNext = pBlock->pFree; + pBlock->pFree = pSlot; + pBlock->usedCount--; + + // Free if unused. + if (pBlock->usedCount == 0) + { + if (pPrev) + pPrev->pNext = pBlock->pNext; + else + g_pMemoryBlocks = pBlock->pNext; + + VirtualFree(pBlock, 0, MEM_RELEASE); + } + + break; + } + + pPrev = pBlock; + pBlock = pBlock->pNext; + } +} + +//------------------------------------------------------------------------- +BOOL IsExecutableAddress(LPVOID pAddress) +{ + MEMORY_BASIC_INFORMATION mi; + VirtualQuery(pAddress, &mi, sizeof(MEMORY_BASIC_INFORMATION)); + + return (mi.State == MEM_COMMIT && (mi.Protect & PAGE_EXECUTE_FLAGS)); +} diff --git a/MinHook_13_src/src/buffer.h b/MinHook_13_src/src/buffer.h new file mode 100644 index 0000000..03edcd5 --- /dev/null +++ b/MinHook_13_src/src/buffer.h @@ -0,0 +1,42 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2014 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER + * OR CONTRIBUTORS 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 + +// Size of each memory slot. +#ifdef _M_X64 + #define MEMORY_SLOT_SIZE 64 +#else + #define MEMORY_SLOT_SIZE 32 +#endif + +VOID InitializeBuffer(VOID); +VOID UninitializeBuffer(VOID); +LPVOID AllocateBuffer(LPVOID pOrigin); +VOID FreeBuffer(LPVOID pBuffer); +BOOL IsExecutableAddress(LPVOID pAddress); diff --git a/MinHook_13_src/src/hook.c b/MinHook_13_src/src/hook.c new file mode 100644 index 0000000..265a8e8 --- /dev/null +++ b/MinHook_13_src/src/hook.c @@ -0,0 +1,752 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2014 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER + * OR CONTRIBUTORS 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. + */ + +#include +#include +#include + +#include "MinHook.h" +#include "buffer.h" +#include "trampoline.h" + +// Initial capacity of the HOOK_ENTRY buffer. +#define INITIAL_HOOK_CAPACITY 32 + +// Initial capacity of the thread IDs buffer. +#define INITIAL_THREAD_CAPACITY 128 + +// Special hook position values. +#define INVALID_HOOK_POS UINT_MAX +#define ALL_HOOKS_POS UINT_MAX + +// Freeze() action argument defines. +#define ACTION_DISABLE 0 +#define ACTION_ENABLE 1 +#define ACTION_APPLY_QUEUED 2 + +// Thread access rights for suspending/resuming threads. +#define THREAD_ACCESS \ + (THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SET_CONTEXT) + +// Hook information. +typedef struct _HOOK_ENTRY +{ + LPVOID pTarget; // Address of the target function. + LPVOID pDetour; // Address of the detour or relay function. + LPVOID pTrampoline; // Address of the trampoline function. + UINT8 backup[8]; // Original prologue of the target function. + + BOOL patchAbove : 1; // Uses the hot patch area. + BOOL isEnabled : 1; // Enabled. + BOOL queueEnable : 1; // Queued for enabling/disabling when != isEnabled. + + UINT nIP : 3; // Count of the instruction boundaries. + UINT8 oldIPs[8]; // Instruction boundaries of the target function. + UINT8 newIPs[8]; // Instruction boundaries of the trampoline function. +} HOOK_ENTRY, *PHOOK_ENTRY; + +// Suspended threads for Freeze()/Unfreeze(). +typedef struct _FROZEN_THREADS +{ + LPDWORD pItems; // Data heap + UINT capacity; // Size of allocated data heap, items + UINT size; // Actual number of data items +} FROZEN_THREADS, *PFROZEN_THREADS; + +//------------------------------------------------------------------------- +// Global Variables: +//------------------------------------------------------------------------- + +// Spin lock flag for EnterSpinLock()/LeaveSpinLock(). +volatile LONG g_isLocked = FALSE; + +// Private heap handle. If not NULL, this library is initialized. +HANDLE g_hHeap = NULL; + +// Hook entries. +struct +{ + PHOOK_ENTRY pItems; // Data heap + UINT capacity; // Size of allocated data heap, items + UINT size; // Actual number of data items +} g_hooks; + +//------------------------------------------------------------------------- +// Returns INVALID_HOOK_POS if not found. +static UINT FindHookEntry(LPVOID pTarget) +{ + UINT i; + for (i = 0; i < g_hooks.size; ++i) + { + if ((ULONG_PTR)pTarget == (ULONG_PTR)g_hooks.pItems[i].pTarget) + return i; + } + + return INVALID_HOOK_POS; +} + +//------------------------------------------------------------------------- +static PHOOK_ENTRY NewHookEntry() +{ + if (g_hooks.pItems == NULL) + { + g_hooks.capacity = INITIAL_HOOK_CAPACITY; + g_hooks.pItems = (PHOOK_ENTRY)HeapAlloc( + g_hHeap, 0, g_hooks.capacity * sizeof(HOOK_ENTRY)); + if (g_hooks.pItems == NULL) + return NULL; + } + else if (g_hooks.size >= g_hooks.capacity) + { + PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc( + g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity * 2) * sizeof(HOOK_ENTRY)); + if (p == NULL) + return NULL; + + g_hooks.capacity *= 2; + g_hooks.pItems = p; + } + + return &g_hooks.pItems[g_hooks.size++]; +} + +//------------------------------------------------------------------------- +static void DelHookEntry(UINT pos) +{ + if (pos < g_hooks.size - 1) + g_hooks.pItems[pos] = g_hooks.pItems[g_hooks.size - 1]; + + g_hooks.size--; + + if (g_hooks.capacity / 2 >= INITIAL_HOOK_CAPACITY && g_hooks.capacity / 2 >= g_hooks.size) + { + PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc( + g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity / 2) * sizeof(HOOK_ENTRY)); + if (p == NULL) + return; + + g_hooks.capacity /= 2; + g_hooks.pItems = p; + } +} + +//------------------------------------------------------------------------- +static DWORD_PTR FindOldIP(PHOOK_ENTRY pHook, DWORD_PTR ip) +{ + UINT i; + + if (pHook->patchAbove && ip == ((DWORD_PTR)pHook->pTarget - sizeof(JMP_REL))) + return (DWORD_PTR)pHook->pTarget; + + for (i = 0; i < pHook->nIP; ++i) + { + if (ip == ((DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i])) + return (DWORD_PTR)pHook->pTarget + pHook->oldIPs[i]; + } + + return 0; +} + +//------------------------------------------------------------------------- +static DWORD_PTR FindNewIP(PHOOK_ENTRY pHook, DWORD_PTR ip) +{ + UINT i; + for (i = 0; i < pHook->nIP; ++i) + { + if (ip == ((DWORD_PTR)pHook->pTarget + pHook->oldIPs[i])) + return (DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i]; + } + + return 0; +} + +//------------------------------------------------------------------------- +static void ProcessThreadIPs(HANDLE hThread, UINT pos, UINT action) +{ + // If the thread suspended in the overwritten area, + // move IP to the proper address. + + CONTEXT c; +#ifdef _M_X64 + DWORD64 *pIP = &c.Rip; +#else + DWORD *pIP = &c.Eip; +#endif + UINT count; + + c.ContextFlags = CONTEXT_CONTROL; + if (!GetThreadContext(hThread, &c)) + return; + + if (pos == ALL_HOOKS_POS) + { + pos = 0; + count = g_hooks.size; + } + else + { + count = pos + 1; + } + + for (; pos < count; ++pos) + { + PHOOK_ENTRY pHook = &g_hooks.pItems[pos]; + BOOL enable; + DWORD_PTR ip; + + switch (action) + { + case ACTION_DISABLE: + enable = FALSE; + break; + + case ACTION_ENABLE: + enable = TRUE; + break; + + case ACTION_APPLY_QUEUED: + enable = pHook->queueEnable; + break; + } + if (pHook->isEnabled == enable) + continue; + + if (enable) + ip = FindNewIP(pHook, *pIP); + else + ip = FindOldIP(pHook, *pIP); + + if (ip != 0) + { + *pIP = ip; + SetThreadContext(hThread, &c); + } + } +} + +//------------------------------------------------------------------------- +static VOID EnumerateThreads(PFROZEN_THREADS pThreads) +{ + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (hSnapshot != INVALID_HANDLE_VALUE) + { + THREADENTRY32 te; + te.dwSize = sizeof(THREADENTRY32); + if (Thread32First(hSnapshot, &te)) + { + do + { + if (te.dwSize >= (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(DWORD)) + && te.th32OwnerProcessID == GetCurrentProcessId() + && te.th32ThreadID != GetCurrentThreadId()) + { + if (pThreads->pItems == NULL) + { + pThreads->capacity = INITIAL_THREAD_CAPACITY; + pThreads->pItems + = (LPDWORD)HeapAlloc(g_hHeap, 0, pThreads->capacity * sizeof(DWORD)); + if (pThreads->pItems == NULL) + break; + } + else if (pThreads->size >= pThreads->capacity) + { + LPDWORD p = (LPDWORD)HeapReAlloc( + g_hHeap, 0, pThreads->pItems, (pThreads->capacity * 2) * sizeof(DWORD)); + if (p == NULL) + break; + + pThreads->capacity *= 2; + pThreads->pItems = p; + } + pThreads->pItems[pThreads->size++] = te.th32ThreadID; + } + + te.dwSize = sizeof(THREADENTRY32); + } while (Thread32Next(hSnapshot, &te)); + } + CloseHandle(hSnapshot); + } +} + +//------------------------------------------------------------------------- +static VOID Freeze(PFROZEN_THREADS pThreads, UINT pos, UINT action) +{ + pThreads->pItems = NULL; + pThreads->capacity = 0; + pThreads->size = 0; + EnumerateThreads(pThreads); + + if (pThreads->pItems != NULL) + { + UINT i; + for (i = 0; i < pThreads->size; ++i) + { + HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]); + if (hThread != NULL) + { + SuspendThread(hThread); + ProcessThreadIPs(hThread, pos, action); + CloseHandle(hThread); + } + } + } +} + +//------------------------------------------------------------------------- +static VOID Unfreeze(PFROZEN_THREADS pThreads) +{ + if (pThreads->pItems != NULL) + { + UINT i; + for (i = 0; i < pThreads->size; ++i) + { + HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]); + if (hThread != NULL) + { + ResumeThread(hThread); + CloseHandle(hThread); + } + } + + HeapFree(g_hHeap, 0, pThreads->pItems); + } +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableHookLL(UINT pos, BOOL enable) +{ + PHOOK_ENTRY pHook = &g_hooks.pItems[pos]; + DWORD oldProtect; + SIZE_T patchSize = sizeof(JMP_REL); + LPBYTE pPatchTarget = (LPBYTE)pHook->pTarget; + + if (pHook->patchAbove) + { + pPatchTarget -= sizeof(JMP_REL); + patchSize += sizeof(JMP_REL_SHORT); + } + + if (!VirtualProtect(pPatchTarget, patchSize, PAGE_EXECUTE_READWRITE, &oldProtect)) + return MH_ERROR_MEMORY_PROTECT; + + if (enable) + { + PJMP_REL pJmp = (PJMP_REL)pPatchTarget; + pJmp->opcode = 0xE9; + pJmp->operand = (UINT32)((LPBYTE)pHook->pDetour - (pPatchTarget + sizeof(JMP_REL))); + + if (pHook->patchAbove) + { + PJMP_REL_SHORT pShortJmp = (PJMP_REL_SHORT)pHook->pTarget; + pShortJmp->opcode = 0xEB; + pShortJmp->operand = (UINT8)(0 - (sizeof(JMP_REL_SHORT) + sizeof(JMP_REL))); + } + } + else + { + if (pHook->patchAbove) + memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL) + sizeof(JMP_REL_SHORT)); + else + memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL)); + } + + VirtualProtect(pPatchTarget, patchSize, oldProtect, &oldProtect); + + pHook->isEnabled = enable; + pHook->queueEnable = enable; + + return MH_OK; +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableAllHooksLL(BOOL enable) +{ + UINT i; + for (i = 0; i < g_hooks.size; ++i) + { + if (g_hooks.pItems[i].isEnabled != enable) + { + FROZEN_THREADS threads; + Freeze(&threads, ALL_HOOKS_POS, enable ? ACTION_ENABLE : ACTION_DISABLE); + __try + { + for (; i < g_hooks.size; ++i) + { + if (g_hooks.pItems[i].isEnabled != enable) + { + MH_STATUS status = EnableHookLL(i, enable); + if (status != MH_OK) + return status; + } + } + } + __finally + { + Unfreeze(&threads); + } + } + } + + return MH_OK; +} + +//------------------------------------------------------------------------- +static VOID EnterSpinLock(VOID) +{ + // Wait until the flag is FALSE. + while (_InterlockedCompareExchange(&g_isLocked, TRUE, FALSE) != FALSE) + { + // Prevent the loop from being too busy. + Sleep(1); + } +} + +//------------------------------------------------------------------------- +static VOID LeaveSpinLock(VOID) +{ + _InterlockedExchange(&g_isLocked, FALSE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_Initialize(VOID) +{ + EnterSpinLock(); + __try + { + if (g_hHeap != NULL) + return MH_ERROR_ALREADY_INITIALIZED; + + g_hHeap = HeapCreate(0, 0, 0); + if (g_hHeap == NULL) + return MH_ERROR_MEMORY_ALLOC; + + // Initialize the internal function buffer. + InitializeBuffer(); + + return MH_OK; + } + __finally + { + LeaveSpinLock(); + } +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_Uninitialize(VOID) +{ + EnterSpinLock(); + __try + { + MH_STATUS status; + + if (g_hHeap == NULL) + return MH_ERROR_NOT_INITIALIZED; + + status = EnableAllHooksLL(FALSE); + if (status != MH_OK) + return status; + + // Free the internal function buffer. + UninitializeBuffer(); + HeapDestroy(g_hHeap); + + g_hHeap = NULL; + + g_hooks.pItems = NULL; + g_hooks.capacity = 0; + g_hooks.size = 0; + + return MH_OK; + } + __finally + { + LeaveSpinLock(); + } +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal) +{ + EnterSpinLock(); + __try + { + UINT pos; + LPVOID pBuffer; + TRAMPOLINE ct; + PHOOK_ENTRY pHook; + + if (g_hHeap == NULL) + return MH_ERROR_NOT_INITIALIZED; + + if (!IsExecutableAddress(pTarget) || !IsExecutableAddress(pDetour)) + return MH_ERROR_NOT_EXECUTABLE; + + pos = FindHookEntry(pTarget); + if (pos != INVALID_HOOK_POS) + return MH_ERROR_ALREADY_CREATED; + + pBuffer = AllocateBuffer(pTarget); + if (pBuffer == NULL) + return MH_ERROR_MEMORY_ALLOC; + + ct.pTarget = pTarget; + ct.pDetour = pDetour; + ct.pTrampoline = pBuffer; + if (!CreateTrampolineFunction(&ct)) + { + FreeBuffer(pBuffer); + return MH_ERROR_UNSUPPORTED_FUNCTION; + } + + pHook = NewHookEntry(); + if (pHook == NULL) + { + FreeBuffer(pBuffer); + return MH_ERROR_MEMORY_ALLOC; + } + + pHook->pTarget = ct.pTarget; +#ifdef _M_X64 + pHook->pDetour = ct.pRelay; +#else + pHook->pDetour = ct.pDetour; +#endif + pHook->pTrampoline = ct.pTrampoline; + pHook->patchAbove = ct.patchAbove; + pHook->isEnabled = FALSE; + pHook->queueEnable = FALSE; + pHook->nIP = ct.nIP; + memcpy(pHook->oldIPs, ct.oldIPs, ARRAYSIZE(ct.oldIPs)); + memcpy(pHook->newIPs, ct.newIPs, ARRAYSIZE(ct.newIPs)); + + // Back up the target function. + if (ct.patchAbove) + { + memcpy( + pHook->backup, + (LPBYTE)pTarget - sizeof(JMP_REL), + sizeof(JMP_REL) + sizeof(JMP_REL_SHORT)); + } + else + { + memcpy(pHook->backup, pTarget, sizeof(JMP_REL)); + } + + if (ppOriginal != NULL) + *ppOriginal = pHook->pTrampoline; + + return MH_OK; + } + __finally + { + LeaveSpinLock(); + } +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget) +{ + EnterSpinLock(); + __try + { + UINT pos; + + if (g_hHeap == NULL) + return MH_ERROR_NOT_INITIALIZED; + + pos = FindHookEntry(pTarget); + if (pos == INVALID_HOOK_POS) + return MH_ERROR_NOT_CREATED; + + if (g_hooks.pItems[pos].isEnabled) + { + FROZEN_THREADS threads; + Freeze(&threads, pos, ACTION_DISABLE); + __try + { + MH_STATUS status = EnableHookLL(pos, FALSE); + if (status != MH_OK) + return status; + } + __finally + { + Unfreeze(&threads); + } + } + + FreeBuffer(g_hooks.pItems[pos].pTrampoline); + DelHookEntry(pos); + + return MH_OK; + } + __finally + { + LeaveSpinLock(); + } +} + +//------------------------------------------------------------------------- +static MH_STATUS EnableHook(LPVOID pTarget, BOOL enable) +{ + EnterSpinLock(); + __try + { + if (g_hHeap == NULL) + return MH_ERROR_NOT_INITIALIZED; + + if (pTarget == MH_ALL_HOOKS) + { + return EnableAllHooksLL(enable); + } + else + { + FROZEN_THREADS threads; + UINT pos = FindHookEntry(pTarget); + if (pos == INVALID_HOOK_POS) + return MH_ERROR_NOT_CREATED; + + if (g_hooks.pItems[pos].isEnabled == enable) + return enable ? MH_ERROR_ENABLED : MH_ERROR_DISABLED; + + Freeze(&threads, pos, ACTION_ENABLE); + __try + { + return EnableHookLL(pos, enable); + } + __finally + { + Unfreeze(&threads); + } + } + } + __finally + { + LeaveSpinLock(); + } +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget) +{ + return EnableHook(pTarget, TRUE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget) +{ + return EnableHook(pTarget, FALSE); +} + +//------------------------------------------------------------------------- +static MH_STATUS QueueHook(LPVOID pTarget, BOOL queueEnable) +{ + EnterSpinLock(); + __try + { + if (g_hHeap == NULL) + return MH_ERROR_NOT_INITIALIZED; + + if (pTarget == MH_ALL_HOOKS) + { + UINT i; + for (i = 0; i < g_hooks.size; ++i) + g_hooks.pItems[i].queueEnable = queueEnable; + } + else + { + UINT pos = FindHookEntry(pTarget); + if (pos == INVALID_HOOK_POS) + return MH_ERROR_NOT_CREATED; + + g_hooks.pItems[pos].queueEnable = queueEnable; + } + + return MH_OK; + } + __finally + { + LeaveSpinLock(); + } +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget) +{ + return QueueHook(pTarget, TRUE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget) +{ + return QueueHook(pTarget, FALSE); +} + +//------------------------------------------------------------------------- +MH_STATUS WINAPI MH_ApplyQueued(VOID) +{ + EnterSpinLock(); + __try + { + UINT i; + + if (g_hHeap == NULL) + return MH_ERROR_NOT_INITIALIZED; + + for (i = 0; i < g_hooks.size; ++i) + { + if (g_hooks.pItems[i].isEnabled != g_hooks.pItems[i].queueEnable) + { + FROZEN_THREADS threads; + Freeze(&threads, ALL_HOOKS_POS, ACTION_APPLY_QUEUED); + __try + { + for (; i < g_hooks.size; ++i) + { + PHOOK_ENTRY pHook = &g_hooks.pItems[i]; + if (pHook->isEnabled != pHook->queueEnable) + { + MH_STATUS status = EnableHookLL(i, pHook->queueEnable); + if (status != MH_OK) + return status; + } + } + } + __finally + { + Unfreeze(&threads); + } + } + } + + return MH_OK; + } + __finally + { + LeaveSpinLock(); + } +} diff --git a/MinHook_13_src/src/trampoline.c b/MinHook_13_src/src/trampoline.c new file mode 100644 index 0000000..c82ca02 --- /dev/null +++ b/MinHook_13_src/src/trampoline.c @@ -0,0 +1,303 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2014 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER + * OR CONTRIBUTORS 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. + */ + +#include +#include + +#ifdef _M_X64 + #include "hde/hde64.h" + typedef hde64s HDE; + #define HDE_DISASM(code, hs) hde64_disasm(code, hs) +#else + #include "hde/hde32.h" + typedef hde32s HDE; + #define HDE_DISASM(code, hs) hde32_disasm(code, hs) +#endif + +#include "trampoline.h" +#include "buffer.h" + +// Maximum size of a trampoline function. +#ifdef _M_X64 + #define TRAMPOLINE_MAX_SIZE (MEMORY_SLOT_SIZE - sizeof(JMP_ABS)) +#else + #define TRAMPOLINE_MAX_SIZE MEMORY_SLOT_SIZE +#endif + +//------------------------------------------------------------------------- +static BOOL IsCodePadding(LPBYTE pInst, UINT size) +{ + UINT i; + + if (pInst[0] != 0x00 && pInst[0] != 0x90 && pInst[0] != 0xCC) + return FALSE; + + for (i = 1; i < size; ++i) + { + if (pInst[i] != pInst[0]) + return FALSE; + } + return TRUE; +} + +//------------------------------------------------------------------------- +BOOL CreateTrampolineFunction(PTRAMPOLINE ct) +{ +#ifdef _M_X64 + CALL_ABS call = { + 0xFF, 0x15, 0x00000002, // FF15 00000002: CALL [RIP+8] + 0xEB, 0x08, // EB 08: JMP +10 + 0x0000000000000000ULL // Absolute destination address + }; + JMP_ABS jmp = { + 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] + 0x0000000000000000ULL // Absolute destination address + }; + JCC_ABS jcc = { + 0x70, 0x0E, // 7* 0E: J** +16 + 0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6] + 0x0000000000000000ULL // Absolute destination address + }; +#else + CALL_REL call = { + 0xE8, // E8 xxxxxxxx: CALL +5+xxxxxxxx + 0x00000000 // Relative destination address + }; + JMP_REL jmp = { + 0xE9, // E9 xxxxxxxx: JMP +5+xxxxxxxx + 0x00000000 // Relative destination address + }; + JCC_REL jcc = { + 0x0F, 0x80, // 0F8* xxxxxxxx: J** +6+xxxxxxxx + 0x00000000 // Relative destination address + }; +#endif + + UINT8 oldPos = 0; + UINT8 newPos = 0; + ULONG_PTR jmpDest = 0; // Destination address of an internal jump. + BOOL finished = FALSE; // Is the function completed? +#ifdef _M_X64 + UINT8 instBuf[16]; +#endif + + ct->patchAbove = FALSE; + ct->nIP = 0; + + do + { + HDE hs; + UINT copySize; + LPVOID pCopySrc; + ULONG_PTR pOldInst = (ULONG_PTR)ct->pTarget + oldPos; + ULONG_PTR pNewInst = (ULONG_PTR)ct->pTrampoline + newPos; + + copySize = HDE_DISASM((LPVOID)pOldInst, &hs); + if (hs.flags & F_ERROR) + return FALSE; + + pCopySrc = (LPVOID)pOldInst; + if (oldPos >= sizeof(JMP_REL)) + { + // The trampoline function is long enough. + // Complete the function with the jump to the target function. +#ifdef _M_X64 + jmp.address = pOldInst; +#else + jmp.operand = (UINT32)(pOldInst - (pNewInst + sizeof(jmp))); +#endif + pCopySrc = &jmp; + copySize = sizeof(jmp); + + finished = TRUE; + } +#ifdef _M_X64 + else if ((hs.modrm & 0xC7) == 0x05) + { + // Instructions using RIP relative addressing. (ModR/M = 00???101B) + + // Modify the RIP relative address. + PUINT32 pRelAddr; + + // Avoid using memcpy to reduce the footprint. + __movsb(instBuf, (LPBYTE)pOldInst, copySize); + pCopySrc = instBuf; + + // Relative address is stored at (instruction length - immediate value length - 4). + pRelAddr = (PUINT32)(instBuf + hs.len - ((hs.flags & 0x3C) >> 2) - 4); + *pRelAddr + = (UINT32)((pOldInst + hs.len + (INT32)hs.disp.disp32) - (pNewInst + hs.len)); + + // Complete the function if JMP (FF /4). + if (hs.opcode == 0xFF && hs.modrm_reg == 4) + finished = TRUE; + } +#endif + else if (hs.opcode == 0xE8) + { + // Direct relative CALL + ULONG_PTR dest = pOldInst + hs.len + (INT32)hs.imm.imm32; +#ifdef _M_X64 + call.address = dest; +#else + call.operand = (UINT32)(dest - (pNewInst + sizeof(call))); +#endif + pCopySrc = &call; + copySize = sizeof(call); + } + else if ((hs.opcode & 0xFD) == 0xE9) + { + // Direct relative JMP (EB or E9) + ULONG_PTR dest = pOldInst + hs.len; + + if (hs.opcode == 0xEB) // isShort jmp + dest += (INT8)hs.imm.imm8; + else + dest += (INT32)hs.imm.imm32; + + // Simply copy an internal jump. + if ((ULONG_PTR)ct->pTarget <= dest + && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) + { + if (jmpDest < dest) + jmpDest = dest; + } + else + { +#ifdef _M_X64 + jmp.address = dest; +#else + jmp.operand = (UINT32)(dest - (pNewInst + sizeof(jmp))); +#endif + pCopySrc = &jmp; + copySize = sizeof(jmp); + + // Exit the function If it is not in the branch + finished = (pOldInst >= jmpDest); + } + } + else if ((hs.opcode & 0xF0) == 0x70 + || (hs.opcode & 0xFC) == 0xE0 + || (hs.opcode2 & 0xF0) == 0x80) + { + // Direct relative Jcc + ULONG_PTR dest = pOldInst + hs.len; + + if ((hs.opcode & 0xF0) == 0x70 // Jcc + || (hs.opcode & 0xFC) == 0xE0) // LOOPNZ/LOOPZ/LOOP/JECXZ + dest += (INT8)hs.imm.imm8; + else + dest += (INT32)hs.imm.imm32; + + // Simply copy an internal jump. + if ((ULONG_PTR)ct->pTarget <= dest + && dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL))) + { + if (jmpDest < dest) + jmpDest = dest; + } + else if ((hs.opcode & 0xFC) == 0xE0) + { + // LOOPNZ/LOOPZ/LOOP/JCXZ/JECXZ to the outside are not supported. + return FALSE; + } + else + { + UINT8 cond = ((hs.opcode != 0x0F ? hs.opcode : hs.opcode2) & 0x0F); +#ifdef _M_X64 + // Invert the condition. + jcc.opcode = 0x71 ^ cond; + jcc.address = dest; +#else + jcc.opcode1 = 0x80 | cond; + jcc.operand = (UINT32)(dest - (pNewInst + sizeof(jcc))); +#endif + pCopySrc = &jcc; + copySize = sizeof(jcc); + } + } + else if ((hs.opcode & 0xFE) == 0xC2) + { + // RET (C2 or C3) + + // Complete the function if not in a branch. + finished = (pOldInst >= jmpDest); + } + + // Can't alter the instruction length in a branch. + if (pOldInst < jmpDest && copySize != hs.len) + return FALSE; + + if ((newPos + copySize) > TRAMPOLINE_MAX_SIZE) + return FALSE; + + if (ct->nIP >= ARRAYSIZE(ct->oldIPs)) + return FALSE; + + ct->oldIPs[ct->nIP] = oldPos; + ct->newIPs[ct->nIP] = newPos; + ct->nIP++; + + // Avoid using memcpy to reduce the footprint. + __movsb((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize); + newPos += copySize; + oldPos += hs.len; + } + while (!finished); + + // Is there enough place for a long jump? + if (oldPos < sizeof(JMP_REL) + && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL) - oldPos)) + { + // Is there enough place for a short jump? + if (oldPos < sizeof(JMP_REL_SHORT) + && !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL_SHORT) - oldPos)) + { + return FALSE; + } + + // Can we place the long jump above the function? + if (!IsExecutableAddress((LPBYTE)ct->pTarget - sizeof(JMP_REL))) + return FALSE; + + if (!IsCodePadding((LPBYTE)ct->pTarget - sizeof(JMP_REL), sizeof(JMP_REL))) + return FALSE; + + ct->patchAbove = TRUE; + } + +#ifdef _M_X64 + // Create a relay function. + jmp.address = (ULONG_PTR)ct->pDetour; + + ct->pRelay = (LPBYTE)ct->pTrampoline + newPos; + memcpy(ct->pRelay, &jmp, sizeof(jmp)); +#endif + + return TRUE; +} diff --git a/MinHook_13_src/src/trampoline.h b/MinHook_13_src/src/trampoline.h new file mode 100644 index 0000000..d2badef --- /dev/null +++ b/MinHook_13_src/src/trampoline.h @@ -0,0 +1,105 @@ +/* + * MinHook - The Minimalistic API Hooking Library for x64/x86 + * Copyright (C) 2009-2014 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT HOLDER + * OR CONTRIBUTORS 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 + +#pragma pack(push, 1) + +// Structs for writing x86/x64 instructions. + +// 8-bit relative jump. +typedef struct _JMP_REL_SHORT +{ + UINT8 opcode; // EB xx: JMP +2+xx + UINT8 operand; +} JMP_REL_SHORT, *PJMP_REL_SHORT; + +// 32-bit direct relative jump/call. +typedef struct _JMP_REL +{ + UINT8 opcode; // E9/E8 xxxxxxxx: JMP/CALL +5+xxxxxxxx + UINT32 operand; // Relative destination address +} JMP_REL, *PJMP_REL, CALL_REL; + +// 64-bit indirect absolute jump. +typedef struct _JMP_ABS +{ + UINT8 opcode0; // FF25 00000000: JMP [+6] + UINT8 opcode1; + UINT32 dummy; + UINT64 address; // Absolute destination address +} JMP_ABS, *PJMP_ABS; + +// 64-bit indirect absolute call. +typedef struct _CALL_ABS +{ + UINT8 opcode0; // FF15 00000002: CALL [+6] + UINT8 opcode1; + UINT32 dummy0; + UINT8 dummy1; // EB 08: JMP +10 + UINT8 dummy2; + UINT64 address; // Absolute destination address +} CALL_ABS; + +// 32-bit direct relative conditional jumps. +typedef struct _JCC_REL +{ + UINT8 opcode0; // 0F8* xxxxxxxx: J** +6+xxxxxxxx + UINT8 opcode1; + UINT32 operand; // Relative destination address +} JCC_REL; + +// 64bit indirect absolute conditional jumps that x64 lacks. +typedef struct _JCC_ABS +{ + UINT8 opcode; // 7* 0E: J** +16 + UINT8 dummy0; + UINT8 dummy1; // FF25 00000000: JMP [+6] + UINT8 dummy2; + UINT32 dummy3; + UINT64 address; // Absolute destination address +} JCC_ABS; + +#pragma pack(pop) + +typedef struct _TRAMPOLINE +{ + LPVOID pTarget; // [In] Address of the target function. + LPVOID pDetour; // [In] Address of the detour function. + LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function. + +#ifdef _M_X64 + LPVOID pRelay; // [Out] Address of the relay function. +#endif + BOOL patchAbove; // [Out] Should use the hot patch area? + UINT nIP; // [Out] Number of the instruction boundaries. + UINT8 oldIPs[8]; // [Out] Instruction boundaries of the target function. + UINT8 newIPs[8]; // [Out] Instruction boundaries of the trampoline function. +} TRAMPOLINE, *PTRAMPOLINE; + +BOOL CreateTrampolineFunction(PTRAMPOLINE ct); diff --git a/Release/.gitattributes b/Release/.gitattributes new file mode 100644 index 0000000..b110a24 --- /dev/null +++ b/Release/.gitattributes @@ -0,0 +1 @@ +*.{dll,exe} filter=lfs diff=lfs merge=lfs -text \ No newline at end of file diff --git a/Release/dxwnd.dll b/Release/dxwnd.dll new file mode 100644 index 0000000..7cf3888 --- /dev/null +++ b/Release/dxwnd.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1bcc2c21f162e19a96bbc07c40a6ce54c339debc559162518e694347e0fbf956 +size 557568 diff --git a/build/dxwnd.dll b/build/dxwnd.dll index 28e192b..25edaa3 100644 --- a/build/dxwnd.dll +++ b/build/dxwnd.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dbb593dd74acbc13c129c32d28ba3808deabc13a62e2163696e371d06a5cdee5 -size 537600 +oid sha256:83be0cc19a6e76c301cfbbd1b9e261a0f875bf019d891fc17a781dd715875777 +size 557568 diff --git a/build/dxwnd.exe b/build/dxwnd.exe index 08c7dac..033e67a 100644 --- a/build/dxwnd.exe +++ b/build/dxwnd.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8fb3df5a4f77d45fa4e102e1b37ab739fdee0eefc74edd8f3574f58c43166ee2 -size 532992 +oid sha256:6ff7d449b4f5a4658ffbe9f95b623d54bcdd46b33c3e7142b4e731c6f7bff61c +size 536064 diff --git a/build/exports/Amerzone.dxw b/build/exports/Amerzone.dxw index c9fc281..fb02f95 100644 --- a/build/exports/Amerzone.dxw +++ b/build/exports/Amerzone.dxw @@ -8,7 +8,7 @@ coord0=0 flag0=134234114 flagg0=1207959568 flagh0=20 -flagi0=4 +flagi0=4194308 tflag0=0 initx0=0 inity0=0 @@ -22,3 +22,8 @@ sizx0=800 sizy0=600 maxfps0=0 initts0=0 +launchpath0= +notes0= +flagj0=128 +winver0=0 +maxres0=0 diff --git a/build/exports/Celtic Kings Rage of War.dxw b/build/exports/Celtic Kings Rage of War.dxw index aebc866..4b9a33b 100644 --- a/build/exports/Celtic Kings Rage of War.dxw +++ b/build/exports/Celtic Kings Rage of War.dxw @@ -6,12 +6,12 @@ module0= opengllib0= ver0=0 coord0=0 -flag0=671088674 +flag0=673185826 flagg0=1744830466 flagh0=65556 flagi0=138412036 flagj0=128 -tflag0=0 +tflag0=6403 initx0=0 inity0=0 minx0=0 @@ -26,3 +26,4 @@ maxfps0=0 initts0=0 winver0=0 maxres0=-1 +notes0= diff --git a/build/exports/Close Combat 5 Invasion Normandy.dxw b/build/exports/Close Combat 5 Invasion Normandy.dxw index a34522b..9de7a68 100644 --- a/build/exports/Close Combat 5 Invasion Normandy.dxw +++ b/build/exports/Close Combat 5 Invasion Normandy.dxw @@ -24,3 +24,6 @@ maxfps0=0 initts0=0 winver0=0 maxres0=-1 +launchpath0= +notes0= +flagj0=128 diff --git a/build/exports/Daikatana.dxw b/build/exports/Daikatana.dxw index ddc3f57..9bec6a3 100644 --- a/build/exports/Daikatana.dxw +++ b/build/exports/Daikatana.dxw @@ -9,7 +9,7 @@ flag0=269492772 flagg0=671220225 flagh0=20 flagi0=4194304 -tflag0=2 +tflag0=0 initx0=0 inity0=0 minx0=0 @@ -25,3 +25,5 @@ initts0=0 launchpath0= winver0=0 maxres0=0 +notes0= +flagj0=0 diff --git a/build/exports/Kingpin Life Of Crime.dxw b/build/exports/Kingpin Life Of Crime.dxw index f9579ac..b435d53 100644 --- a/build/exports/Kingpin Life Of Crime.dxw +++ b/build/exports/Kingpin Life Of Crime.dxw @@ -6,12 +6,12 @@ module0= opengllib0=3dfxgl.dll ver0=9 coord0=0 -flag0=134234400 +flag0=134234146 flagg0=1744830464 flagh0=21 flagi0=-2009071610 flagj0=128 -tflag0=6147 +tflag0=0 initx0=0 inity0=0 minx0=0 @@ -26,3 +26,4 @@ maxfps0=0 initts0=0 winver0=0 maxres0=-1 +notes0= diff --git a/build/exports/MDK2.dxw b/build/exports/MDK2.dxw index 8a3a852..265338b 100644 --- a/build/exports/MDK2.dxw +++ b/build/exports/MDK2.dxw @@ -5,11 +5,11 @@ module0= opengllib0= ver0=0 coord0=0 -flag0=134217760 +flag0=134234146 flagg0=1744961536 -flagh0=20 -flagi0=4 -tflag0=64 +flagh0=65556 +flagi0=4194308 +tflag0=0 initx0=0 inity0=0 minx0=0 @@ -24,3 +24,6 @@ maxfps0=0 initts0=0 winver0=0 maxres0=-1 +launchpath0= +notes0= +flagj0=4096 diff --git a/build/exports/Sid Meier's Alpha Centauri (GOG).dxw b/build/exports/Sid Meier's Alpha Centauri (GOG).dxw new file mode 100644 index 0000000..29366b7 --- /dev/null +++ b/build/exports/Sid Meier's Alpha Centauri (GOG).dxw @@ -0,0 +1,29 @@ +[target] +title0=Sid Meier's Alpha Centauri (GOG) +path0=D:\Games\Sid Meier's Alpha Centauri\terran.exe +launchpath0= +module0= +opengllib0= +notes0= +ver0=0 +coord0=0 +flag0=134217762 +flagg0=1744830464 +flagh0=20 +flagi0=138412036 +flagj0=4224 +tflag0=0 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/exports/Take no Prisoners.dxw b/build/exports/Take no Prisoners.dxw index f43be41..4087dda 100644 --- a/build/exports/Take no Prisoners.dxw +++ b/build/exports/Take no Prisoners.dxw @@ -6,10 +6,10 @@ opengllib0= ver0=0 coord0=0 flag0=134217762 -flagg0=134217860 +flagg0=1207959684 flagh0=20 -flagi0=512 -tflag0=259 +flagi0=4194816 +tflag0=0 initx0=0 inity0=0 minx0=0 @@ -22,3 +22,8 @@ sizx0=800 sizy0=600 maxfps0=0 initts0=0 +launchpath0= +notes0= +flagj0=128 +winver0=0 +maxres0=0 diff --git a/build/exports/Theme Hospital.dxw b/build/exports/Theme Hospital.dxw index acf4ae7..ea92844 100644 --- a/build/exports/Theme Hospital.dxw +++ b/build/exports/Theme Hospital.dxw @@ -25,3 +25,5 @@ maxfps0=0 initts0=0 winver0=0 maxres0=-1 +notes0= +flagj0=128 diff --git a/build/exports/Thief the Dark Project GOLD (GOG).dxw b/build/exports/Thief the Dark Project GOLD (GOG).dxw index a20eb17..74e5545 100644 --- a/build/exports/Thief the Dark Project GOLD (GOG).dxw +++ b/build/exports/Thief the Dark Project GOLD (GOG).dxw @@ -5,10 +5,10 @@ module0= opengllib0= ver0=0 coord0=0 -flag0=256 +flag0=2 flagg0=1207959568 flagh0=20 -flagi0=4 +flagi0=4194308 tflag0=0 initx0=0 inity0=0 @@ -24,3 +24,6 @@ maxfps0=0 initts0=0 winver0=0 maxres0=-1 +launchpath0= +notes0= +flagj0=128 diff --git a/build/exports/Thief the Dark Project GOLD.dxw b/build/exports/Thief the Dark Project GOLD.dxw index 08bcc64..b10d8f9 100644 --- a/build/exports/Thief the Dark Project GOLD.dxw +++ b/build/exports/Thief the Dark Project GOLD.dxw @@ -5,10 +5,10 @@ module0= opengllib0= ver0=7 coord0=0 -flag0=272 -flagg0=440401936 +flag0=18 +flagg0=1514143760 flagh0=131612 -flagi0=4 +flagi0=4194308 tflag0=9 initx0=0 inity0=0 @@ -24,3 +24,6 @@ maxfps0=0 initts0=0 winver0=1 maxres0=-1 +launchpath0= +notes0= +flagj0=128 diff --git a/build/exports/Tiger Woods PGA TOUR 08 Demo.dxw b/build/exports/Tiger Woods PGA TOUR 08 Demo.dxw new file mode 100644 index 0000000..07a7424 --- /dev/null +++ b/build/exports/Tiger Woods PGA TOUR 08 Demo.dxw @@ -0,0 +1,29 @@ +[target] +title0=Tiger Woods PGA TOUR 08 Demo +path0=D:\Games\Tiger Woods PGA TOUR 08 Demo\bin\TW2008Demo.exe +launchpath0= +module0= +opengllib0= +notes0= +ver0=0 +coord0=0 +flag0=134217762 +flagg0=1476395008 +flagh0=65556 +flagi0=138412036 +flagj0=4224 +tflag0=6403 +initx0=0 +inity0=0 +minx0=0 +miny0=0 +maxx0=0 +maxy0=0 +posx0=50 +posy0=50 +sizx0=800 +sizy0=600 +maxfps0=0 +initts0=0 +winver0=0 +maxres0=-1 diff --git a/build/exports/Unreal Tournament.dxw b/build/exports/Unreal Tournament.dxw index fe92270..f57b635 100644 --- a/build/exports/Unreal Tournament.dxw +++ b/build/exports/Unreal Tournament.dxw @@ -8,8 +8,8 @@ coord0=0 flag0=-2013265886 flagg0=1209073680 flagh0=20 -flagi0=2052 -tflag0=4097 +flagi0=4196356 +tflag0=0 initx0=0 inity0=0 minx0=0 @@ -22,3 +22,8 @@ sizx0=1200 sizy0=900 maxfps0=0 initts0=0 +launchpath0= +notes0= +flagj0=128 +winver0=0 +maxres0=0 diff --git a/build/exports/dxwnd.ini b/build/exports/dxwnd.ini deleted file mode 100644 index 06104c1..0000000 --- a/build/exports/dxwnd.ini +++ /dev/null @@ -1,5 +0,0 @@ -[window] -posx=1189 -posy=594 -sizx=497 -sizy=464 diff --git a/build/readme-relnotes.txt b/build/readme-relnotes.txt index 1faa15b..7a93f41 100644 --- a/build/readme-relnotes.txt +++ b/build/readme-relnotes.txt @@ -681,3 +681,28 @@ fix: catched several sporadic errors before they could crash the application fix: GetAttachedSurface() now retrieves a backbuffer from the list, instead of referencing the last one - this fixes "Tomb Raider III" GOG release in non emulated mode. add: "Normalize performance counter" flag to fix an improper use of QueryPerformanceCounter() made by "Cyber Gladiators" add: "GDI Color conversion" debug flag + +v2.03.07 +fix: key matching for virtual registry now made case insensitive (needed for "Die Hard Trilogy") +fix: handling of null values passed to extRegQueryValueEx as lpType and lpData arguments (needed for "Die Hard Trilogy") +fix: DirectDrawSurface::GetPalette returns the virtual palette when applied to virtual primary / backup surfaces (needed for "Die Hard Trilogy") +fix: fixed dump for 8BPP palettized textures (needed for "Die Hard Trilogy") +fix: handling (with no operation) of D3DFMT_Q8W8V8U8 texture type and other bumpmap formats (used by "Tiger Woods PGA Tour 08") +fix: handling of LIMITRESOURCES flag for DirectDraw::GetCaps method when memory exceeds 0x70000000 bytes +fix: handling of LIMITRESOURCES flag for Direct3DDevice::GetAvailableTextureMem method when memory exceeds 1GB +fix: don't change screen resolution in SetDisplayMode when wrong (negative) values are passed. Fixes a problem in binkplayer.exe +fix: fixed OutTrace to avoid possible infinite recursion when loading C runtime libraries and logging LoadLibrary activity +fix: eliminated critical races when using DLL injection, thank to Luigi Auriemma's suggestion (inject an endless loop in the main thread and remove it at the end of injection) +fix: implemented DLL injection according to Luigi Auriemma's schema in CreateProcess hooking routine (needed for "Die Hard Trilogy") +fix: using MinHook library to acquire compatibility with all APIs +fix: hooked GetExitCodeProcess to handle "SUPPRESSCHILD" special case +fix: using hot patching for SystemParametersInfo APIs +fix: in SystemParametersInfo suppressed invalid operations in window mode: SPI_SETKEYBOARDDELAY SPI_SETKEYBOARDSPEED +add: son process handling with 4 different cases: 2 old cases (default case and "SUPPRESSCHILD") plus "INJECTSON" and "ENABLESONHOOK" to hook the son process without/with DLL injection +add: debug color conversion mode through GDI routines +add: multi-hooking for multiple processes contemporarily, adding the line "multiprocesshook=1" in [window] section of dxwnd.ini. Use at your own risk! +add: partial logging of Direct3DDevice::GetDeviceCaps output (to be completed) +add: handling of notes in the DxWnd GUI (configuration notes tab) +mod: when log is not possible on program's folder, it is no longer written in %TEMP% dir, is now written in DxWnd local dir. + + diff --git a/build/registry/dxwnd.Die Hard Trilogy.REG b/build/registry/dxwnd.Die Hard Trilogy.REG new file mode 100644 index 0000000..3b1826b --- /dev/null +++ b/build/registry/dxwnd.Die Hard Trilogy.REG @@ -0,0 +1,69 @@ + +[HKEY_LOCAL_MACHINE] +[HKEY_LOCAL_MACHINE\SOFTWARE] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard] +"Install Directory"="d:\\games\\Die Hard Trilogy" +"FMV Installed"=dword:00000000 +"Data Installed"=dword:00000001 +"Abnormal Termination"=dword:00000000 +"StartupFolder"="Fox Interactive" +"Version"="1.00" + +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\Configuration] +"complexity"=dword:00000000 +"cutoff"=dword:00000000 +"perspective"=dword:00000000 +"Quality"=dword:00000000 +"Use Hardware"=dword:00000000 +"Preferred Height"=dword:00000258 +"Preferred Width"=dword:00000320 +"lighting"=dword:00000001 +"texture quality"=dword:00000000 +"Language"=dword:00000000 + +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d1] +"Input"=dword:00000000 +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d1\Keyboard] +"keyboard"=dword:00000001 +"speed"=dword:00000000 +"sensitivity"=dword:00000000 +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d1\Joystick] +"joystick"=dword:00000001 +"speed"=dword:00000000 +"sensitivity"=dword:00000000 +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d1\Mouse] +"mouse"=dword:00000001 +"speed"=dword:00000000 +"sensitivity"=dword:00000000 +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2] +"Input"=dword:00000000 +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2\Keyboard] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2\Keyboard\speed] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2\Keyboard\sensitivity] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2\Joystick] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2\Joystick\speed] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2\Joystick\sensitivity] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2\Mouse] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2\Mouse\speed] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d2\Mouse\sensitivity] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3] +"Input"=dword:00000000 +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3\Keyboard] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3\Keyboard\speed] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3\Keyboard\sensitivity] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3\Joystick] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3\Joystick\speed] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3\Joystick\sensitivity] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3\Mouse] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3\Mouse\speed] +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\d3\Mouse\sensitivity] + +[HKEY_LOCAL_MACHINE\SOFTWARE\Die Hard\Sound] +"Music Volume"=dword:000000ff +"Music Mute"=dword:00000000 +"SFX Volume"=dword:000000ff +"SFX Mute"=dword:00000000 + +[HKEY_LOCAL_MACHINE\SOFTWARE\Fox Interactive] +[HKEY_LOCAL_MACHINE\SOFTWARE\Fox Interactive\Die Hard Trilogy] +[HKEY_LOCAL_MACHINE\SOFTWARE\Fox Interactive\Die Hard Trilogy\1.0] diff --git a/dll/Inject.cpp b/dll/Inject.cpp new file mode 100644 index 0000000..3d018c5 --- /dev/null +++ b/dll/Inject.cpp @@ -0,0 +1,105 @@ +#define _CRT_SECURE_NO_WARNINGS + +#include +#include +#include +#include +#include + +#define WIN32_LEAN_AND_MEAN + +#define true 1 +#define false 0 + +#include "Winternl.h" + +BOOL Inject(DWORD pID, const char * DLL_NAME) +{ + HANDLE Proc; + char buf[50] = {0}; + LPVOID RemoteString, LoadLibAddy; + if(!pID) return false; + //Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID); // not working on Win XP + Proc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pID); + if(!Proc) + { + sprintf(buf, "OpenProcess() failed: pid=%x err=%d", pID, GetLastError()); + MessageBox(NULL, buf, "Loader", MB_OK); + printf(buf); + return false; + } + LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); + // Allocate space in the process for our DLL + RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + // Write the string name of our DLL in the memory allocated + WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL); + // Load our DLL + if(!CreateRemoteThread(Proc, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, 0, NULL)){ + sprintf(buf, "CreateRemoteThread() failed: pid=%x err=%d", pID, GetLastError()); + MessageBox(NULL, buf, "Loader", MB_OK); + printf(buf); + return false; + } + CloseHandle(Proc); + return true; +} + +#if 0 +DWORD GetTargetThreadIDFromProcName(const char * ProcName) +{ + PROCESSENTRY32 pe; + HANDLE thSnapShot; + BOOL retval, ProcFound = false; + thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if(thSnapShot == INVALID_HANDLE_VALUE) + { + MessageBox(NULL, "Error: Unable to create toolhelp snapshot!", "2MLoader", MB_OK); + //printf("Error: Unable to create toolhelp snapshot!"); + return false; + } + pe.dwSize = sizeof(PROCESSENTRY32); + retval = Process32First(thSnapShot, &pe); + while(retval) + { + if(StrStrI(pe.szExeFile, ProcName)) + { + return pe.th32ProcessID; + } + retval = Process32Next(thSnapShot, &pe); + } + return 0; +} +#endif + +#define STATUS_SUCCESS ((NTSTATUS)0x000 00000L) +#define ThreadQuerySetWin32StartAddress 9 + +LPVOID GetThreadStartAddress(HANDLE hThread) +{ + NTSTATUS ntStatus; + HANDLE hDupHandle; + HMODULE hLibNTHandle; + LPVOID dwStartAddress; + + typedef NTSTATUS (WINAPI *NtQueryInformationThread_Type)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG); + hLibNTHandle = GetModuleHandle("ntdll.dll"); + if(!hLibNTHandle) return 0; + + NtQueryInformationThread_Type NtQueryInformationThread = + (NtQueryInformationThread_Type)GetProcAddress(hLibNTHandle, "NtQueryInformationThread"); + + if(NtQueryInformationThread == NULL) return 0; + + HANDLE hCurrentProcess = GetCurrentProcess(); + if(!DuplicateHandle(hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){ + SetLastError(ERROR_ACCESS_DENIED); + return 0; + } + + ntStatus = NtQueryInformationThread(hDupHandle, (THREADINFOCLASS)ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD), NULL); + CloseHandle(hDupHandle); + CloseHandle(hLibNTHandle); + //if(ntStatus != STATUS_SUCCESS) return 0; + + return dwStartAddress; +} \ No newline at end of file diff --git a/dll/advapi.cpp b/dll/advapi.cpp index 3bd31bc..729f179 100644 --- a/dll/advapi.cpp +++ b/dll/advapi.cpp @@ -112,7 +112,8 @@ static LONG myRegOpenKeyEx( fgets(RegBuf, 256, regf); while (!feof(regf)){ if(RegBuf[0]=='['){ - if((!strncmp(&RegBuf[1],sKey,strlen(sKey))) && (RegBuf[strlen(sKey)+1]==']')){ + // beware: registry keys are case insensitive. Must use _strnicmp instead of strncmp + if((!_strnicmp(&RegBuf[1],sKey,strlen(sKey))) && (RegBuf[strlen(sKey)+1]==']')){ OutTrace("RegOpenKeyEx: found fake Key=\"%s\" hkResult=%x\n", sKey, phkResult ? *phkResult : 0); fclose(regf); return ERROR_SUCCESS; @@ -158,8 +159,8 @@ LONG WINAPI extRegQueryValueEx( HKEY hKey, LPCTSTR lpValueName, LPDWORD lpReserved, - LPDWORD lpType, - LPBYTE lpData, + LPDWORD lpType, // beware: could be NULL + LPBYTE lpData, // beware: could be NULL LPDWORD lpcbData) { LONG res; @@ -171,7 +172,7 @@ LONG WINAPI extRegQueryValueEx( if (res==ERROR_SUCCESS){ OutTrace("RegQueryValueEx: size=%d type=%x(%s) ", lpcbData?*lpcbData:0, lpType?*lpType:0, lpType?ExplainRegType(*lpType):"none"); - if(lpType) switch(*lpType){ + if(lpType && lpData) switch(*lpType){ case REG_SZ: OutTrace("Data=\"%s\"\n", lpData); break; case REG_DWORD: OutTrace("Data=0x%x\n", *(DWORD *)lpData); break; case REG_BINARY: @@ -213,23 +214,25 @@ LONG WINAPI extRegQueryValueEx( //OutTrace("loop: \"%s\"\n", RegBuf); if((RegBuf[0]=='"') && - !strncmp(lpValueName, &RegBuf[1], strlen(lpValueName)) && + !_strnicmp(lpValueName, &RegBuf[1], strlen(lpValueName)) && (RegBuf[strlen(lpValueName)+1]=='"') && (RegBuf[strlen(lpValueName)+2]=='=')) { res=ERROR_FILE_NOT_FOUND; pData=&RegBuf[strlen(lpValueName)+3]; if(*pData=='"'){ // string value - LPBYTE lpb; - lpb = lpData; - *lpcbData=0; - pData++; - while(*pData && (*pData != '"')){ - if(*pData=='\\') pData++; - *lpb++=*pData++; - *lpcbData++; + if(lpData){ + LPBYTE lpb; + lpb = lpData; + *lpcbData=0; + pData++; + while(*pData && (*pData != '"')){ + if(*pData=='\\') pData++; + *lpb++=*pData++; + *lpcbData++; + } + *lpb = 0; // string terminator } - *lpb = 0; // string terminator if(lpType) *lpType=REG_SZ; // OutTraceR("RegQueryValueEx: Data=\"%s\" type=REG_SZ\n", lpData); @@ -239,7 +242,7 @@ LONG WINAPI extRegQueryValueEx( DWORD val; pData+=strlen("dword:"); sscanf(pData, "%x", &val); - memcpy(lpData, &val, sizeof(DWORD)); + if(lpData) memcpy(lpData, &val, sizeof(DWORD)); if(lpType) *lpType=REG_DWORD; *lpcbData=sizeof(DWORD); OutTraceR("RegQueryValueEx: Data=0x%x type=REG_DWORD\n", val); @@ -247,16 +250,18 @@ LONG WINAPI extRegQueryValueEx( } if(!strncmp(pData,"hex:",strlen("hex:"))){ //dword value pData+=strlen("hex:"); - lpData[strlen((char *)lpData)-1]=0; // eliminates \n + pData[strlen(pData)-1]=0; // eliminates \n if(lpType) *lpType=REG_BINARY; - *lpcbData=0; OutTraceDW("RegQueryValueEx: Data="); - while(strlen(pData)>1){ - sscanf(pData, "%x,", (char *)lpData); - OutTraceDW("%02.2x,", *(unsigned char *)lpData); - pData+=3; - lpData++; - (*lpcbData)++; + if(lpData){ + *lpcbData=0; + while(strlen(pData)>1){ + sscanf(pData, "%x,", (char *)lpData); + OutTraceDW("%02.2x,", *(unsigned char *)lpData); + pData+=3; + lpData++; + (*lpcbData)++; + } } OutTraceR(" type=REG_BINARY cbData=%d\n", *lpcbData); res=ERROR_SUCCESS; @@ -279,7 +284,6 @@ LONG WINAPI extRegCloseKey(HKEY hKey) return (*pRegCloseKey)(hKey); } - LONG WINAPI extRegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE *lpData, DWORD cbData) { if (IsTraceR){ diff --git a/dll/d3dtexture.cpp b/dll/d3dtexture.cpp index c41c305..1186cc8 100644 --- a/dll/d3dtexture.cpp +++ b/dll/d3dtexture.cpp @@ -217,6 +217,16 @@ void D3DTextureDump(D3DSURFACE_DESC Desc, D3DLOCKED_RECT LockedRect) case D3DFMT_DXT5: hash = HashSurface((BYTE *)LockedRect.pBits, LockedRect.Pitch / 4, Desc.Width / 4, Desc.Height); break; + case D3DFMT_V8U8: + case D3DFMT_Q8W8V8U8: // Tiger Woods PGA Tour 08 + case D3DFMT_V16U16: + case D3DFMT_Q16W16V16U16: + case D3DFMT_CxV8U8: + case D3DFMT_L6V5U5: + case D3DFMT_X8L8V8U8: + case D3DFMT_A2W10V10U10: + // Bumpmap surfaces, dump is meaningless ..... + break; default: char sMsg[80+1]; static BOOL DoOnce = TRUE; diff --git a/dll/ddraw.cpp b/dll/ddraw.cpp index 8e12d72..0dc8e61 100644 --- a/dll/ddraw.cpp +++ b/dll/ddraw.cpp @@ -1507,6 +1507,14 @@ HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2) c2->dwCKeyCaps, ExplainDDCKeyCaps(c2->dwCKeyCaps)); } + if(dxw.dwFlags2 & LIMITRESOURCES){ // check for memory value overflow + const DWORD dwMaxMem = 0x70000000; + if(c1->dwVidMemTotal > dwMaxMem) c1->dwVidMemTotal = dwMaxMem; + if(c1->dwVidMemFree > dwMaxMem) c1->dwVidMemFree = dwMaxMem; + if(c2->dwVidMemTotal > dwMaxMem) c2->dwVidMemTotal = dwMaxMem; + if(c2->dwVidMemFree > dwMaxMem) c2->dwVidMemFree = dwMaxMem; + } + if((dxw.dwFlags3 & FORCESHEL) && c1) { DDCAPS_DX7 swcaps; // DDCAPS_DX7 because it is the bigger in size int size; @@ -1517,7 +1525,16 @@ HRESULT WINAPI extGetCapsD(LPDIRECTDRAW lpdd, LPDDCAPS c1, LPDDCAPS c2) c2=&swcaps; res=(*pGetCapsD)(lpdd, NULL, c2); } + DWORD dwVidMemTotal=c1->dwVidMemTotal; + DWORD dwVidMemFree=c1->dwVidMemFree; memcpy((void *)c1, (void *)c2, size); +#if 0 + if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=0x40000000; // about 1GB - aqrit's suggestion + if(c1->dwVidMemFree == 0) c1->dwVidMemFree =0x40000000; // about 1GB - aqrit's suggestion +#else + if(c1->dwVidMemTotal == 0) c1->dwVidMemTotal=dwVidMemTotal; + if(c1->dwVidMemFree == 0) c1->dwVidMemFree =dwVidMemFree; +#endif } if(dxw.dwFlags3 & CAPMASK) MaskCapsD(c1, c2); @@ -1902,7 +1919,8 @@ HRESULT WINAPI extQueryInterfaceS(void *lpdds, REFIID riid, LPVOID *obp) } if(dwLocalTexVersion) { - if(dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)) TextureHandling((LPDIRECTDRAWSURFACE)lpdds); + // Texture Handling on QueryInterface + if(dxw.dwFlags5 & TEXTUREMASK) TextureHandling((LPDIRECTDRAWSURFACE)lpdds); HookTexture(obp, dwLocalTexVersion); } @@ -1924,6 +1942,10 @@ HRESULT WINAPI extSetDisplayMode(int version, LPDIRECTDRAW lpdd, else OutTrace("\n"); } + // binkplayer fix + if((int)dwwidth < 0) dwwidth = dxw.GetScreenWidth(); + if((int)dwheight < 0) dwheight = dxw.GetScreenHeight(); + dxw.SetScreenSize(dwwidth, dwheight); GetHookInfo()->Height=(short)dxw.GetScreenHeight(); GetHookInfo()->Width=(short)dxw.GetScreenWidth(); @@ -3265,7 +3287,10 @@ HRESULT WINAPI sBlt(char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect, if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!! } if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0; - if(dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)) TextureHandling(lpdds); + if(dxw.dwFlags5 & TEXTUREMASK) { + // Texture Handling on Blt + TextureHandling(lpdds); + } return res; } @@ -3681,10 +3706,22 @@ HRESULT WINAPI extCreatePalette(LPDIRECTDRAW lpdd, DWORD dwflags, LPPALETTEENTRY HRESULT WINAPI extGetPalette(LPDIRECTDRAWSURFACE lpdds, LPDIRECTDRAWPALETTE *lplpddp) { HRESULT res; + BOOL isPrim, isBack; - OutTraceDDRAW("GetPalette: lpdds=%x\n", lpdds); + isPrim=dxw.IsAPrimarySurface(lpdds); + isBack=dxw.IsABackBufferSurface(lpdds); + OutTraceDDRAW("GetPalette: lpdds=%x%s%s\n", lpdds, isPrim?"(PRIM)":"", isBack?"(BACK)":""); res=(*pGetPalette)(lpdds, lplpddp); + + // v2.03.07: in "Die Hard Trilogy" the backbuffer surface is queryed for the palette + if((dxw.dwFlags1 & EMULATESURFACE) && (res == DDERR_NOPALETTEATTACHED) && (isPrim||isBack)){ + OutTraceDW("GetPalette: retrieve PRIMARY palette for emulated surface lpDDP=%x\n", lpDDP); + *lplpddp = lpDDP; + lpDDP->AddRef(); + res=DD_OK; + } + if (res) OutTraceE("GetPalette: ERROR res=%x(%s)\n", res, ExplainDDError(res)); else OutTraceDDRAW("GetPalette: OK\n"); return res; @@ -3938,7 +3975,10 @@ HRESULT WINAPI extUnlock(int dxversion, Unlock4_Type pUnlock, LPDIRECTDRAWSURFAC if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK; - if((dxw.dwFlags5 & (TEXTUREHIGHLIGHT|TEXTUREDUMP|TEXTUREHACK)) && (!IsPrim)) TextureHandling(lpdds); + if((dxw.dwFlags5 & TEXTUREMASK) && (!IsPrim)) { + // Texture Handling on Unlock + TextureHandling(lpdds); + } return res; } diff --git a/dll/ddtexture.cpp b/dll/ddtexture.cpp index 0872c59..375b4a5 100644 --- a/dll/ddtexture.cpp +++ b/dll/ddtexture.cpp @@ -21,26 +21,6 @@ extern int Set_dwSize_From_Surface(LPDIRECTDRAWSURFACE); #define GRIDSIZE 16 -char *GetDxWndPath() -{ - static BOOL DoOnce = TRUE; - static char sFolderPath[MAX_PATH]; - - if(DoOnce){ // first time through, build the texture dir if not done yet - DWORD dwAttrib; - dwAttrib = GetFileAttributes("dxwnd.dll"); - if (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { - MessageBox(0, "DXWND: ERROR can't locate itself", "ERROR", MB_OK | MB_ICONEXCLAMATION); - exit(0); - } - GetModuleFileName(GetModuleHandle("dxwnd"), sFolderPath, MAX_PATH); - sFolderPath[strlen(sFolderPath)-strlen("dxwnd.dll")] = 0; // terminate the string just before "dxwnd.dll" - DoOnce = FALSE; - } - - return sFolderPath; -} - /* RS Hash Function */ static unsigned int Hash(BYTE *buf, int len) @@ -76,6 +56,9 @@ static char *SurfaceType(DDPIXELFORMAT ddpfPixelFormat) char sColorType[21]; DWORD mask; int i, count; + + if(ddpfPixelFormat.dwRGBBitCount == 8) return "RGB8"; + strcpy(sSurfaceType, ""); // red mask=ddpfPixelFormat.dwRBitMask; @@ -251,9 +234,11 @@ static void TextureDump(LPDIRECTDRAWSURFACE s) pbi.bV4Height = - pbi.bV4Height; pbi.bV4Planes = 1; pbi.bV4V4Compression = BI_BITFIELDS; + if(pbi.bV4BitCount == 8) pbi.bV4V4Compression = BI_RGB; pbi.bV4XPelsPerMeter = 1; pbi.bV4YPelsPerMeter = 1; pbi.bV4ClrUsed = 0; + if(pbi.bV4BitCount == 8) pbi.bV4ClrUsed = 256; pbi.bV4ClrImportant = 0; pbi.bV4RedMask = ddsd.ddpfPixelFormat.dwRBitMask; pbi.bV4GreenMask = ddsd.ddpfPixelFormat.dwGBitMask; @@ -288,8 +273,22 @@ static void TextureDump(LPDIRECTDRAWSURFACE s) // Copy the BITMAPFILEHEADER into the .BMP file. fwrite((LPVOID)&hdr, sizeof(BITMAPFILEHEADER), 1, hf); - // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. - fwrite((LPVOID)&pbi, sizeof(BITMAPV4HEADER) + pbi.bV4ClrUsed * sizeof (RGBQUAD), 1, hf); + // Copy the BITMAPINFOHEADER array into the file. + fwrite((LPVOID)&pbi, sizeof(BITMAPV4HEADER), 1, hf); + + // Copy the RGBQUAD array into the file. + if(pbi.bV4ClrUsed){ + //DWORD PaletteEntries[256]; + //LPDIRECTDRAWSURFACE lpDDS=NULL; + //LPDIRECTDRAWPALETTE lpDDP=NULL; + //lpDDS=dxw.GetPrimarySurface(); + //if(lpDDS) lpDDS->GetPalette(&lpDDP); + //if(lpDDP) lpDDP->GetEntries(0, 0, 256, (LPPALETTEENTRY)PaletteEntries); + //for(int i=0; i<256; i++) PaletteEntries[i]=0xff0000; + extern DWORD PaletteEntries[256]; + fwrite((LPVOID)PaletteEntries, pbi.bV4ClrUsed * sizeof (RGBQUAD), 1, hf); + //fwrite((LPBYTE)PaletteEntries, pbi.bV4ClrUsed * sizeof (RGBQUAD), 1, hf); + } // Copy the array of color indices into the .BMP file. for(int y=0; y<(int)ddsd.dwHeight; y++) diff --git a/dll/dxhook.cpp b/dll/dxhook.cpp index c2e45de..ee275b7 100644 --- a/dll/dxhook.cpp +++ b/dll/dxhook.cpp @@ -20,6 +20,7 @@ #include "Winnls32.h" #include "Mmsystem.h" #include "disasm.h" +#include "MinHook.h" #define SKIPIMEWINDOW TRUE @@ -41,8 +42,6 @@ extern void *IATPatch(HMODULE, char *, void *, const char *, void *); void HookModule(HMODULE, int); static void RecoverScreenMode(); static void LockScreenMode(DWORD, DWORD, DWORD); -DEVMODE SetDevMode; -DEVMODE *pSetDevMode=NULL; extern HANDLE hTraceMutex; @@ -97,8 +96,8 @@ static char *Flag5Names[32]={ "NOBLT", "NOSYSTEMEMULATED", "DOFASTBLT", "AEROBOOST", "QUARTERBLT", "NOIMAGEHLP", "BILINEARFILTER", "REPLACEPRIVOPS", "REMAPMCI", "TEXTUREHIGHLIGHT", "TEXTUREDUMP", "TEXTUREHACK", - "TEXTURETRANSP", "", "", "", - "", "", "", "", + "TEXTURETRANSP", "NORMALIZEPERFCOUNT", "HYBRIDMODE", "GDICOLORCONV", + "INJECTSON", "ENABLESONHOOK", "", "", "", "", "", "", "", "", "", "", }; @@ -114,6 +113,26 @@ static char *TFlagNames[32]={ "", "", "", "", }; +char *GetDxWndPath() +{ + static BOOL DoOnce = TRUE; + static char sFolderPath[MAX_PATH]; + + if(DoOnce){ + DWORD dwAttrib; + dwAttrib = GetFileAttributes("dxwnd.dll"); + if (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { + MessageBox(0, "DXWND: ERROR can't locate itself", "ERROR", MB_OK | MB_ICONEXCLAMATION); + exit(0); + } + GetModuleFileName(GetModuleHandle("dxwnd"), sFolderPath, MAX_PATH); + sFolderPath[strlen(sFolderPath)-strlen("dxwnd.dll")] = 0; // terminate the string just before "dxwnd.dll" + DoOnce = FALSE; + } + + return sFolderPath; +} + static void OutTraceHeader(FILE *fp) { SYSTEMTIME Time; @@ -139,9 +158,12 @@ void OutTrace(const char *format, ...) va_list al; static char path[MAX_PATH]; static FILE *fp=NULL; // GHO: thread safe??? + DWORD tFlags; // check global log flag if(!(dxw.dwTFlags & OUTTRACE)) return; + tFlags = dxw.dwTFlags; + dxw.dwTFlags = 0x0; // to avoid possible log recursion while loading C runtime libraries!!! WaitForSingleObject(hTraceMutex, INFINITE); if (fp == NULL){ @@ -149,14 +171,12 @@ void OutTrace(const char *format, ...) strcat(path, "\\dxwnd.log"); fp = fopen(path, "a+"); if (fp==NULL){ // in case of error (e.g. current dir on unwritable CD unit)... - strcpy(path, getenv("TEMP")); + strcpy(path, GetDxWndPath()); strcat(path, "\\dxwnd.log"); fp = fopen(path, "a+"); } - if (fp==NULL){ // last chance: do not log... - dxw.dwTFlags &= ~OUTTRACE; // turn flag OFF - return; - } + if (fp==NULL) + return; // last chance: do not log... else OutTraceHeader(fp); } @@ -166,6 +186,7 @@ void OutTrace(const char *format, ...) ReleaseMutex(hTraceMutex); fflush(fp); + dxw.dwTFlags = tFlags; // restore settings } #ifdef CHECKFORCOMPATIBILITYFLAGS diff --git a/dll/dxwnd.cpp b/dll/dxwnd.cpp index 0b0fcc9..dda3968 100644 --- a/dll/dxwnd.cpp +++ b/dll/dxwnd.cpp @@ -16,6 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#define _CRT_SECURE_NO_WARNINGS #include #include @@ -24,10 +25,12 @@ along with this program. If not, see . #include "dxwnd.h" #include "dxwcore.hpp" -#define VERSION "2.03.06" -#define DXWACTIVATESINGLETASK 1 // comment to allow multiple task activations +#include "TlHelp32.h" + +#define VERSION "2.03.07" #define DDTHREADLOCK 1 +//#define LOCKTHREADS LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam); @@ -60,12 +63,46 @@ BOOL APIENTRY DllMain( HANDLE hmodule, if(dwreason != DLL_PROCESS_ATTACH) return TRUE; + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); // trick to reduce concurrency problems at program startup + +#ifdef LOCKTHREADS + DWORD currentPID = GetCurrentProcessId(); + DWORD currentTID = GetCurrentThreadId(); + if(currentTID && currentPID){ + int ThreadCount=0; + HANDLE hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL); + if(hThreadSnapshot != INVALID_HANDLE_VALUE){ + DWORD result = 0; + THREADENTRY32 tEntry; + tEntry.dwSize = sizeof(THREADENTRY32); + for (BOOL success = Thread32First(hThreadSnapshot, &tEntry); + !result && success && GetLastError() != ERROR_NO_MORE_FILES; + success = Thread32Next(hThreadSnapshot, &tEntry)){ + if ((tEntry.th32ThreadID != currentTID) && (tEntry.th32OwnerProcessID == currentPID)){ + HANDLE th; + th=OpenThread(THREAD_SUSPEND_RESUME, FALSE, tEntry.th32ThreadID); + ThreadCount++; + SuspendThread(th); + CloseHandle(th); + } + } + CloseHandle(hThreadSnapshot); + //char sMsg[81]; + //sprintf(sMsg,"suspended threads=%d", ThreadCount); + //MessageBox(0, sMsg, "info", MB_OK | MB_ICONEXCLAMATION); + } + } +#endif + hInst = (HINSTANCE)hmodule; // optimization: disables DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for the specified DLL DisableThreadLibraryCalls((HMODULE)hmodule); hMapping = CreateFileMapping((HANDLE)0xffffffff, NULL, PAGE_READWRITE, 0, sizeof(DxWndStatus)+sizeof(TARGETMAP)*MAXTARGETS, "UniWind_TargetList"); - if(!hMapping) return false; + if(!hMapping) { + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + return false; + } // v2.0.2.75: beware: some tasks (namely, Flash player) get dxwnd.dll loaded, but can't create the file mapping // this situation has to be intercepted, or it can cause the dll to cause faults that may crash the program. pStatus = (DXWNDSTATUS *)MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(DXWNDSTATUS)+sizeof(TARGETMAP)*MAXTARGETS); @@ -82,9 +119,46 @@ BOOL APIENTRY DllMain( HANDLE hmodule, if(!hDDLockMutex) hDDLockMutex = CreateMutex(0, FALSE, "DDLock_Mutex"); } InjectHook(); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); + +#ifdef LOCKTHREADS + if(currentTID && currentPID){ + int ThreadCount=0; + HANDLE hThreadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL); + if(hThreadSnapshot != INVALID_HANDLE_VALUE){ + DWORD result = 0; + THREADENTRY32 tEntry; + tEntry.dwSize = sizeof(THREADENTRY32); + for (BOOL success = Thread32First(hThreadSnapshot, &tEntry); + !result && success && GetLastError() != ERROR_NO_MORE_FILES; + success = Thread32Next(hThreadSnapshot, &tEntry)){ + if ((tEntry.th32ThreadID != currentTID) && (tEntry.th32OwnerProcessID == currentPID)){ + HANDLE th; + th=OpenThread(THREAD_SUSPEND_RESUME, FALSE, tEntry.th32ThreadID); + ThreadCount++; + ResumeThread(th); + CloseHandle(th); + } + } + CloseHandle(hThreadSnapshot); + //char sMsg[81]; + //sprintf(sMsg,"resumed threads=%d", ThreadCount); + //MessageBox(0, sMsg, "info", MB_OK | MB_ICONEXCLAMATION); + } + } +#endif + return true; } +static BOOL GetMultiTaskEnabling(){ + char inipath[MAX_PATH]; + GetModuleFileName(GetModuleHandle("dxwnd"), inipath, MAX_PATH); + inipath[strlen(inipath)-strlen("dxwnd.dll")] = 0; // terminate the string just before "dxwnd.dll" + strcat(inipath, "dxwnd.ini"); + return GetPrivateProfileInt("window", "multiprocesshook", 0, inipath); +} + int SetTarget(TARGETMAP *targets){ int i, j; @@ -97,6 +171,7 @@ int SetTarget(TARGETMAP *targets){ memset((void *)&(pStatus->pfd), 0, sizeof(DDPIXELFORMAT)); pStatus->Height = pStatus->Width = 0; pStatus->DXVersion = 0; + pStatus->AllowMultiTask=GetMultiTaskEnabling(); for(i = 0; targets[i].path[0]; i ++){ //OutTraceDW("SetTarget entry %s\n",pMapping[i].path); pMapping[i] = targets[i]; @@ -193,14 +268,15 @@ LRESULT CALLBACK HookProc(int ncode, WPARAM wparam, LPARAM lparam) // no good trying to insert fancy dialog boxes: the window // isn't ready yet, and the operation fails. -#ifdef DXWACTIVATESINGLETASK - if(WaitForSingleObject(hLockMutex, 0)==WAIT_TIMEOUT){ - ReleaseMutex(hMutex); - exit(0); + // V2.03.07: allow multiple process hooking depending on config + if(!(pStatus->AllowMultiTask)){ + if(WaitForSingleObject(hLockMutex, 0)==WAIT_TIMEOUT){ + ReleaseMutex(hMutex); + exit(0); + } } -#else - WaitForSingleObject(hLockMutex, 0); -#endif + else + WaitForSingleObject(hLockMutex, 0); pStatus->Status=DXW_RUNNING; pStatus->TaskIdx=i; diff --git a/dll/dxwnd.vs2008.suo b/dll/dxwnd.vs2008.suo index b65a310..d632866 100644 Binary files a/dll/dxwnd.vs2008.suo and b/dll/dxwnd.vs2008.suo differ diff --git a/dll/dxwnd.vs2008.vcproj b/dll/dxwnd.vs2008.vcproj index d862672..f5f4e48 100644 --- a/dll/dxwnd.vs2008.vcproj +++ b/dll/dxwnd.vs2008.vcproj @@ -50,7 +50,7 @@ Name="VCCLCompilerTool" AdditionalOptions="/IInclude" Optimization="0" - AdditionalIncludeDirectories="../Include" + AdditionalIncludeDirectories=".;../Include" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;DXWND_EXPORTS" MinimalRebuild="true" ExceptionHandling="2" @@ -77,10 +77,13 @@ /> + + diff --git a/dll/gdi32.cpp b/dll/gdi32.cpp index ca635d4..06bce5e 100644 --- a/dll/gdi32.cpp +++ b/dll/gdi32.cpp @@ -206,7 +206,6 @@ FARPROC Remap_GDI32_ProcAddress(LPCSTR proc, HMODULE hModule) // //-------------------------------------------------------------------------------------------- -extern DEVMODE *pSetDevMode; extern DWORD PaletteEntries[256]; extern Unlock4_Type pUnlockMethod(LPDIRECTDRAWSURFACE); extern HRESULT WINAPI sBlt(char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL); @@ -317,31 +316,6 @@ int WINAPI extGetDeviceCaps(HDC hdc, int nindex) } } - // if you have a bypassed setting, use it first! - if(pSetDevMode){ - switch(nindex){ - case BITSPIXEL: - case COLORRES: - res = pSetDevMode->dmBitsPerPel; - OutTraceDW("GetDeviceCaps: fix(1) BITSPIXEL/COLORRES cap=%x\n",res); - return res; - case HORZRES: - if(dxw.Windowize){ - res = pSetDevMode->dmPelsWidth; - OutTraceDW("GetDeviceCaps: fix(1) HORZRES cap=%d\n", res); - return res; - } - break; - case VERTRES: - if(dxw.Windowize){ - res = pSetDevMode->dmPelsHeight; - OutTraceDW("GetDeviceCaps: fix(1) VERTRES cap=%d\n", res); - return res; - } - break; - } - } - switch(nindex){ case VERTRES: if(dxw.Windowize){ diff --git a/dll/hd3d.cpp b/dll/hd3d.cpp index 8985c54..a8b4811 100644 --- a/dll/hd3d.cpp +++ b/dll/hd3d.cpp @@ -91,6 +91,7 @@ DisableD3DSpy_Type pDisableD3DSpy = 0; // IDirect3DDevice8/9 methods +typedef UINT (WINAPI *GetAvailableTextureMem_Type)(void *); typedef HRESULT (WINAPI *TestCooperativeLevel_Type)(void *); typedef HRESULT (WINAPI *GetDirect3D8_Type)(void *, void **); typedef HRESULT (WINAPI *GetDirect3D9_Type)(void *, void **); @@ -110,6 +111,7 @@ typedef HRESULT (WINAPI *CreateTexture8_Type)(void *, UINT, UINT, UINT, DWORD, D typedef HRESULT (WINAPI *CreateTexture9_Type)(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **, HANDLE *); typedef HRESULT (WINAPI *CopyRects_Type)(void *, void *, CONST RECT *, UINT, void *, CONST POINT *); +UINT WINAPI extGetAvailableTextureMem(void *); HRESULT WINAPI extTestCooperativeLevel(void *); HRESULT WINAPI extGetDirect3D8(void *, void **); HRESULT WINAPI extGetDirect3D9(void *, void **); @@ -130,6 +132,7 @@ HRESULT WINAPI extCreateTexture8(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3D HRESULT WINAPI extCreateTexture9(void *, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, void **, HANDLE *); HRESULT WINAPI extCopyRects(void *, void *, CONST RECT *, UINT, void *, CONST POINT *); +GetAvailableTextureMem_Type pGetAvailableTextureMem = 0; TestCooperativeLevel_Type pTestCooperativeLevel = 0; GetDirect3D8_Type pGetDirect3D8 = 0; GetDirect3D9_Type pGetDirect3D9 = 0; @@ -196,7 +199,6 @@ HRESULT WINAPI extQueryInterfaceDev8(void *, REFIID, void** ); HRESULT WINAPI extQueryInterfaceD3D9(void *, REFIID, void** ); HRESULT WINAPI extQueryInterfaceDev9(void *, REFIID, void** ); - HRESULT WINAPI extEnumAdapterModes8(void *, UINT, UINT , D3DDISPLAYMODE *); HRESULT WINAPI extEnumAdapterModes9(void *, UINT, D3DFORMAT, UINT , D3DDISPLAYMODE *); HRESULT WINAPI extGetAdapterDisplayMode8(void *, UINT, D3DDISPLAYMODE *); @@ -361,7 +363,7 @@ int HookDirect3D(HMODULE module, int version){ ID3D11Device *lpd3d11; HRESULT res; - OutTrace("HookDirect3D: module=%x version=%d\n", module, version); + OutTraceDW("HookDirect3D: module=%x version=%d\n", module, version); switch(version){ case 0: HookLibrary(module, d3d8Hooks, "d3d8.dll"); @@ -434,6 +436,8 @@ void HookD3DDevice8(void** ppD3Ddev8) { OutTraceD3D("Device hook for IID_IDirect3DDevice8 interface\n"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 0), extQueryInterfaceDev8, (void **)&pQueryInterfaceDev8, "QueryInterface(D8)"); + SetHook((void *)(**(DWORD **)ppD3Ddev8 + 12), extTestCooperativeLevel, (void **)&pTestCooperativeLevel, "TestCooperativeLevel(D8)"); + SetHook((void *)(**(DWORD **)ppD3Ddev8 + 16), extGetAvailableTextureMem, (void **)&pGetAvailableTextureMem, "GetAvailableTextureMem(D8)"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 24), extGetDirect3D8, (void **)&pGetDirect3D8, "GetDirect3D(D8)"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 32), extGetDisplayMode8, (void **)&pGetDisplayMode8, "GetDisplayMode(D8)"); SetHook((void *)(**(DWORD **)ppD3Ddev8 + 44), extSetCursorPosition8, (void **)&pSetCursorPosition8, "SetCursorPosition(D8)"); @@ -472,6 +476,8 @@ void HookD3DDevice9(void** ppD3Ddev9) { OutTraceD3D("Device hook for IID_IDirect3DDevice9 interface\n"); SetHook((void *)(**(DWORD **)ppD3Ddev9 + 0), extQueryInterfaceDev9, (void **)&pQueryInterfaceDev9, "QueryInterface(D9)"); + SetHook((void *)(**(DWORD **)ppD3Ddev9 + 12), extTestCooperativeLevel, (void **)&pTestCooperativeLevel, "TestCooperativeLevel(D9)"); + SetHook((void *)(**(DWORD **)ppD3Ddev9 + 16), extGetAvailableTextureMem, (void **)&pGetAvailableTextureMem, "GetAvailableTextureMem(D9)"); SetHook((void *)(**(DWORD **)ppD3Ddev9 + 24), extGetDirect3D9, (void **)&pGetDirect3D9, "GetDirect3D(D9)"); SetHook((void *)(**(DWORD **)ppD3Ddev9 + 32), extGetDisplayMode9, (void **)&pGetDisplayMode9, "GetDisplayMode(D9)"); SetHook((void *)(**(DWORD **)ppD3Ddev9 + 44), extSetCursorPosition9, (void **)&pSetCursorPosition9, "SetCursorPosition(D9)"); @@ -508,9 +514,6 @@ void HookD3DDevice9(void** ppD3Ddev9) if (!(dxw.dwTFlags & OUTPROXYTRACE)) return; SetHook((void *)(**(DWORD **)ppD3Ddev9 + 4), extAddRef9, (void **)&pAddRef9, "AddRef(D9)"); SetHook((void *)(**(DWORD **)ppD3Ddev9 + 8), extRelease9, (void **)&pRelease9, "Release(D9)"); - SetHook((void *)(**(DWORD **)ppD3Ddev9 + 12), extTestCooperativeLevel, (void **)&pTestCooperativeLevel, "TestCooperativeLevel(D9)"); - - } // WIP @@ -1708,70 +1711,170 @@ HRESULT WINAPI voidDirect3DShaderValidatorCreate9(void) HRESULT WINAPI extRegisterSoftwareDevice(void *lpd3d, void *pInitializeFunction) { - OutTrace("RegisterSoftwareDevice: d3d=%x\n", lpd3d); + OutTraceD3D("RegisterSoftwareDevice: d3d=%x\n", lpd3d); return (*pRegisterSoftwareDevice)(lpd3d, pInitializeFunction); } UINT WINAPI extGetAdapterModeCount(void *lpd3d, UINT Adapter, D3DFORMAT Format) { - OutTrace("GetAdapterModeCount: d3d=%x adapter=%d\n", lpd3d, Adapter); + OutTraceD3D("GetAdapterModeCount: d3d=%x adapter=%d\n", lpd3d, Adapter); return (*pGetAdapterModeCount)(lpd3d, Adapter, Format); } HRESULT WINAPI extCheckDeviceType(void *lpd3d, UINT Adapter, D3DDEVTYPE DevType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed) { - OutTrace("CheckDeviceType: d3d=%x adapter=%d windowed=%x\n", lpd3d, Adapter, bWindowed); + OutTraceD3D("CheckDeviceType: d3d=%x adapter=%d windowed=%x\n", lpd3d, Adapter, bWindowed); return (*pCheckDeviceType)(lpd3d, Adapter, DevType, AdapterFormat, BackBufferFormat, bWindowed); } HRESULT WINAPI extCheckDeviceFormat(void *lpd3d, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat) { - OutTrace("CheckDeviceFormat: d3d=%x adapter=%d\n", lpd3d, Adapter); + OutTraceD3D("CheckDeviceFormat: d3d=%x adapter=%d\n", lpd3d, Adapter); return (*pCheckDeviceFormat)(lpd3d, Adapter, DeviceType, AdapterFormat, Usage, RType, CheckFormat); } HRESULT WINAPI extCheckDeviceMultiSampleType(void *lpd3d, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SurfaceFormat, BOOL Windowed, D3DMULTISAMPLE_TYPE MultiSampleType, DWORD *pQualityLevels) { - OutTrace("CheckDeviceMultiSampleType: d3d=%x adapter=%d windowed=%x\n", lpd3d, Adapter, Windowed); + OutTraceD3D("CheckDeviceMultiSampleType: d3d=%x adapter=%d windowed=%x\n", lpd3d, Adapter, Windowed); return (*pCheckDeviceMultiSampleType)(lpd3d, Adapter, DeviceType, SurfaceFormat, Windowed, MultiSampleType, pQualityLevels); } HRESULT WINAPI extCheckDepthStencilMatch(void *lpd3d, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat) { - OutTrace("CheckDepthStencilMatch: d3d=%x adapter=%d\n", lpd3d, Adapter); + OutTraceD3D("CheckDepthStencilMatch: d3d=%x adapter=%d\n", lpd3d, Adapter); return (*pCheckDepthStencilMatch)(lpd3d, Adapter, DeviceType, AdapterFormat, RenderTargetFormat, DepthStencilFormat); } HRESULT WINAPI extCheckDeviceFormatConversion(void *lpd3d, UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat) { - OutTrace("CheckDeviceFormatConversion: d3d=%x adapter=%d\n", lpd3d, Adapter); + OutTraceD3D("CheckDeviceFormatConversion: d3d=%x adapter=%d\n", lpd3d, Adapter); return (*pCheckDeviceFormatConversion)(lpd3d, Adapter, DeviceType, SourceFormat, TargetFormat); } +static char *ExplainD3D9DeviceType(D3DDEVTYPE DeviceType) +{ + char *s; + switch(DeviceType){ + case D3DDEVTYPE_HAL: s="HAL"; break; + case D3DDEVTYPE_NULLREF: s="NULLREF"; break; + case D3DDEVTYPE_REF: s="REF"; break; + case D3DDEVTYPE_SW: s="SW"; break; + default: s="unknown"; break; + } + return s; +} + HRESULT WINAPI extD3DGetDeviceCaps(void *lpd3d, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) { - OutTrace("GetDeviceCaps: d3d=%x adapter=%d\n", lpd3d, Adapter); - return (*pD3DGetDeviceCaps)(lpd3d, Adapter, DeviceType, pCaps); + HRESULT res; + OutTraceD3D("GetDeviceCaps: d3d=%x adapter=%d devtype=%x(%s)\n", lpd3d, Adapter, DeviceType, ExplainD3D9DeviceType(DeviceType)); + res=(*pD3DGetDeviceCaps)(lpd3d, Adapter, DeviceType, pCaps); + if(res){ + OutTraceE("GetDeviceCaps: ERROR: err=%x\n", res); + } + else{ + if(IsDebug){ + OutTrace("GetDeviceCaps: DeviceType=%x(%s) Caps=%x Caps2=%x Caps3=%x PresentationIntervals=%x CursorCaps=%x DevCaps=%x\n", + pCaps->DeviceType, ExplainD3D9DeviceType(pCaps->DeviceType), pCaps->Caps, pCaps->Caps2, pCaps->Caps3, pCaps->PresentationIntervals, + pCaps->CursorCaps, pCaps->DevCaps); + OutTrace("GetDeviceCaps: PrimitiveMiscCaps=%x RasterCaps=%x ZCmpCaps=%x SrcBlendCaps=%x DestBlendCaps=%x AlphaCmpCaps=%x\n", + pCaps->PrimitiveMiscCaps, pCaps->RasterCaps, pCaps->ZCmpCaps, pCaps->SrcBlendCaps, pCaps->DestBlendCaps, pCaps->AlphaCmpCaps); + OutTrace("GetDeviceCaps: AlphaCmpCaps=%x ShadeCaps=%x TextureCaps=%x TextureFilterCaps=%x CubeTextureFilterCaps=%x VolumeTextureFilterCaps=%x\n", + pCaps->AlphaCmpCaps, pCaps->ShadeCaps, pCaps->TextureCaps, pCaps->TextureFilterCaps, pCaps->CubeTextureFilterCaps, pCaps->VolumeTextureFilterCaps); + OutTrace("GetDeviceCaps: TextureAddressCaps=%x VolumeTextureAddressCaps=%x LineCaps=%x StencilCaps=%x FVFCaps=%x TextureOpCaps=%x VertexProcessingCaps=%x\n", + pCaps->TextureAddressCaps, pCaps->VolumeTextureAddressCaps, pCaps->LineCaps, pCaps->StencilCaps, pCaps->FVFCaps, pCaps->TextureOpCaps, pCaps->VertexProcessingCaps); + OutTrace("GetDeviceCaps: MaxTexture(Width x Height)=(%dx%d) MaxVolumeExtent=%d MaxTextureRepeat=%d MaxTextureAspectRatio=%d MaxAnisotropy=%d\n", + pCaps->MaxTextureWidth, pCaps->MaxTextureHeight, pCaps->MaxVolumeExtent, pCaps->MaxTextureRepeat, pCaps->MaxTextureAspectRatio, pCaps->MaxAnisotropy); + OutTrace("GetDeviceCaps: MaxActiveLights=%d MaxUserClipPlanes=%x MaxUserClipPlanes=%x\n", + pCaps->MaxActiveLights, pCaps->MaxUserClipPlanes, pCaps->MaxUserClipPlanes); +/* + float MaxVertexW; + + float GuardBandLeft; + float GuardBandTop; + float GuardBandRight; + float GuardBandBottom; + + float ExtentsAdjust; + + DWORD MaxTextureBlendStages; + DWORD MaxSimultaneousTextures; + + DWORD ; + DWORD ; + DWORD ; + DWORD MaxVertexBlendMatrices; + DWORD MaxVertexBlendMatrixIndex; + + float MaxPointSize; + + DWORD MaxPrimitiveCount; // max number of primitives per DrawPrimitive call + DWORD MaxVertexIndex; + DWORD MaxStreams; + DWORD MaxStreamStride; // max stride for SetStreamSource + + DWORD VertexShaderVersion; + DWORD MaxVertexShaderConst; // number of vertex shader constant registers + + DWORD PixelShaderVersion; + float PixelShader1xMaxValue; // max value storable in registers of ps.1.x shaders + + // Here are the DX9 specific ones + DWORD DevCaps2; + + float MaxNpatchTessellationLevel; + DWORD Reserved5; + + UINT MasterAdapterOrdinal; // ordinal of master adaptor for adapter group + UINT AdapterOrdinalInGroup; // ordinal inside the adapter group + UINT NumberOfAdaptersInGroup; // number of adapters in this adapter group (only if master) + DWORD DeclTypes; // Data types, supported in vertex declarations + DWORD NumSimultaneousRTs; // Will be at least 1 + DWORD StretchRectFilterCaps; // Filter caps supported by StretchRect + D3DVSHADERCAPS2_0 VS20Caps; + D3DPSHADERCAPS2_0 PS20Caps; + DWORD VertexTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's for texture, used in vertex shaders + DWORD MaxVShaderInstructionsExecuted; // maximum number of vertex shader instructions that can be executed + DWORD MaxPShaderInstructionsExecuted; // maximum number of pixel shader instructions that can be executed + DWORD MaxVertexShader30InstructionSlots; + DWORD MaxPixelShader30InstructionSlots; + */ + } + } + return res; } HMONITOR WINAPI extGetAdapterMonitor(void *lpd3d, UINT Adapter) { - OutTrace("GetAdapterMonitor: d3d=%x adapter=%d\n", lpd3d, Adapter); + OutTraceD3D("GetAdapterMonitor: d3d=%x adapter=%d\n", lpd3d, Adapter); return (*pGetAdapterMonitor)(lpd3d, Adapter); } +UINT WINAPI extGetAvailableTextureMem(void *lpd3dd) +{ + const UINT TextureMemoryLimit = 1024 * 1024 * 1024; // 1GB + // const DWORD dwMaxMem = 0x70000000; = 1.8G + UINT AvailableTextureMem = (*pGetAvailableTextureMem)(lpd3dd); + OutTraceD3D("GetAvailableTextureMem: lpd3dd=%x AvailableTextureMem=%u(%dMB)\n", lpd3dd, AvailableTextureMem, AvailableTextureMem>>20); + if((dxw.dwFlags2 & LIMITRESOURCES) && (AvailableTextureMem > TextureMemoryLimit)){ + OutTraceDW("GetAvailableTextureMem: LIMIT AvailableTextureMem=%u->%u\n", AvailableTextureMem, TextureMemoryLimit); + AvailableTextureMem = TextureMemoryLimit; + } + return AvailableTextureMem; +} + HRESULT WINAPI extTestCooperativeLevel(void *lpd3dd) { HRESULT res; res = (*pTestCooperativeLevel)(lpd3dd); - OutTrace("TestCooperativeLevel: d3dd=%x res=%x\n", lpd3dd, res); + OutTraceB("TestCooperativeLevel: d3dd=%x res=%x\n", lpd3dd, res); return res; } HRESULT WINAPI extGetSwapChain(void *lpd3dd, UINT iSwapChain, IDirect3DSwapChain9** pSwapChain) { HRESULT res; - OutTrace("GetSwapChain: d3dd=%x SwapChain=%d\n", lpd3dd, iSwapChain); + OutTraceD3D("GetSwapChain: d3dd=%x SwapChain=%d\n", lpd3dd, iSwapChain); res = (*pGetSwapChain)(lpd3dd, iSwapChain, pSwapChain); return res; } @@ -1780,14 +1883,14 @@ UINT WINAPI extGetNumberOfSwapChains(void *lpd3dd) { UINT res; res = (*pGetNumberOfSwapChains)(lpd3dd); - OutTrace("GetNumberOfSwapChains: d3dd=%x res=%d\n", lpd3dd, res); + OutTraceD3D("GetNumberOfSwapChains: d3dd=%x res=%d\n", lpd3dd, res); return res; } HRESULT WINAPI extBeginStateBlock8(void *lpd3dd) { HRESULT res; - OutTrace("BeginStateBlock(8): d3dd=%x\n", lpd3dd); + OutTraceD3D("BeginStateBlock(8): d3dd=%x\n", lpd3dd); res = (*pBeginStateBlock8)(lpd3dd); HookD3DDevice8(&lpd3dd); return res; @@ -1799,7 +1902,7 @@ HRESULT WINAPI extBeginStateBlock9(void *lpd3dd) // you need to hook the device object again. This operation fixes the switch to fullscreen mode // in "Freedom Force vs. the Third Reich". HRESULT res; - OutTrace("BeginStateBlock(9): d3dd=%x\n", lpd3dd); + OutTraceD3D("BeginStateBlock(9): d3dd=%x\n", lpd3dd); res = (*pBeginStateBlock9)(lpd3dd); HookD3DDevice9(&lpd3dd); return res; @@ -1808,7 +1911,7 @@ HRESULT WINAPI extBeginStateBlock9(void *lpd3dd) HRESULT WINAPI extEndStateBlock8(void *lpd3dd, DWORD *pToken) { HRESULT res; - OutTrace("EndStateBlock(8): d3dd=%x\n", lpd3dd); + OutTraceD3D("EndStateBlock(8): d3dd=%x\n", lpd3dd); res = (*pEndStateBlock8)(lpd3dd, pToken); return res; } @@ -1816,7 +1919,7 @@ HRESULT WINAPI extEndStateBlock8(void *lpd3dd, DWORD *pToken) HRESULT WINAPI extEndStateBlock9(void *lpd3dd, IDirect3DStateBlock9** ppSB) { HRESULT res; - OutTrace("EndStateBlock(9): d3dd=%x\n", lpd3dd); + OutTraceD3D("EndStateBlock(9): d3dd=%x\n", lpd3dd); res = (*pEndStateBlock9)(lpd3dd, ppSB); return res; } diff --git a/dll/hotpatch.cpp b/dll/hotpatch.cpp index b2d5ce9..496b6e2 100644 --- a/dll/hotpatch.cpp +++ b/dll/hotpatch.cpp @@ -5,12 +5,47 @@ // 1 = already patched // addr = address of the original function +#define USEMINHOOK + #include #include "dxwnd.h" #include "dxwcore.hpp" +#ifdef USEMINHOOK +#include "MinHook.h" +#endif void *HotPatch(void *apiproc, const char *apiname, void *hookproc) { +#ifdef USEMINHOOK + void *pProc; + static BOOL DoOnce = TRUE; + + if(DoOnce){ + if (MH_Initialize() != MH_OK) { + OutTraceE("HotPatch: MH_Initialize FAILED\n"); + // What to do here? No recovery action ... + return 0; + } + DoOnce = FALSE; + } + + OutTraceH("HotPatch: api=%s addr=%x hook=%x\n", apiname, apiproc, hookproc); + + if(!strcmp(apiname, "GetProcAddress")) return 0; // do not mess with this one! + + if (MH_CreateHook(apiproc, hookproc, reinterpret_cast(&pProc)) != MH_OK){ + OutTraceH("HotPatch: MH_CreateHook FAILED\n"); + return 0; + } + + if (MH_EnableHook(apiproc) != MH_OK){ + OutTraceH("HotPatch: MH_EnableHook FAILED\n"); + return 0; + } + + OutTrace("HotPatch: api=%s addr=%x->%x hook=%x\n", apiname, apiproc, pProc, hookproc); + return pProc; +#else DWORD dwPrevProtect; BYTE* patch_address; void *orig_address; @@ -62,4 +97,5 @@ void *HotPatch(void *apiproc, const char *apiname, void *hookproc) VirtualProtect( patch_address, 12, dwPrevProtect, &dwPrevProtect ); // restore protection OutTrace("HotPatch: api=%s addr=%x->%x hook=%x\n", apiname, apiproc, orig_address, hookproc); return orig_address; +#endif } \ No newline at end of file diff --git a/dll/kernel32.cpp b/dll/kernel32.cpp index e1b9ed7..12ddec9 100644 --- a/dll/kernel32.cpp +++ b/dll/kernel32.cpp @@ -9,6 +9,7 @@ //#undef IsTraceDW //#define IsTraceDW TRUE +#define LOCKINJECTIONTHREADS BOOL WINAPI extCheckRemoteDebuggerPresent(HANDLE, PBOOL); @@ -735,42 +736,145 @@ BOOL WINAPI extCreateProcessA( ) { BOOL res; +#ifdef LOCKINJECTIONTHREADS + DWORD StartingCode; + LPVOID StartAddress = 0; + extern LPVOID GetThreadStartAddress(HANDLE); +#endif OutTraceDW("CreateProcess: ApplicationName=\"%s\" CommandLine=\"%s\"\n", lpApplicationName, lpCommandLine); if(dxw.dwFlags4 & SUPPRESSCHILD) { OutTraceDW("CreateProcess: SUPPRESS\n"); - return TRUE; + return TRUE; + } + + if(dxw.dwFlags5 & (INJECTSON|ENABLESONHOOK)) { + extern HANDLE hLockMutex; + ReleaseMutex(hLockMutex); + } + + if(dxw.dwFlags5 & INJECTSON) { + DEBUG_EVENT debug_event ={0}; + char path[MAX_PATH]; + extern char *GetFileNameFromHandle(HANDLE); + DWORD dwContinueStatus = DBG_CONTINUE; + extern BOOL Inject(DWORD, const char *); + + //dwCreationFlags |= DEBUG_ONLY_THIS_PROCESS; + dwCreationFlags |= (DEBUG_ONLY_THIS_PROCESS|DEBUG_PROCESS); + + res=(*pCreateProcessA)( + lpApplicationName, lpCommandLine, + lpProcessAttributes, lpThreadAttributes, bInheritHandles, + dwCreationFlags, lpEnvironment, + lpCurrentDirectory, lpStartupInfo, lpProcessInformation + ); + OutTrace("CreateProcess res=%x\n", res); + BOOL bContinueDebugging = TRUE; + while(bContinueDebugging) + { + if (!WaitForDebugEvent(&debug_event, INFINITE)) break; + switch(debug_event.dwDebugEventCode){ + case EXIT_PROCESS_DEBUG_EVENT: + bContinueDebugging=false; + OutTrace("CreateProcess: process terminated\n", res); + break; + case CREATE_PROCESS_DEBUG_EVENT: + GetModuleFileName(GetModuleHandle("dxwnd"), path, MAX_PATH); + OutTrace("CreateProcess: injecting path=%s\n", path); + if(!Inject(lpProcessInformation->dwProcessId, path)){ + OutTrace("CreateProcess: Injection ERROR pid=%x dll=%s\n", lpProcessInformation->dwProcessId, path); + } +#ifdef LOCKINJECTIONTHREADS + extern LPVOID GetThreadStartAddress(HANDLE); + DWORD TargetHandle; + DWORD EndlessLoop; + EndlessLoop=0x9090FEEB; + SIZE_T BytesCount; + TargetHandle = (DWORD)OpenProcess( + PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, + FALSE, + lpProcessInformation->dwProcessId); + if(TargetHandle){ + StartAddress = GetThreadStartAddress(lpProcessInformation->hThread); + OutTrace("CreateProcess: StartAddress=%x\n", StartAddress); + if(StartAddress){ + if(!ReadProcessMemory(lpProcessInformation->hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ + OutTrace("CreateProcess: ReadProcessMemory error=%d\n", GetLastError()); + } + OutTrace("CreateProcess: StartCode=%x\n", StartingCode); + if(!WriteProcessMemory(lpProcessInformation->hProcess, StartAddress, &EndlessLoop, 4, &BytesCount)){ + OutTrace("CreateProcess: WriteProcessMemory error=%d\n", GetLastError()); + } + } + } +#endif OutTrace("CreateProcess: injection terminated\n", res); + break; + case EXIT_THREAD_DEBUG_EVENT: +#ifdef LOCKINJECTIONTHREADS + if(TargetHandle && StartAddress){ + if(!WriteProcessMemory(lpProcessInformation->hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ + OutTrace("CreateProcess: WriteProcessMemory error=%d\n", GetLastError()); + } + CloseHandle((HANDLE)TargetHandle); + } +#endif + bContinueDebugging=false; + default: + break; + } + if(bContinueDebugging){ + ContinueDebugEvent(debug_event.dwProcessId, + debug_event.dwThreadId, + dwContinueStatus); + } + else{ + DebugSetProcessKillOnExit(FALSE); + ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, DBG_CONTINUE); + DebugActiveProcessStop(debug_event.dwProcessId); + } + } + OutTrace("CreateProcess: detached\n", res); + } + else{ + res=(*pCreateProcessA)( + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bInheritHandles, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + lpStartupInfo, + lpProcessInformation + ); + } + + if(!res) OutTraceE("CreateProcess: ERROR err=%d\n", GetLastError()); + return res; } -#if 0 - // useless: DxWnd should hook to two processes contemporarily .... - // problem: binkplay seems to detect the screen actual size - if(TRUE){ - // get rid of /R option from binkplay argument line - if(!strncmp(lpCommandLine, "binkplay.exe ", strlen("binkplay.exe "))){ - char *rCommand; - rCommand = strstr(lpCommandLine, "/R "); - if(rCommand) memset(rCommand, ' ', strlen("/R ")); - OutTraceDW("CreateProcess: ApplicationName=\"%s\" CommandLine=\"%s\"\n", lpApplicationName, lpCommandLine); +BOOL WINAPI extGetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) +{ + BOOL res; + + OutTraceDW("GetExitCodeProcess: hProcess=%x\n", hProcess); + + if(dxw.dwFlags4 & SUPPRESSCHILD) { + OutTraceDW("GetExitCodeProcess: FAKE exit code=0\n"); + lpExitCode = 0; + return TRUE; + } + + res=(*pGetExitCodeProcess)(hProcess, lpExitCode); + if(dxw.dwFlags5 & (INJECTSON|ENABLESONHOOK)) { + if(*lpExitCode != STILL_ACTIVE){ + OutTraceDW("GetExitCodeProcess: locking mutex\n"); + extern HANDLE hLockMutex; + WaitForSingleObject(hLockMutex, 0); } } -#endif - -//#define RELEASEHOOKTOSONPROCESS TRUE -// extern void UnhookProc(); -// if(RELEASEHOOKTOSONPROCESS) UnhookProc(); - res=(*pCreateProcessA)( - lpApplicationName, - lpCommandLine, - lpProcessAttributes, - lpThreadAttributes, - bInheritHandles, - dwCreationFlags, - lpEnvironment, - lpCurrentDirectory, - lpStartupInfo, - lpProcessInformation - ); - if(!res) OutTraceE("CreateProcess: ERROR err=%d\n", GetLastError()); + OutTraceDW("GetExitCodeProcess: hProcess=%x ExitCode=%x res=%x\n", hProcess, *lpExitCode, res); return res; } diff --git a/dll/libMinHook.x86.lib b/dll/libMinHook.x86.lib new file mode 100644 index 0000000..9239fac Binary files /dev/null and b/dll/libMinHook.x86.lib differ diff --git a/dll/syslibs.h b/dll/syslibs.h index 07cd16c..a699a50 100644 --- a/dll/syslibs.h +++ b/dll/syslibs.h @@ -130,6 +130,7 @@ typedef BOOL (WINAPI *CloseHandle_Type)(HANDLE); typedef BOOL (WINAPI *QueryPerformanceFrequency_Type)(LARGE_INTEGER *); typedef BOOL (WINAPI *QueryPerformanceCounter_Type)(LARGE_INTEGER *); typedef BOOL (WINAPI *QueryPerformanceFrequency_Type)(LARGE_INTEGER *); +typedef BOOL (WINAPI *GetExitCodeProcess_Type)(HANDLE, LPDWORD); // ole32.dll: typedef HRESULT (STDAPICALLTYPE *CoCreateInstance_Type)(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID FAR*); @@ -342,6 +343,8 @@ DXWEXTERN SetFilePointer_Type pSetFilePointer DXWINITIALIZED; DXWEXTERN CloseHandle_Type pCloseHandle DXWINITIALIZED; DXWEXTERN QueryPerformanceFrequency_Type pQueryPerformanceFrequency DXWINITIALIZED; DXWEXTERN QueryPerformanceCounter_Type pQueryPerformanceCounter DXWINITIALIZED; +DXWEXTERN GetExitCodeProcess_Type pGetExitCodeProcess DXWINITIALIZED; + // ole32.dll: DXWEXTERN CoCreateInstance_Type pCoCreateInstance DXWINITIALIZED; @@ -553,6 +556,7 @@ extern HANDLE WINAPI extCreateFile(LPCTSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, extern DWORD WINAPI extSetFilePointer(HANDLE, LONG, PLONG, DWORD); extern BOOL WINAPI extCloseHandle(HANDLE); extern BOOL WINAPI extCreateProcessA(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCTSTR, LPSTARTUPINFO, LPPROCESS_INFORMATION); +extern BOOL WINAPI extGetExitCodeProcess(HANDLE, LPDWORD); extern BOOL WINAPI extQueryPerformanceFrequency(LARGE_INTEGER *); extern BOOL WINAPI extQueryPerformanceCounter(LARGE_INTEGER *); diff --git a/dll/user32.cpp b/dll/user32.cpp index 62c1bb4..fe0d6c5 100644 --- a/dll/user32.cpp +++ b/dll/user32.cpp @@ -54,8 +54,9 @@ static HookEntry_Type Hooks[]={ {HOOK_HOT_CANDIDATE, "SetWindowLongW", (FARPROC)SetWindowLongW, (FARPROC *)&pSetWindowLongW, (FARPROC)extSetWindowLongW}, {HOOK_HOT_CANDIDATE, "GetWindowLongW", (FARPROC)GetWindowLongW, (FARPROC *)&pGetWindowLongW, (FARPROC)extGetWindowLongW}, {HOOK_IAT_CANDIDATE, "IsWindowVisible", (FARPROC)NULL, (FARPROC *)&pIsWindowVisible, (FARPROC)extIsWindowVisible}, - {HOOK_IAT_CANDIDATE, "SystemParametersInfoA", (FARPROC)SystemParametersInfoA, (FARPROC *)&pSystemParametersInfoA, (FARPROC)extSystemParametersInfoA}, - {HOOK_IAT_CANDIDATE, "SystemParametersInfoW", (FARPROC)SystemParametersInfoW, (FARPROC *)&pSystemParametersInfoW, (FARPROC)extSystemParametersInfoW}, + // hot by MinHook since v2.03.07 + {HOOK_HOT_CANDIDATE, "SystemParametersInfoA", (FARPROC)SystemParametersInfoA, (FARPROC *)&pSystemParametersInfoA, (FARPROC)extSystemParametersInfoA}, + {HOOK_HOT_CANDIDATE, "SystemParametersInfoW", (FARPROC)SystemParametersInfoW, (FARPROC *)&pSystemParametersInfoW, (FARPROC)extSystemParametersInfoW}, //{HOOK_HOT_CANDIDATE, "GetActiveWindow", (FARPROC)NULL, (FARPROC *)&pGetActiveWindow, (FARPROC)extGetActiveWindow}, //{HOOK_HOT_CANDIDATE, "GetForegroundWindow", (FARPROC)NULL, (FARPROC *)&pGetForegroundWindow, (FARPROC)extGetForegroundWindow}, //{HOOK_IAT_CANDIDATE, "GetWindowTextA", (FARPROC)GetWindowTextA, (FARPROC *)&pGetWindowTextA, (FARPROC)extGetWindowTextA}, @@ -245,7 +246,6 @@ int LastCurPosX, LastCurPosY; extern GetDC_Type pGetDC; extern ReleaseDC_Type pReleaseDC; -extern DEVMODE *pSetDevMode; //extern void FixWindowFrame(HWND); extern HRESULT WINAPI sBlt(char *, LPDIRECTDRAWSURFACE, LPRECT, LPDIRECTDRAWSURFACE, LPRECT, DWORD, LPDDBLTFX, BOOL); @@ -411,18 +411,8 @@ void dxwFixMinMaxInfo(char *ApiName, HWND hwnd, LPARAM lParam) lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); lpmmi->ptMaxPosition.x=0; lpmmi->ptMaxPosition.y=0; - if(pSetDevMode){ - lpmmi->ptMaxSize.x = pSetDevMode->dmPelsWidth; - lpmmi->ptMaxSize.y = pSetDevMode->dmPelsHeight; - } - else{ - lpmmi->ptMaxSize.x = dxw.GetScreenWidth(); - lpmmi->ptMaxSize.y = dxw.GetScreenHeight(); - } - - // allow for initial dimensions .... - //if(lpmmi->ptMaxSize.x < dxw.iSizX) lpmmi->ptMaxSize.x = dxw.iSizX; - //if(lpmmi->ptMaxSize.y < dxw.iSizY) lpmmi->ptMaxSize.y = dxw.iSizY; + lpmmi->ptMaxSize.x = dxw.GetScreenWidth(); + lpmmi->ptMaxSize.y = dxw.GetScreenHeight(); OutTraceDW("%s: SET PREVENTMAXIMIZE MaxPosition=(%d,%d) MaxSize=(%d,%d)\n", ApiName, lpmmi->ptMaxPosition.x, lpmmi->ptMaxPosition.y, lpmmi->ptMaxSize.x, lpmmi->ptMaxSize.y); @@ -1114,24 +1104,6 @@ int WINAPI extGetSystemMetrics(int nindex) return res; } - // if you have a bypassed setting, use it first! - if(pSetDevMode){ - switch(nindex){ - case SM_CXFULLSCREEN: - case SM_CXSCREEN: - case SM_CXVIRTUALSCREEN: // v2.02.31 - res = pSetDevMode->dmPelsWidth; - OutTraceDW("GetDeviceCaps: fix HORZRES cap=%d\n", res); - return res; - case SM_CYFULLSCREEN: - case SM_CYSCREEN: - case SM_CYVIRTUALSCREEN: // v2.02.31 - res = pSetDevMode->dmPelsHeight; - OutTraceDW("GetDeviceCaps: fix VERTRES cap=%d\n", res); - return res; - } - } - switch(nindex){ case SM_CXFULLSCREEN: case SM_CXSCREEN: @@ -1698,32 +1670,26 @@ LONG WINAPI extEnumDisplaySettings(LPCTSTR lpszDeviceName, DWORD iModeNum, DEVMO { LONG res; OutTraceDW("EnumDisplaySettings: Devicename=%s ModeNum=%x\n", lpszDeviceName, iModeNum); - if(pSetDevMode && iModeNum==ENUM_CURRENT_SETTINGS){ - lpDevMode=pSetDevMode; - return 1; - } - else{ - res=(*pEnumDisplaySettings)(lpszDeviceName, iModeNum, lpDevMode); - if(dxw.dwFlags4 & LIMITSCREENRES){ - #define HUGE 100000 - DWORD maxw, maxh; - maxw = maxh = HUGE; - switch(dxw.MaxScreenRes){ - case DXW_NO_LIMIT: maxw=HUGE; maxh=HUGE; break; - case DXW_LIMIT_320x200: maxw=320; maxh=200; break; - case DXW_LIMIT_640x480: maxw=640; maxh=480; break; - case DXW_LIMIT_800x600: maxw=800; maxh=600; break; - case DXW_LIMIT_1024x768: maxw=1024; maxh=768; break; - case DXW_LIMIT_1280x960: maxw=1280; maxh=960; break; - } - if((lpDevMode->dmPelsWidth > maxw) || (lpDevMode->dmPelsHeight > maxh)){ - OutTraceDW("EnumDisplaySettings: limit device size=(%d,%d)\n", maxw, maxh); - lpDevMode->dmPelsWidth = maxw; - lpDevMode->dmPelsHeight = maxh; - } + res=(*pEnumDisplaySettings)(lpszDeviceName, iModeNum, lpDevMode); + if(dxw.dwFlags4 & LIMITSCREENRES){ + #define HUGE 100000 + DWORD maxw, maxh; + maxw = maxh = HUGE; + switch(dxw.MaxScreenRes){ + case DXW_NO_LIMIT: maxw=HUGE; maxh=HUGE; break; + case DXW_LIMIT_320x200: maxw=320; maxh=200; break; + case DXW_LIMIT_640x480: maxw=640; maxh=480; break; + case DXW_LIMIT_800x600: maxw=800; maxh=600; break; + case DXW_LIMIT_1024x768: maxw=1024; maxh=768; break; + case DXW_LIMIT_1280x960: maxw=1280; maxh=960; break; + } + if((lpDevMode->dmPelsWidth > maxw) || (lpDevMode->dmPelsHeight > maxh)){ + OutTraceDW("EnumDisplaySettings: limit device size=(%d,%d)\n", maxw, maxh); + lpDevMode->dmPelsWidth = maxw; + lpDevMode->dmPelsHeight = maxh; } - return res; } + return res; } LONG WINAPI extChangeDisplaySettingsA(DEVMODEA *lpDevMode, DWORD dwflags) @@ -2614,7 +2580,14 @@ BOOL WINAPI extIsWindowVisible(HWND hwnd) BOOL WINAPI extSystemParametersInfoA(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni) { BOOL ret; - OutTraceDW("SystemParametersInfo: Action=%x Param=%x WinIni=%x\n", uiAction, uiParam, fWinIni); + OutTraceDW("SystemParametersInfoA: Action=%x Param=%x WinIni=%x\n", uiAction, uiParam, fWinIni); + switch(uiAction){ + case SPI_SETKEYBOARDDELAY: + case SPI_SETKEYBOARDSPEED: + OutTraceDW("SystemParametersInfoA: bypass action=%x\n", uiAction); + return TRUE; + break; + } ret=(*pSystemParametersInfoA)(uiAction, uiParam, pvParam, fWinIni); if(uiAction==SPI_GETWORKAREA){ LPRECT cli = (LPRECT)pvParam; @@ -2622,7 +2595,7 @@ BOOL WINAPI extSystemParametersInfoA(UINT uiAction, UINT uiParam, PVOID pvParam, cli->left = 0; cli->bottom = dxw.GetScreenHeight(); cli->right = dxw.GetScreenWidth(); - OutTraceDW("SystemParametersInfo: resized client workarea rect=(%d,%d)-(%d,%d)\n", cli->left, cli->top, cli->right, cli->bottom); + OutTraceDW("SystemParametersInfoA: resized client workarea rect=(%d,%d)-(%d,%d)\n", cli->left, cli->top, cli->right, cli->bottom); } return ret; } @@ -2630,7 +2603,14 @@ BOOL WINAPI extSystemParametersInfoA(UINT uiAction, UINT uiParam, PVOID pvParam, BOOL WINAPI extSystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni) { BOOL ret; - OutTraceDW("SystemParametersInfo: Action=%x Param=%x WinIni=%x\n", uiAction, uiParam, fWinIni); + OutTraceDW("SystemParametersInfoW: Action=%x Param=%x WinIni=%x\n", uiAction, uiParam, fWinIni); + switch(uiAction){ + case SPI_SETKEYBOARDDELAY: + case SPI_SETKEYBOARDSPEED: + OutTraceDW("SystemParametersInfoW: bypass action=%x\n", uiAction); + return TRUE; + break; + } ret=(*pSystemParametersInfoW)(uiAction, uiParam, pvParam, fWinIni); if(uiAction==SPI_GETWORKAREA){ LPRECT cli = (LPRECT)pvParam; @@ -2638,7 +2618,7 @@ BOOL WINAPI extSystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, cli->left = 0; cli->bottom = dxw.GetScreenHeight(); cli->right = dxw.GetScreenWidth(); - OutTraceDW("SystemParametersInfo: resized client workarea rect=(%d,%d)-(%d,%d)\n", cli->left, cli->top, cli->right, cli->bottom); + OutTraceDW("SystemParametersInfoW: resized client workarea rect=(%d,%d)-(%d,%d)\n", cli->left, cli->top, cli->right, cli->bottom); } return ret; } diff --git a/host/Inject.cpp b/host/Inject.cpp index 9ae6c69..cca0596 100644 --- a/host/Inject.cpp +++ b/host/Inject.cpp @@ -5,6 +5,8 @@ #include #include +#include + #define WIN32_LEAN_AND_MEAN #define true 1 @@ -36,28 +38,35 @@ BOOL Inject(DWORD pID, const char * DLL_NAME) return true; } -DWORD GetTargetThreadIDFromProcName(const char * ProcName) -{ - PROCESSENTRY32 pe; - HANDLE thSnapShot; - BOOL retval, ProcFound = false; - thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if(thSnapShot == INVALID_HANDLE_VALUE) - { - MessageBox(NULL, "Error: Unable to create toolhelp snapshot!", "2MLoader", MB_OK); - //printf("Error: Unable to create toolhelp snapshot!"); - return false; - } - pe.dwSize = sizeof(PROCESSENTRY32); - retval = Process32First(thSnapShot, &pe); - while(retval) - { - if(StrStrI(pe.szExeFile, ProcName)) - { - return pe.th32ProcessID; - } - retval = Process32Next(thSnapShot, &pe); - } - return 0; -} +#define STATUS_SUCCESS ((NTSTATUS)0x000 00000L) +#define ThreadQuerySetWin32StartAddress 9 +LPVOID GetThreadStartAddress(HANDLE hThread) +{ + NTSTATUS ntStatus; + HANDLE hDupHandle; + HMODULE hLibNTHandle; + LPVOID dwStartAddress; + + typedef NTSTATUS (WINAPI *NtQueryInformationThread_Type)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG); + hLibNTHandle = GetModuleHandle("ntdll.dll"); + if(!hLibNTHandle) return 0; + + NtQueryInformationThread_Type NtQueryInformationThread = + (NtQueryInformationThread_Type)GetProcAddress(hLibNTHandle, "NtQueryInformationThread"); + + if(NtQueryInformationThread == NULL) return 0; + + HANDLE hCurrentProcess = GetCurrentProcess(); + if(!DuplicateHandle(hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){ + SetLastError(ERROR_ACCESS_DENIED); + return 0; + } + + ntStatus = NtQueryInformationThread(hDupHandle, (THREADINFOCLASS)ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD), NULL); + CloseHandle(hDupHandle); + CloseHandle(hLibNTHandle); + //if(ntStatus != STATUS_SUCCESS) return 0; + + return dwStartAddress; +} \ No newline at end of file diff --git a/host/Resource.h b/host/Resource.h index 7945a0e..9c77855 100644 Binary files a/host/Resource.h and b/host/Resource.h differ diff --git a/host/TabNotes.cpp b/host/TabNotes.cpp new file mode 100644 index 0000000..0990fb8 --- /dev/null +++ b/host/TabNotes.cpp @@ -0,0 +1,55 @@ +// TabNotes.cpp : implementation file +// + +#include "stdafx.h" +#include "TargetDlg.h" +#include "TabNotes.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CTabNotes dialog + +CTabNotes::CTabNotes(CWnd* pParent /*=NULL*/) +// : CTargetDlg(pParent) + : CDialog(CTabNotes::IDD, pParent) +{ + //{{AFX_DATA_INIT(CTabNotes) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + +void CTabNotes::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); + DDX_Text(pDX, IDC_NOTES, cTarget->m_Notes); +} + +BEGIN_MESSAGE_MAP(CTabNotes, CDialog) + //{{AFX_MSG_MAP(CTabNotes) + // NOTE: the ClassWizard will add message map macros here + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CTabNotes message handlers + + +//BOOL CTabNotes::OnInitDialog() +//{ +// AfxEnableControlContainer(); +// CListBox *List; +// CTargetDlg *cTarget = ((CTargetDlg *)(this->GetParent()->GetParent())); +// int i; +// List=(CListBox *)this->GetDlgItem(IDC_LISTFAKE); +// List->ResetContent(); +// for(i=0; i<9; i++) List->AddString(WinVersions[i].sName); +// List->SetCurSel(cTarget->m_FakeVersion); +// CDialog::OnInitDialog(); +// return TRUE; +//} \ No newline at end of file diff --git a/host/TabNotes.h b/host/TabNotes.h new file mode 100644 index 0000000..9da054b --- /dev/null +++ b/host/TabNotes.h @@ -0,0 +1,45 @@ +#if !defined(AFX_TABNOTES_H__798A9124_C906_446C_822D_322B5AB6C4C4__INCLUDED_) +#define AFX_TABNOTES_H__798A9124_C906_446C_822D_322B5AB6C4C4__INCLUDED_ + +#include "resource.h" +#include "TargetDlg.h" + +///////////////////////////////////////////////////////////////////////////// +// CTabNotes dialog + +//class CTabNotes : public CTargetDlg +class CTabNotes : public CDialog +{ +// Construction +public: + CTabNotes(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(CTabDirectX) + enum { IDD = IDD_TAB_NOTES }; + // NOTE: the ClassWizard will add data members here + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CTabDirectX) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //BOOL OnInitDialog(); + + // Generated message map functions + //{{AFX_MSG(CTabDirectX) + // NOTE: the ClassWizard will add member functions here + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_TABTHREE_H__798A9124_C906_446C_822D_322B5AB6C4C4__INCLUDED_) diff --git a/host/TabSysLibs.cpp b/host/TabSysLibs.cpp index 4c72038..3dcfe92 100644 --- a/host/TabSysLibs.cpp +++ b/host/TabSysLibs.cpp @@ -40,6 +40,9 @@ void CTabSysLibs::DoDataExchange(CDataExchange* pDX) // MCI DDX_Check(pDX, IDC_REMAPMCI, cTarget->m_RemapMCI); + + // Kernel32 + DDX_Radio(pDX, IDC_SONDEFAULT, cTarget->m_SonProcessMode); } BEGIN_MESSAGE_MAP(CTabSysLibs, CDialog) diff --git a/host/TabWindow.cpp b/host/TabWindow.cpp index 7307df5..df40232 100644 --- a/host/TabWindow.cpp +++ b/host/TabWindow.cpp @@ -43,7 +43,7 @@ void CTabWindow::DoDataExchange(CDataExchange* pDX) DDX_Check(pDX, IDC_REFRESHONRESIZE, cTarget->m_RefreshOnResize); DDX_Check(pDX, IDC_FIXD3DFRAME, cTarget->m_FixD3DFrame); DDX_Check(pDX, IDC_NOWINDOWMOVE, cTarget->m_NoWindowMove); - DDX_Check(pDX, IDC_SUPPRESSCHILD, cTarget->m_SuppressChild); + //DDX_Check(pDX, IDC_SUPPRESSCHILD, cTarget->m_SuppressChild); DDX_Check(pDX, IDC_HIDEDESKTOP, cTarget->m_HideDesktop); // color management diff --git a/host/TargetDlg.cpp b/host/TargetDlg.cpp index 1b2a563..9b0c06e 100644 --- a/host/TargetDlg.cpp +++ b/host/TargetDlg.cpp @@ -52,7 +52,7 @@ CTargetDlg::CTargetDlg(CWnd* pParent /*=NULL*/) m_FixRefCounter = TRUE; // default true !! m_ReturnNullRef = FALSE; m_NoD3DReset = FALSE; - m_SuppressChild = FALSE; + //m_SuppressChild = FALSE; m_HideDesktop = FALSE; m_LockSysColors = FALSE; m_ForceYUVtoRGB = FALSE; @@ -193,6 +193,7 @@ BOOL CTargetDlg::OnInitDialog() m_tabdxTabCtrl.InsertItem(i++, _T("Log")); m_tabdxTabCtrl.InsertItem(i++, _T("Libs")); m_tabdxTabCtrl.InsertItem(i++, _T("Compat")); + m_tabdxTabCtrl.InsertItem(i++, _T("Notes")); if (gbDebug) m_tabdxTabCtrl.InsertItem(i++, _T("Debug")); #else char sCaption[48+1]; @@ -214,6 +215,8 @@ BOOL CTargetDlg::OnInitDialog() m_tabdxTabCtrl.InsertItem(i++, _T(sCaption)); LoadString(AfxGetResourceHandle(), DXW_TAB_COMPAT, sCaption, sizeof(sCaption)); m_tabdxTabCtrl.InsertItem(i++, _T(sCaption)); + LoadString(AfxGetResourceHandle(), DXW_TAB_NOTES, sCaption, sizeof(sCaption)); + m_tabdxTabCtrl.InsertItem(i++, _T(sCaption)); LoadString(AfxGetResourceHandle(), DXW_TAB_DEBUG, sCaption, sizeof(sCaption)); if (gbDebug) m_tabdxTabCtrl.InsertItem(i++, _T(sCaption)); #endif diff --git a/host/TargetDlg.h b/host/TargetDlg.h index 58bd0ae..9ffe3ab 100644 --- a/host/TargetDlg.h +++ b/host/TargetDlg.h @@ -31,6 +31,7 @@ public: int m_DCEmulationMode; int m_MouseVisibility; int m_TextureHandling; + int m_SonProcessMode; BOOL m_HookDI; BOOL m_ModifyMouse; BOOL m_OutProxyTrace; @@ -66,6 +67,7 @@ public: CString m_Module; CString m_Title; CString m_OpenGLLib; + CString m_Notes; BOOL m_SaveLoad; BOOL m_SlowDown; BOOL m_BlitFromBackBuffer; @@ -164,7 +166,7 @@ public: BOOL m_FixRefCounter; BOOL m_ReturnNullRef; BOOL m_NoD3DReset; - BOOL m_SuppressChild; + //BOOL m_SuppressChild; BOOL m_HideDesktop; BOOL m_LockSysColors; BOOL m_SingleProcAffinity; diff --git a/host/dxTabCtrl.cpp b/host/dxTabCtrl.cpp index 9086e0b..89699c8 100644 --- a/host/dxTabCtrl.cpp +++ b/host/dxTabCtrl.cpp @@ -31,6 +31,7 @@ #include "TabOpenGL.h" #include "TabCompat.h" #include "TabColor.h" +#include "TabNotes.h" #include "TabSysLibs.h" #include "TabDebug.h" @@ -57,6 +58,7 @@ CDXTabCtrl::CDXTabCtrl() m_tabPages[i++]=new CTabLogs; m_tabPages[i++]=new CTabSysLibs; m_tabPages[i++]=new CTabCompat; + m_tabPages[i++]=new CTabNotes; if (gbDebug) m_tabPages[i++]=new CTabDebug; m_nNumberOfPages=i; @@ -83,6 +85,7 @@ void CDXTabCtrl::Init() m_tabPages[i++]->Create(IDD_TAB_LOG, this); m_tabPages[i++]->Create(IDD_TAB_SYSLIBS, this); m_tabPages[i++]->Create(IDD_TAB_COMPAT, this); + m_tabPages[i++]->Create(IDD_TAB_NOTES, this); if (gbDebug) m_tabPages[i++]->Create(IDD_TAB_DEBUG, this); for(int nCount=0; nCount < m_nNumberOfPages; nCount++){ diff --git a/host/dxwndhost.aps b/host/dxwndhost.aps index a7c5aef..ed57fe9 100644 Binary files a/host/dxwndhost.aps and b/host/dxwndhost.aps differ diff --git a/host/dxwndhost.clw b/host/dxwndhost.clw deleted file mode 100644 index fd0cdd1..0000000 --- a/host/dxwndhost.clw +++ /dev/null @@ -1,156 +0,0 @@ -; CLW t@C MFC ClassWizard ̏܂ł܂B - -[General Info] -Version=1 -LastClass=CTargetDlg -LastTemplate=CDialog -NewFileInclude1=#include "stdafx.h" -NewFileInclude2=#include "dxwndhost.h" -LastPage=0 - -ClassCount=6 -Class1=CDxwndhostApp -Class2=CDxwndhostDoc -Class3=CDxwndhostView -Class4=CMainFrame - -ResourceCount=4 -Resource1=IDD_ABOUTBOX -Resource2=IDR_MENU_POPUP -Class5=CAboutDlg -Class6=CTargetDlg -Resource3=IDR_MAINFRAME -Resource4=IDD_TARGET - -[CLS:CDxwndhostApp] -Type=0 -HeaderFile=dxwndhost.h -ImplementationFile=dxwndhost.cpp -Filter=N - -[CLS:CDxwndhostDoc] -Type=0 -HeaderFile=dxwndhostDoc.h -ImplementationFile=dxwndhostDoc.cpp -Filter=N - -[CLS:CDxwndhostView] -Type=0 -HeaderFile=dxwndhostView.h -ImplementationFile=dxwndhostView.cpp -Filter=C -BaseClass=CListView -VirtualFilter=VWC -LastObject=ID_RUN - - -[CLS:CMainFrame] -Type=0 -HeaderFile=MainFrm.h -ImplementationFile=MainFrm.cpp -Filter=T -LastObject=ID_MENUITEM32774 - - - - -[CLS:CAboutDlg] -Type=0 -HeaderFile=dxwndhost.cpp -ImplementationFile=dxwndhost.cpp -Filter=D -LastObject=IDC_VERSION -BaseClass=CDialog -VirtualFilter=dWC - -[DLG:IDD_ABOUTBOX] -Type=1 -Class=CAboutDlg -ControlCount=4 -Control1=IDC_STATIC,static,1342177283 -Control2=IDC_VERSION,static,1342308480 -Control3=IDC_STATIC,static,1342308352 -Control4=IDOK,button,1342373889 - -[MNU:IDR_MAINFRAME] -Type=1 -Class=CMainFrame -Command1=ID_APP_EXIT -Command2=ID_RUN -Command3=ID_MODIFY -Command4=ID_DELETE -Command5=ID_ADD -Command6=ID_APP_ABOUT -CommandCount=6 - -[ACL:IDR_MAINFRAME] -Type=1 -Class=CMainFrame -Command1=ID_FILE_NEW -Command2=ID_FILE_OPEN -Command3=ID_FILE_SAVE -Command4=ID_EDIT_UNDO -Command5=ID_EDIT_CUT -Command6=ID_EDIT_COPY -Command7=ID_EDIT_PASTE -Command8=ID_EDIT_UNDO -Command9=ID_EDIT_CUT -Command10=ID_EDIT_COPY -Command11=ID_EDIT_PASTE -Command12=ID_NEXT_PANE -Command13=ID_PREV_PANE -CommandCount=13 - -[DLG:IDD_TARGET] -Type=1 -Class=CTargetDlg -ControlCount=30 -Control1=IDC_FILE,edit,1350631552 -Control2=IDC_OPEN,button,1342242816 -Control3=IDC_AUTO,button,1342308361 -Control4=IDC_DIRECTX1,button,1342177289 -Control5=IDC_DIRECTX7,button,1342177289 -Control6=IDC_DIRECTX8,button,1342177289 -Control7=IDC_DIRECTX9,button,1342177289 -Control8=IDC_UNNOTIFY,button,1342242819 -Control9=IDC_EMULATEPAL,button,1342242819 -Control10=IDC_HOOKDI,button,1342242819 -Control11=IDC_INITX,edit,1350639744 -Control12=IDC_INITY,edit,1350639744 -Control13=IDC_MINX,edit,1350631552 -Control14=IDC_MINY,edit,1350631552 -Control15=IDC_MAXX,edit,1350631552 -Control16=IDC_MAXY,edit,1350631552 -Control17=IDC_MODIFYMOUSE,button,1342242819 -Control18=IDC_OUTTRACE,button,1342242819 -Control19=IDC_SAVELOAD,button,1342242819 -Control20=IDOK,button,1342242817 -Control21=IDCANCEL,button,1342242816 -Control22=IDC_STATIC,button,1342308359 -Control23=IDC_STATIC,static,1342308352 -Control24=IDC_STATIC,static,1342308352 -Control25=IDC_STATIC,static,1342308352 -Control26=IDC_STATIC,static,1342308352 -Control27=IDC_STATIC,static,1342308352 -Control28=IDC_STATIC,static,1342308352 -Control29=IDC_STATIC,static,1342308352 -Control30=IDC_STATIC,static,1342308352 - -[CLS:CTargetDlg] -Type=0 -HeaderFile=TargetDlg.h -ImplementationFile=TargetDlg.cpp -BaseClass=CDialog -Filter=D -LastObject=IDC_FILE -VirtualFilter=dWC - -[MNU:IDR_MENU_POPUP] -Type=1 -Class=CDxwndhostView -Command1=ID_PRUN -Command2=ID_PMODIFY -Command3=ID_PDELETE -Command4=ID_PADD -CommandCount=4 - diff --git a/host/dxwndhost.h b/host/dxwndhost.h index c948818..0932920 100644 --- a/host/dxwndhost.h +++ b/host/dxwndhost.h @@ -22,10 +22,13 @@ extern int MessageBoxLangArg(UINT, UINT, UINT, ...); // to the dxwnd hook callback, so they are left in a separate array to save // the (limited) IPC space and allow for more record entryes (currently 255). +#define MAX_NOTES 1024 + typedef struct PRIVATEMAP { char title[40+1]; char launchpath[MAX_PATH+1]; + char notes[MAX_NOTES+1]; }PRIVATEMAP; ///////////////////////////////////////////////////////////////////////////// diff --git a/host/dxwndhost.opt b/host/dxwndhost.opt deleted file mode 100644 index 7e92732..0000000 Binary files a/host/dxwndhost.opt and /dev/null differ diff --git a/host/dxwndhost.plg b/host/dxwndhost.plg deleted file mode 100644 index fbcb14c..0000000 --- a/host/dxwndhost.plg +++ /dev/null @@ -1,16 +0,0 @@ - - -
-

ނ۸

-

---------------------\: dxwndhost - Win32 Release-------------------- -

-

ײ

- - - -

-dxwnd.exe - װ 0Ax 0 -
- - diff --git a/host/dxwndhost.rc b/host/dxwndhost.rc index 8a84921..5861eaf 100644 Binary files a/host/dxwndhost.rc and b/host/dxwndhost.rc differ diff --git a/host/dxwndhost.vs2008.suo b/host/dxwndhost.vs2008.suo index 34016bb..79bb7de 100644 Binary files a/host/dxwndhost.vs2008.suo and b/host/dxwndhost.vs2008.suo differ diff --git a/host/dxwndhost.vs2008.vcproj b/host/dxwndhost.vs2008.vcproj index de9ad05..50c6eb3 100644 --- a/host/dxwndhost.vs2008.vcproj +++ b/host/dxwndhost.vs2008.vcproj @@ -421,6 +421,10 @@ RelativePath=".\TabLogs.cpp" >
+ + @@ -538,6 +542,10 @@ RelativePath=".\TabLogs.h" > + + diff --git a/host/dxwndhostView.cpp b/host/dxwndhostView.cpp index e8dc9ce..9cc3fcb 100644 --- a/host/dxwndhostView.cpp +++ b/host/dxwndhostView.cpp @@ -33,6 +33,48 @@ extern int KillProcByName(char *, BOOL); PRIVATEMAP *pTitles; // global ptr: get rid of it!! TARGETMAP *pTargets; // idem. +#define LOCKINJECTIONTHREADS + + +static char *Escape(char *s) +{ + static char tmp[1024]; + char *t = tmp; + for(; *s; s++){ + if(*s=='\n'){ + *t++ = '\\'; + *t++ = 'n'; + } + else{ + if(*s == '\r'){ + } + else{ + *t++ = *s; + } + } + } + *t=0; + return tmp; +} + +static char *Unescape(char *s) +{ + static char tmp[1024]; + char *t = tmp; + for(; *s; s++){ + if((*s=='\\') && (*(s+1)=='n')){ + *t++ = '\r'; + *t++ = '\n'; + s++; + } + else{ + *t++ = *s; + } + } + *t=0; + return tmp; +} + ///////////////////////////////////////////////////////////////////////////// // CDxwndhostView @@ -167,6 +209,13 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) case 3: t->flags5 |= TEXTUREHACK; break; } + switch(dlg->m_SonProcessMode){ + case 0: break; + case 1: t->flags4 |= SUPPRESSCHILD; break; + case 2: t->flags5 |= ENABLESONHOOK; break; + case 3: t->flags5 |= INJECTSON; break; + } + if(dlg->m_HookDI) t->flags |= HOOKDI; if(dlg->m_ModifyMouse) t->flags |= MODIFYMOUSE; if(dlg->m_OutProxyTrace) t->tflags |= OUTPROXYTRACE; @@ -209,7 +258,7 @@ static void SetTargetFromDlg(TARGETMAP *t, CTargetDlg *dlg) if(dlg->m_FixRefCounter) t->flags4 |= FIXREFCOUNTER; if(dlg->m_ReturnNullRef) t->flags4 |= RETURNNULLREF; if(dlg->m_NoD3DReset) t->flags4 |= NOD3DRESET; - if(dlg->m_SuppressChild) t->flags4 |= SUPPRESSCHILD; + //if(dlg->m_SuppressChild) t->flags4 |= SUPPRESSCHILD; if(dlg->m_HideDesktop) t->flags4 |= HIDEDESKTOP; if(dlg->m_LockSysColors) t->flags3 |= LOCKSYSCOLORS; if(dlg->m_ForceYUVtoRGB) t->flags3 |= YUV2RGB; @@ -362,6 +411,11 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) if(t->flags5 & TEXTUREDUMP) dlg->m_TextureHandling = 2; if(t->flags5 & TEXTUREHACK) dlg->m_TextureHandling = 3; + dlg->m_SonProcessMode = 0; + if(t->flags4 & SUPPRESSCHILD) dlg->m_SonProcessMode = 1; + if(t->flags5 & ENABLESONHOOK) dlg->m_SonProcessMode = 2; + if(t->flags5 & INJECTSON) dlg->m_SonProcessMode = 3; + dlg->m_HookDI = t->flags & HOOKDI ? 1 : 0; dlg->m_ModifyMouse = t->flags & MODIFYMOUSE ? 1 : 0; dlg->m_OutProxyTrace = t->tflags & OUTPROXYTRACE ? 1 : 0; @@ -392,7 +446,7 @@ static void SetDlgFromTarget(TARGETMAP *t, CTargetDlg *dlg) dlg->m_FixRefCounter = t->flags4 & FIXREFCOUNTER ? 1 : 0; dlg->m_ReturnNullRef = t->flags4 & RETURNNULLREF ? 1 : 0; dlg->m_NoD3DReset = t->flags4 & NOD3DRESET ? 1 : 0; - dlg->m_SuppressChild = t->flags4 & SUPPRESSCHILD ? 1 : 0; + //dlg->m_SuppressChild = t->flags4 & SUPPRESSCHILD ? 1 : 0; dlg->m_HideDesktop = t->flags4 & HIDEDESKTOP ? 1 : 0; dlg->m_LockSysColors = t->flags3 & LOCKSYSCOLORS ? 1 : 0; dlg->m_ForceRGBtoYUV = t->flags3 & RGB2YUV ? 1 : 0; @@ -517,6 +571,8 @@ static void SaveConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, WritePrivateProfileString("target", key, TargetMap->module, InitPath); sprintf_s(key, sizeof(key), "opengllib%i", i); WritePrivateProfileString("target", key, TargetMap->OpenGLLib, InitPath); + sprintf_s(key, sizeof(key), "notes%i", i); + WritePrivateProfileString("target", key, Escape(PrivateMap->notes), InitPath); sprintf_s(key, sizeof(key), "ver%i", i); sprintf_s(val, sizeof(val), "%i", TargetMap->dxversion); WritePrivateProfileString("target", key, val, InitPath); @@ -638,12 +694,13 @@ static void ClearTarget(int i, char *InitPath) WritePrivateProfileString("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "maxres%i", i); WritePrivateProfileString("target", key, 0, InitPath); + sprintf_s(key, sizeof(key), "notes%i", i); + WritePrivateProfileString("target", key, 0, InitPath); } static int LoadConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, char *InitPath) { char key[32]; - DWORD flags; extern BOOL gbDebug; sprintf_s(key, sizeof(key), "path%i", i); GetPrivateProfileString("target", key, "", TargetMap->path, MAX_PATH, InitPath); @@ -656,22 +713,15 @@ static int LoadConfigItem(TARGETMAP *TargetMap, PRIVATEMAP *PrivateMap, int i, c GetPrivateProfileString("target", key, "", TargetMap->module, sizeof(TargetMap->module)-1, InitPath); sprintf_s(key, sizeof(key), "opengllib%i", i); GetPrivateProfileString("target", key, "", TargetMap->OpenGLLib, sizeof(TargetMap->OpenGLLib)-1, InitPath); + sprintf_s(key, sizeof(key), "notes%i", i); + GetPrivateProfileString("target", key, "", PrivateMap->notes, MAX_NOTES, InitPath); + strcpy(PrivateMap->notes, Unescape(PrivateMap->notes)); sprintf_s(key, sizeof(key), "ver%i", i); TargetMap->dxversion = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "coord%i", i); TargetMap->coordinates = GetPrivateProfileInt("target", key, 0, InitPath); - sprintf_s(key, sizeof(key), "flag%i", i); TargetMap->flags = GetPrivateProfileInt("target", key, 0, InitPath); - //// be sure just one of the emulation flags is set - //flags = TargetMap->flags; - //TargetMap->flags &= ~EMULATEFLAGS; - //do{ - // if(flags & EMULATESURFACE) {TargetMap->flags |= EMULATESURFACE; break;} - // if(flags & EMULATEBUFFER) {TargetMap->flags |= EMULATEBUFFER; break;} - // if(flags & LOCKEDSURFACE) {TargetMap->flags |= LOCKEDSURFACE; break;} - //} while (0); - sprintf_s(key, sizeof(key), "flagg%i", i); TargetMap->flags2 = GetPrivateProfileInt("target", key, 0, InitPath); sprintf_s(key, sizeof(key), "flagh%i", i); @@ -980,10 +1030,12 @@ void CDxwndhostView::OnModify() pos = listctrl.GetFirstSelectedItemPosition(); i = listctrl.GetNextSelectedItem(pos); dlg.m_Title = TitleMaps[i].title; + dlg.m_Notes = TitleMaps[i].notes; dlg.m_LaunchPath = TitleMaps[i].launchpath; SetDlgFromTarget(&TargetMaps[i], &dlg); if(dlg.DoModal() == IDOK && dlg.m_FilePath.GetLength()){ strncpy(TitleMaps[i].title, dlg.m_Title, 40); + strncpy(TitleMaps[i].notes, dlg.m_Notes, MAX_NOTES); strncpy(TitleMaps[i].launchpath, dlg.m_LaunchPath, MAX_PATH); SetTargetFromDlg(&TargetMaps[i], &dlg); CListCtrl& listctrl = GetListCtrl(); @@ -1283,6 +1335,7 @@ void CDxwndhostView::OnAdd() memset(&TargetMaps[i],0,sizeof(TARGETMAP)); // clean up, just in case.... if(dlg.DoModal() == IDOK && dlg.m_FilePath.GetLength()){ strncpy(TitleMaps[i].title, dlg.m_Title, 40); + strncpy(TitleMaps[i].notes, dlg.m_Notes, MAX_NOTES); strncpy(TitleMaps[i].launchpath, dlg.m_LaunchPath, MAX_PATH); SetTargetFromDlg(&TargetMaps[i], &dlg); CListCtrl& listctrl = GetListCtrl(); @@ -1623,38 +1676,52 @@ DWORD WINAPI StartDebug(void *p) { ThreadInfo_Type *ThInfo; STARTUPINFO sinfo; - PROCESS_INFORMATION pinfo, *pi; + PROCESS_INFORMATION pinfo; + char path[MAX_PATH]; +#ifdef DXWDEBUGSTEPPING + PROCESS_INFORMATION *pi; CREATE_THREAD_DEBUG_INFO *ti; LOAD_DLL_DEBUG_INFO *li; UNLOAD_DLL_DEBUG_INFO *ui; EXCEPTION_DEBUG_INFO *ei; EXIT_PROCESS_DEBUG_INFO *xpi; EXIT_THREAD_DEBUG_INFO *xti; - char path[MAX_PATH]; - BOOL step=FALSE; // initialize to TRUE to enable + int res; + BOOL step=TRUE; // initialize to TRUE to enable BOOL stepdll=FALSE; // initialize to TRUE to enable +#endif +#ifdef LOCKINJECTIONTHREADS + DWORD StartingCode; + LPVOID StartAddress = 0; + DWORD TargetHandle = NULL; +#endif extern char *GetFileNameFromHandle(HANDLE); + bool bContinueDebugging; + char DebugMessage[256+1]; ThInfo = (ThreadInfo_Type *)p; ZeroMemory(&sinfo, sizeof(sinfo)); sinfo.cb = sizeof(sinfo); strcpy_s(path, sizeof(path), ThInfo->TM->path); PathRemoveFileSpec(path); - CreateProcess(NULL, + if(!CreateProcess(NULL, (strlen(ThInfo->PM->launchpath)>0) ? ThInfo->PM->launchpath : ThInfo->TM->path, - 0, 0, false, DEBUG_ONLY_THIS_PROCESS, NULL, path, &sinfo, &pinfo); + 0, 0, false, DEBUG_PROCESS|DEBUG_ONLY_THIS_PROCESS, NULL, path, &sinfo, &pinfo)){ + sprintf(DebugMessage, "CREATE PROCESS error=%d", GetLastError()); + MessageBoxEx(0, DebugMessage, "ERROR", MB_YESNO | MB_ICONQUESTION, NULL); + } + CString strEventMessage; DEBUG_EVENT debug_event ={0}; - bool bContinueDebugging = true; + bContinueDebugging = true; DWORD dwContinueStatus = DBG_CONTINUE; while(bContinueDebugging) { - int res; - char DebugMessage[256+1]; dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED; if (!WaitForDebugEvent(&debug_event, INFINITE)) return TRUE; switch(debug_event.dwDebugEventCode){ case EXIT_PROCESS_DEBUG_EVENT: +#ifdef DXWDEBUGSTEPPING if(step){ // DXW_STRING_STEPPING xpi=(EXIT_PROCESS_DEBUG_INFO *)&debug_event.u; @@ -1662,30 +1729,54 @@ DWORD WINAPI StartDebug(void *p) res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); if(res!=IDYES) step=FALSE; } +#endif bContinueDebugging=false; break; case CREATE_PROCESS_DEBUG_EVENT: - // wait for process to stabilize .... - // ref: problems in setting default exception handler in Tomb Raider IV demo - if(ThInfo->TM->flags & HANDLEEXCEPTIONS) { - Sleep(500); - MessageBoxLang(DXW_STRING_EXCEPTION, DXW_STRING_WAIT, MB_OK); - } +#ifdef DXWDEBUGSTEPPING if(step){ pi=(PROCESS_INFORMATION *)&debug_event.u; - sprintf(DebugMessage, "CREATE PROCESS hProcess=%x dwProcessId=%x path=%s", - pi->hProcess, pi->dwProcessId, GetFileNameFromHandle(pi->hProcess)); + sprintf(DebugMessage, "CREATE PROCESS hProcess=%x hThread=%x dwProcessId=%x dwThreadId=%x path=%s", + pi->hProcess, pi->hThread, pi->dwProcessId, pi->dwThreadId, GetFileNameFromHandle(pi->hProcess)); res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); if(res!=IDYES) step=FALSE; } +#endif GetFullPathName("dxwnd.dll", MAX_PATH, path, NULL); if(!Inject(pinfo.dwProcessId, path)){ // DXW_STRING_INJECTION sprintf(DebugMessage,"Injection error: pid=%x dll=%s", pinfo.dwProcessId, path); MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); } +#ifdef LOCKINJECTIONTHREADS + extern LPVOID GetThreadStartAddress(HANDLE); + DWORD EndlessLoop; + EndlessLoop=0x9090FEEB; // careful: it's BIG ENDIAN: EB FE 90 90 + SIZE_T BytesCount; + TargetHandle = (DWORD)OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, FALSE, pinfo.dwProcessId); + if(TargetHandle){ + //sprintf(DebugMessage,"OpenProcess returns=%x", TargetHandle); + //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); + StartAddress = GetThreadStartAddress(pinfo.hThread); + //sprintf(DebugMessage,"GetThreadStartAddress returns=%x", StartAddress); + //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); + if(StartAddress){ + if(!ReadProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ + sprintf(DebugMessage,"ReadProcessMemory error=%d", GetLastError()); + MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); + } + //sprintf(DebugMessage,"ReadProcessMemory got=%x", StartingCode); + //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); + if(!WriteProcessMemory(pinfo.hProcess, StartAddress, &EndlessLoop, 4, &BytesCount)){ + sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError()); + MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); + } + } + } +#endif break; case CREATE_THREAD_DEBUG_EVENT: +#ifdef DXWDEBUGSTEPPING if(step){ ti=(CREATE_THREAD_DEBUG_INFO *)&debug_event.u; sprintf(DebugMessage, "CREATE THREAD hThread=%x lpThreadLocalBase=%x lpStartAddress=%x", @@ -1693,37 +1784,59 @@ DWORD WINAPI StartDebug(void *p) res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); if(res!=IDYES) step=FALSE; } +#endif break; case EXIT_THREAD_DEBUG_EVENT: +#ifdef DXWDEBUGSTEPPING if(step){ xti=(EXIT_THREAD_DEBUG_INFO *)&debug_event.u; sprintf(DebugMessage, "EXIT THREAD RetCode=%x", xti->dwExitCode); res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); if(res!=IDYES) step=FALSE; } +#endif +#ifdef LOCKINJECTIONTHREADS + if(TargetHandle && StartAddress){ + //sprintf(DebugMessage,"OpenProcess returns=%x", TargetHandle); + //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); + if(!WriteProcessMemory(pinfo.hProcess, StartAddress, &StartingCode, 4, &BytesCount)){ + sprintf(DebugMessage,"WriteProcessMemory error=%d", GetLastError()); + MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); + } + //sprintf(DebugMessage,"WriteProcessMemory recovered=%x", StartingCode); + //MessageBoxEx(0, DebugMessage, "Injection", MB_ICONEXCLAMATION, NULL); + CloseHandle((HANDLE)TargetHandle); + } +#endif + bContinueDebugging=false; break; case LOAD_DLL_DEBUG_EVENT: +#ifdef DXWDEBUGSTEPPING if(stepdll){ li=(LOAD_DLL_DEBUG_INFO *)&debug_event.u; sprintf(DebugMessage, "LOAD DLL hFile=%x path=%s", li->hFile, GetFileNameFromHandle(li->hFile)); res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) stepdll=FALSE; + if(res!=IDYES) stepdll=FALSE; } +#endif break; case UNLOAD_DLL_DEBUG_EVENT: +#ifdef DXWDEBUGSTEPPING if(stepdll){ ui=(UNLOAD_DLL_DEBUG_INFO *)&debug_event.u; sprintf(DebugMessage, "UNLOAD DLL Base=%x", ui->lpBaseOfDll); res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); - if(res!=IDYES) stepdll=FALSE; + if(res!=IDYES) stepdll=FALSE; } +#endif break; case OUTPUT_DEBUG_STRING_EVENT: break; case EXCEPTION_DEBUG_EVENT: - ei=(EXCEPTION_DEBUG_INFO *)&debug_event.u; +#ifdef DXWDEBUGSTEPPING if(step){ + ei=(EXCEPTION_DEBUG_INFO *)&debug_event.u; sprintf(DebugMessage, "EXCEPTION code=%x flags=%x addr=%x firstchance=%x", ei->ExceptionRecord.ExceptionCode, ei->ExceptionRecord.ExceptionFlags, @@ -1732,15 +1845,23 @@ DWORD WINAPI StartDebug(void *p) res=MessageBoxEx(0, DebugMessage, "Continue stepping?", MB_YESNO | MB_ICONQUESTION, NULL); if(res!=IDYES) step=FALSE; } - //if(ei->ExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT) - // dwContinueStatus = DBG_CONTINUE; // skip initial breakpoint +#endif break; default: break; } - ContinueDebugEvent(debug_event.dwProcessId, - debug_event.dwThreadId, - dwContinueStatus); + if(bContinueDebugging){ + ContinueDebugEvent(debug_event.dwProcessId, + debug_event.dwThreadId, + dwContinueStatus); + } + else{ + DebugSetProcessKillOnExit(FALSE); + ContinueDebugEvent(debug_event.dwProcessId,debug_event.dwThreadId, DBG_CONTINUE); + DebugActiveProcessStop(debug_event.dwProcessId); + if (pinfo.hProcess) CloseHandle(pinfo.hProcess); + if (pinfo.hThread) CloseHandle(pinfo.hThread); + } } return TRUE; } diff --git a/host/host.aps b/host/host.aps deleted file mode 100644 index d9b7ec6..0000000 Binary files a/host/host.aps and /dev/null differ diff --git a/host/resource b/host/resource index ae55ba3..fe43bad 100644 Binary files a/host/resource and b/host/resource differ