1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-14 22:03:27 +01:00

Use Microsoft Detours for Windows API Hooks

This commit is contained in:
FunkyFr3sh 2019-04-06 05:35:23 +02:00
parent 6557ea669b
commit 55e62891d8
25 changed files with 13324 additions and 94 deletions

View File

@ -13,6 +13,19 @@
<ItemGroup>
<ClCompile Include="src\clipper.c" />
<ClCompile Include="src\debug.c" />
<ClCompile Include="src\detours\creatwth.cpp" />
<ClCompile Include="src\detours\detours.cpp" />
<ClCompile Include="src\detours\disasm.cpp" />
<ClCompile Include="src\detours\disolarm.cpp" />
<ClCompile Include="src\detours\disolarm64.cpp" />
<ClCompile Include="src\detours\disolia64.cpp" />
<ClCompile Include="src\detours\disolx64.cpp" />
<ClCompile Include="src\detours\disolx86.cpp" />
<ClCompile Include="src\detours\image.cpp" />
<ClCompile Include="src\detours\modules.cpp" />
<ClCompile Include="src\detours\uimports.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="src\dinput.c" />
<ClCompile Include="src\hook.c" />
<ClCompile Include="src\lodepng.c" />
@ -99,7 +112,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>inc</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>inc;src\detours</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@ -124,7 +137,7 @@ if exist "$(LocalDebuggerCommand)" if exist "$(LocalDebuggerWorkingDirectory)"
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>inc</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>inc;src\detours</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

View File

@ -13,6 +13,9 @@
<UniqueIdentifier>{9b152f9d-a092-42a9-ac47-0594f135a640}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Source Files\detours">
<UniqueIdentifier>{af194dd7-3316-4887-93d6-9f2af2135f94}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\clipper.c">
@ -60,6 +63,39 @@
<ClCompile Include="src\hook.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\detours\disolx64.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\disolx86.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\image.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\modules.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\uimports.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\creatwth.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\detours.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\disasm.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\disolarm.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\disolarm64.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
<ClCompile Include="src\detours\disolia64.cpp">
<Filter>Source Files\detours</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="inc\clipper.h">

View File

@ -4,7 +4,7 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 3
#define VERSION_BUILD 4
#define VERSION_REVISION 1
#define VERSION_REVISION 2
#define VERSION VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION
#define VERSION_STRING ver_str(VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_REVISION)
@ -21,7 +21,7 @@ PRODUCTVERSION VERSION
VALUE "FileDescription", "DirectDraw replacement"
VALUE "FileVersion", VERSION_STRING
VALUE "InternalName", "ddraw"
VALUE "LegalCopyright", "Copyright (c) 2010-2018"
VALUE "LegalCopyright", "Copyright (c) 2010-2019"
VALUE "LegalTrademarks", ""
VALUE "OriginalFileName", "ddraw.dll"
VALUE "ProductName", "cnc-ddraw"

View File

@ -41,11 +41,13 @@ extern MOVEWINDOWPROC real_MoveWindow;
extern SENDMESSAGEAPROC real_SendMessageA;
extern SETWINDOWLONGAPROC real_SetWindowLongA;
extern int HookingMethod;
extern BOOL Hook_Active;
void Hook_Init();
void Hook_Exit();
void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newFunction);
PROC Hook_HotPatch(PROC function, PROC newFunction);
void Hook_Create(char *moduleName, char *functionName, PROC newFunction, PROC *function);
void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *function);
#endif

View File

@ -124,7 +124,6 @@ typedef struct IDirectDrawImpl
BOOL altenter;
BOOL hidecursor;
BOOL accurateTimers;
BOOL hook;
SpeedLimiter ticksLimiter;
SpeedLimiter flipLimiter;
SpeedLimiter fpsLimiter;

115
src/detours/CREDITS.TXT Normal file
View File

@ -0,0 +1,115 @@
==============================================================================
The following individuals have helped identify specific bugs and improvements
in Detours. The entire Detours community has benefited from their help.
==============================================================================
* Jay Krell: Identified issue with VirtualSize == 0 files created in
NT 3.1 images. (Build_339)
* Igor Odnovorov: Identified an issue with the placement of the trampoline
region when a function is detoured twice and the second
trampoline region is outside of the +/- 2GB range of
the target. (Build_337)
* Jay Krell: Identified need for some programs to enumerate the
address of IAT entries. (Build_336)
* Calvin Hsia: Identified need for some program to change the excluded
system region. (Build_336)
* Adam Smith: Identified error in failure handling when VirtualProect
cannot make pages executable because the Prohibit
Dynamic Code Generation mitigation policy has been
applied to a process. (Build_335)
* Ben Faull: Identified fix to detour_alloc_region_from_lo and
detour_alloc_region_from_hi that preserves ASLR entropy.
(Build_334)
* Shaoxiang Su: Reported errors building with Visual Studio 2015.
(Build_332)
* Jay Krell: Identified and resolved significant gaps in the X86, X64
and IA64 disassemblers for instruction found in code,
but seldom found in function prologues. (Build_331)
* Allan Murphy: Identify error in rep and jmp ds: encodings. (Build_331)
* Philip Bacon: Identified incorrect entry point return for pure
resource-only binaries. (Build_330)
* Jay Krell: Identified failure in DetourAttachEx to update nAlign.
(Build_330)
* Sumit Sarin: Helped debug error with packed binaries.
(Build_329)
* Nitya Kumar Sharma: Reported bug in DetourAfterWithDll for 32/64 agnostic
EXEs.
(Build_327)
* Richard Black: Identified a large number of typos in documentation.
(Build_326)
* Michael Bilodeau: Identified bug in DetourUpdateProcessWithDll when the
target process contains a Detours payload *after* all
valid PE binaries.
(Build_324)
* Meera Jindal: Reported bug in identification of target address in
DetourCopyInstruction for jmp[] and call[] on x86 & x64,
the ff15 and ff25 opcodes.
(Build_323)
* Ken Johnson: Assistance with SAL 2.0 annotations.
(Build_319)
* Nick Wood: Identified bug in DetourFindFunction on ARM.
(Build_314)
* Mark Russinovich: Helped debug DetourCreateProcessWithDllEx.
(Build_314)
* John Lin: Implementation idea for DetoursCreateProcessWithDllEx.
(Build_314)
* Andrew Zawadowskiy Reported an improper memory page permissions
vulnerability in Detours 2.1. (Vulnerability does not
exist in versions later than Detours 2.1.)
(Build_223)
* Nightxie: Identified bug in detour_alloc_round_up_to_region.
(Build_310)
* Diana Milirud: Identified bug in B* instructions on ARM.
(Build_309)
* Juan Carlos Identified correct MSIL entry point for unsigned MSIL.
Luciani: (Build_308)
* Lee Hunt Suggested improvements in algorithm for allocation of
Lawrence Landauer trampoline regions on x64 to avoid collisions with
Joe Laughlin: system DLLs.
(Build_307)
* Tyler Sims Identified bug in handling of "anycpu" MSIL binaries
Darren Kennedy: on x64.
(Build_307)
* Andre Vachon: Help with optimized binaries.
(Build 301)
* Chris Mann: Identified fix not forward ported from 2.2 to 3.0.
(Build_301)
* Mark Irving: Identified bug with EXEs missing second import table.
(Build_300)
* Ben Schwarz: Identified bug in handling of multi-byte NOPs.
(Build_300)
* Aaron Giles Coded initial ARM/Thumb2 disassembler.
Jared Henderson: (Build_300)
* Doug Brubacher: Coded initial x86 disassembler.
(Build_100)

23
src/detours/LICENSE.md Normal file
View File

@ -0,0 +1,23 @@
# Copyright (c) Microsoft Corporation
All rights reserved.
# MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

48
src/detours/README.md Normal file
View File

@ -0,0 +1,48 @@
# Microsoft Research Detours Package
Detours is a software package for monitoring and instrumenting API calls on Windows. Detours
has been used by many ISVs and is also used by product teams at Microsoft. Detours is now available under
a standard open source license (MIT). This simplifies licensing for programmers using Detours
and allows the community to support Detours using open source tools and processes.
Detours is compatible with the Windows NT family of
operating systems: Windows NT, Windows XP, Windows Server 2003, Windows 7,
Windows 8, and Windows 10. It cannot be used by Window Store apps
because Detours requires APIs not available to those applications.
This repo contains the source code for version 4.0.1 of Detours.
For technical documentation on Detours, see the [Detours Wiki](https://github.com/microsoft/Detours/wiki).
For directions on how to build and run samples, see the
samples [README.txt](https://github.com/Microsoft/Detours/blob/master/samples/README.TXT) file.
## Contributing
The [`Detours`](https://github.com/microsoft/detours) repository is where development is done.
Here are some ways you can participate in the project:
* [Answer questions](https://github.com/microsoft/detours/issues) about using Detours.
* [Improve the Wiki](https://github.com/microsoft/detours/wiki).
* [Submit bugs](https://github.com/microsoft/detours/issues) and help us verify fixes and changes as they are checked in.
* Review [source code changes](https://github.com/microsoft/detours/pulls).
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Issues, questions, and feedback
* Open an issue on [GitHub Issues](https://github.com/Microsoft/detours/issues).
## Mailing list for announcements
The detours-announce mailing list is a low-traffic email list for important announcements
about the project, such as the availability of new versions of Detours. To join it, send
an email to listserv@lists.research.microsoft.com with a
message body containing only the text SUBSCRIBE DETOURS-ANNOUNCE.
To leave it, send an email to listserv@lists.research.microsoft.com with a
message body containing only the text UNSUBSCRIBE DETOURS-ANNOUNCE.
## License
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [MIT](LICENSE.md) License.

1586
src/detours/creatwth.cpp Normal file

File diff suppressed because it is too large Load Diff

2489
src/detours/detours.cpp Normal file

File diff suppressed because it is too large Load Diff

1080
src/detours/detours.h Normal file

File diff suppressed because it is too large Load Diff

27
src/detours/detver.h Normal file
View File

@ -0,0 +1,27 @@
//////////////////////////////////////////////////////////////////////////////
//
// Common version parameters.
//
// Microsoft Research Detours Package, Version 4.0.1
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#define _USING_V110_SDK71_ 1
#include "winver.h"
#if 0
#include <windows.h>
#include <detours.h>
#else
#ifndef DETOURS_STRINGIFY
#define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x)
#define DETOURS_STRINGIFY_(x) #x
#endif
#define VER_FILEFLAGSMASK 0x3fL
#define VER_FILEFLAGS 0x0L
#define VER_FILEOS 0x00040004L
#define VER_FILETYPE 0x00000002L
#define VER_FILESUBTYPE 0x00000000L
#endif
#define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS)

4344
src/detours/disasm.cpp Normal file

File diff suppressed because it is too large Load Diff

2
src/detours/disolarm.cpp Normal file
View File

@ -0,0 +1,2 @@
#define DETOURS_ARM_OFFLINE_LIBRARY
#include "disasm.cpp"

View File

@ -0,0 +1,2 @@
#define DETOURS_ARM64_OFFLINE_LIBRARY
#include "disasm.cpp"

View File

@ -0,0 +1,2 @@
#define DETOURS_IA64_OFFLINE_LIBRARY
#include "disasm.cpp"

2
src/detours/disolx64.cpp Normal file
View File

@ -0,0 +1,2 @@
#define DETOURS_X64_OFFLINE_LIBRARY
#include "disasm.cpp"

2
src/detours/disolx86.cpp Normal file
View File

@ -0,0 +1,2 @@
#define DETOURS_X86_OFFLINE_LIBRARY
#include "disasm.cpp"

2247
src/detours/image.cpp Normal file

File diff suppressed because it is too large Load Diff

929
src/detours/modules.cpp Normal file
View File

@ -0,0 +1,929 @@
//////////////////////////////////////////////////////////////////////////////
//
// Module Enumeration Functions (modules.cpp of detours.lib)
//
// Microsoft Research Detours Package, Version 4.0.1
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Module enumeration functions.
//
#define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1
#pragma warning(disable:4068) // unknown pragma (suppress)
#if _MSC_VER >= 1900
#pragma warning(push)
#pragma warning(disable:4091) // empty typedef
#endif
#define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1
#include <windows.h>
#if (_MSC_VER < 1310)
#else
#pragma warning(push)
#if _MSC_VER > 1400
#pragma warning(disable:6102 6103) // /analyze warnings
#endif
#include <strsafe.h>
#pragma warning(pop)
#endif
// #define DETOUR_DEBUG 1
#define DETOURS_INTERNAL
#include "detours.h"
#if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH
#error detours.h version mismatch
#endif
#if _MSC_VER >= 1900
#pragma warning(pop)
#endif
#define CLR_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR]
#define IAT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT]
//////////////////////////////////////////////////////////////////////////////
//
const GUID DETOUR_EXE_RESTORE_GUID = {
0x2ed7a3ff, 0x3339, 0x4a8d,
{ 0x80, 0x5c, 0xd4, 0x98, 0x15, 0x3f, 0xc2, 0x8f }};
//////////////////////////////////////////////////////////////////////////////
//
PDETOUR_SYM_INFO DetourLoadImageHlp(VOID)
{
static DETOUR_SYM_INFO symInfo;
static PDETOUR_SYM_INFO pSymInfo = NULL;
static BOOL failed = false;
if (failed) {
return NULL;
}
if (pSymInfo != NULL) {
return pSymInfo;
}
ZeroMemory(&symInfo, sizeof(symInfo));
// Create a real handle to the process.
#if 0
DuplicateHandle(GetCurrentProcess(),
GetCurrentProcess(),
GetCurrentProcess(),
&symInfo.hProcess,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
#else
symInfo.hProcess = GetCurrentProcess();
#endif
symInfo.hDbgHelp = LoadLibraryExW(L"dbghelp.dll", NULL, 0);
if (symInfo.hDbgHelp == NULL) {
abort:
failed = true;
if (symInfo.hDbgHelp != NULL) {
FreeLibrary(symInfo.hDbgHelp);
}
symInfo.pfImagehlpApiVersionEx = NULL;
symInfo.pfSymInitialize = NULL;
symInfo.pfSymSetOptions = NULL;
symInfo.pfSymGetOptions = NULL;
symInfo.pfSymLoadModule64 = NULL;
symInfo.pfSymGetModuleInfo64 = NULL;
symInfo.pfSymFromName = NULL;
return NULL;
}
symInfo.pfImagehlpApiVersionEx
= (PF_ImagehlpApiVersionEx)GetProcAddress(symInfo.hDbgHelp,
"ImagehlpApiVersionEx");
symInfo.pfSymInitialize
= (PF_SymInitialize)GetProcAddress(symInfo.hDbgHelp, "SymInitialize");
symInfo.pfSymSetOptions
= (PF_SymSetOptions)GetProcAddress(symInfo.hDbgHelp, "SymSetOptions");
symInfo.pfSymGetOptions
= (PF_SymGetOptions)GetProcAddress(symInfo.hDbgHelp, "SymGetOptions");
symInfo.pfSymLoadModule64
= (PF_SymLoadModule64)GetProcAddress(symInfo.hDbgHelp, "SymLoadModule64");
symInfo.pfSymGetModuleInfo64
= (PF_SymGetModuleInfo64)GetProcAddress(symInfo.hDbgHelp, "SymGetModuleInfo64");
symInfo.pfSymFromName
= (PF_SymFromName)GetProcAddress(symInfo.hDbgHelp, "SymFromName");
API_VERSION av;
ZeroMemory(&av, sizeof(av));
av.MajorVersion = API_VERSION_NUMBER;
if (symInfo.pfImagehlpApiVersionEx == NULL ||
symInfo.pfSymInitialize == NULL ||
symInfo.pfSymLoadModule64 == NULL ||
symInfo.pfSymGetModuleInfo64 == NULL ||
symInfo.pfSymFromName == NULL) {
goto abort;
}
symInfo.pfImagehlpApiVersionEx(&av);
if (av.MajorVersion < API_VERSION_NUMBER) {
goto abort;
}
if (!symInfo.pfSymInitialize(symInfo.hProcess, NULL, FALSE)) {
// We won't retry the initialize if it fails.
goto abort;
}
if (symInfo.pfSymGetOptions != NULL && symInfo.pfSymSetOptions != NULL) {
DWORD dw = symInfo.pfSymGetOptions();
dw &= ~(SYMOPT_CASE_INSENSITIVE |
SYMOPT_UNDNAME |
SYMOPT_DEFERRED_LOADS |
0);
dw |= (
#if defined(SYMOPT_EXACT_SYMBOLS)
SYMOPT_EXACT_SYMBOLS |
#endif
#if defined(SYMOPT_NO_UNQUALIFIED_LOADS)
SYMOPT_NO_UNQUALIFIED_LOADS |
#endif
SYMOPT_DEFERRED_LOADS |
#if defined(SYMOPT_FAIL_CRITICAL_ERRORS)
SYMOPT_FAIL_CRITICAL_ERRORS |
#endif
#if defined(SYMOPT_INCLUDE_32BIT_MODULES)
SYMOPT_INCLUDE_32BIT_MODULES |
#endif
0);
symInfo.pfSymSetOptions(dw);
}
pSymInfo = &symInfo;
return pSymInfo;
}
PVOID WINAPI DetourFindFunction(_In_ PCSTR pszModule,
_In_ PCSTR pszFunction)
{
/////////////////////////////////////////////// First, try GetProcAddress.
//
#pragma prefast(suppress:28752, "We don't do the unicode conversion for LoadLibraryExA.")
HMODULE hModule = LoadLibraryExA(pszModule, NULL, 0);
if (hModule == NULL) {
return NULL;
}
PBYTE pbCode = (PBYTE)GetProcAddress(hModule, pszFunction);
if (pbCode) {
return pbCode;
}
////////////////////////////////////////////////////// Then try ImageHelp.
//
DETOUR_TRACE(("DetourFindFunction(%hs, %hs)\n", pszModule, pszFunction));
PDETOUR_SYM_INFO pSymInfo = DetourLoadImageHlp();
if (pSymInfo == NULL) {
DETOUR_TRACE(("DetourLoadImageHlp failed: %d\n",
GetLastError()));
return NULL;
}
if (pSymInfo->pfSymLoadModule64(pSymInfo->hProcess, NULL,
(PCHAR)pszModule, NULL,
(DWORD64)hModule, 0) == 0) {
if (ERROR_SUCCESS != GetLastError()) {
DETOUR_TRACE(("SymLoadModule64(%p) failed: %d\n",
pSymInfo->hProcess, GetLastError()));
return NULL;
}
}
HRESULT hrRet;
CHAR szFullName[512];
IMAGEHLP_MODULE64 modinfo;
ZeroMemory(&modinfo, sizeof(modinfo));
modinfo.SizeOfStruct = sizeof(modinfo);
if (!pSymInfo->pfSymGetModuleInfo64(pSymInfo->hProcess, (DWORD64)hModule, &modinfo)) {
DETOUR_TRACE(("SymGetModuleInfo64(%p, %p) failed: %d\n",
pSymInfo->hProcess, hModule, GetLastError()));
return NULL;
}
hrRet = StringCchCopyA(szFullName, sizeof(szFullName)/sizeof(CHAR), modinfo.ModuleName);
if (FAILED(hrRet)) {
DETOUR_TRACE(("StringCchCopyA failed: %08x\n", hrRet));
return NULL;
}
hrRet = StringCchCatA(szFullName, sizeof(szFullName)/sizeof(CHAR), "!");
if (FAILED(hrRet)) {
DETOUR_TRACE(("StringCchCatA failed: %08x\n", hrRet));
return NULL;
}
hrRet = StringCchCatA(szFullName, sizeof(szFullName)/sizeof(CHAR), pszFunction);
if (FAILED(hrRet)) {
DETOUR_TRACE(("StringCchCatA failed: %08x\n", hrRet));
return NULL;
}
struct CFullSymbol : SYMBOL_INFO {
CHAR szRestOfName[512];
} symbol;
ZeroMemory(&symbol, sizeof(symbol));
//symbol.ModBase = (ULONG64)hModule;
symbol.SizeOfStruct = sizeof(SYMBOL_INFO);
#ifdef DBHLPAPI
symbol.MaxNameLen = sizeof(symbol.szRestOfName)/sizeof(symbol.szRestOfName[0]);
#else
symbol.MaxNameLength = sizeof(symbol.szRestOfName)/sizeof(symbol.szRestOfName[0]);
#endif
if (!pSymInfo->pfSymFromName(pSymInfo->hProcess, szFullName, &symbol)) {
DETOUR_TRACE(("SymFromName(%hs) failed: %d\n", szFullName, GetLastError()));
return NULL;
}
#if defined(DETOURS_IA64)
// On the IA64, we get a raw code pointer from the symbol engine
// and have to convert it to a wrapped [code pointer, global pointer].
//
PPLABEL_DESCRIPTOR pldEntry = (PPLABEL_DESCRIPTOR)DetourGetEntryPoint(hModule);
PPLABEL_DESCRIPTOR pldSymbol = new PLABEL_DESCRIPTOR;
pldSymbol->EntryPoint = symbol.Address;
pldSymbol->GlobalPointer = pldEntry->GlobalPointer;
return (PBYTE)pldSymbol;
#elif defined(DETOURS_ARM)
// On the ARM, we get a raw code pointer, which we must convert into a
// valied Thumb2 function pointer.
return DETOURS_PBYTE_TO_PFUNC(symbol.Address);
#else
return (PBYTE)symbol.Address;
#endif
}
//////////////////////////////////////////////////// Module Image Functions.
//
HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast)
{
PBYTE pbLast = (PBYTE)hModuleLast + MM_ALLOCATION_GRANULARITY;
MEMORY_BASIC_INFORMATION mbi;
ZeroMemory(&mbi, sizeof(mbi));
// Find the next memory region that contains a mapped PE image.
//
for (;; pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) {
if (VirtualQuery(pbLast, &mbi, sizeof(mbi)) <= 0) {
break;
}
// Skip uncommitted regions and guard pages.
//
if ((mbi.State != MEM_COMMIT) ||
((mbi.Protect & 0xff) == PAGE_NOACCESS) ||
(mbi.Protect & PAGE_GUARD)) {
continue;
}
__try {
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pbLast;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE ||
(DWORD)pDosHeader->e_lfanew > mbi.RegionSize ||
(DWORD)pDosHeader->e_lfanew < sizeof(*pDosHeader)) {
continue;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
continue;
}
return (HMODULE)pDosHeader;
}
#pragma prefast(suppress:28940, "A bad pointer means this probably isn't a PE header.")
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
continue;
}
}
return NULL;
}
PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
if (hModule == NULL) {
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
}
__try {
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return NULL;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
return NULL;
}
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return NULL;
}
PDETOUR_CLR_HEADER pClrHeader = NULL;
if (pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
if (((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.VirtualAddress != 0 &&
((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.Size != 0) {
pClrHeader = (PDETOUR_CLR_HEADER)
(((PBYTE)pDosHeader)
+ ((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.VirtualAddress);
}
}
else if (pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
if (((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.VirtualAddress != 0 &&
((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.Size != 0) {
pClrHeader = (PDETOUR_CLR_HEADER)
(((PBYTE)pDosHeader)
+ ((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.VirtualAddress);
}
}
if (pClrHeader != NULL) {
// For MSIL assemblies, we want to use the _Cor entry points.
HMODULE hClr = GetModuleHandleW(L"MSCOREE.DLL");
if (hClr == NULL) {
return NULL;
}
SetLastError(NO_ERROR);
return GetProcAddress(hClr, "_CorExeMain");
}
SetLastError(NO_ERROR);
// Pure resource DLLs have neither an entry point nor CLR information
// so handle them by returning NULL (LastError is NO_ERROR)
if (pNtHeader->OptionalHeader.AddressOfEntryPoint == 0) {
return NULL;
}
return ((PBYTE)pDosHeader) +
pNtHeader->OptionalHeader.AddressOfEntryPoint;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return NULL;
}
}
ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
if (hModule == NULL) {
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
}
__try {
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return NULL;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
return NULL;
}
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return NULL;
}
SetLastError(NO_ERROR);
return (pNtHeader->OptionalHeader.SizeOfImage);
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return NULL;
}
}
HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr)
{
MEMORY_BASIC_INFORMATION mbi;
ZeroMemory(&mbi, sizeof(mbi));
__try {
if (VirtualQuery(pvAddr, &mbi, sizeof(mbi)) <= 0) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return NULL;
}
// Skip uncommitted regions and guard pages.
//
if ((mbi.State != MEM_COMMIT) ||
((mbi.Protect & 0xff) == PAGE_NOACCESS) ||
(mbi.Protect & PAGE_GUARD)) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return NULL;
}
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mbi.AllocationBase;
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return NULL;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
return NULL;
}
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return NULL;
}
SetLastError(NO_ERROR);
return (HMODULE)pDosHeader;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
return NULL;
}
}
static inline PBYTE RvaAdjust(_Pre_notnull_ PIMAGE_DOS_HEADER pDosHeader, _In_ DWORD raddr)
{
if (raddr != NULL) {
return ((PBYTE)pDosHeader) + raddr;
}
return NULL;
}
BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule,
_In_opt_ PVOID pContext,
_In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
if (hModule == NULL) {
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
}
__try {
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return NULL;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
return FALSE;
}
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return FALSE;
}
PIMAGE_EXPORT_DIRECTORY pExportDir
= (PIMAGE_EXPORT_DIRECTORY)
RvaAdjust(pDosHeader,
pNtHeader->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
if (pExportDir == NULL) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return FALSE;
}
PBYTE pExportDirEnd = (PBYTE)pExportDir + pNtHeader->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
PDWORD pdwFunctions = (PDWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfFunctions);
PDWORD pdwNames = (PDWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfNames);
PWORD pwOrdinals = (PWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfNameOrdinals);
for (DWORD nFunc = 0; nFunc < pExportDir->NumberOfFunctions; nFunc++) {
PBYTE pbCode = (pdwFunctions != NULL)
? (PBYTE)RvaAdjust(pDosHeader, pdwFunctions[nFunc]) : NULL;
PCHAR pszName = NULL;
// if the pointer is in the export region, then it is a forwarder.
if (pbCode > (PBYTE)pExportDir && pbCode < pExportDirEnd) {
pbCode = NULL;
}
for (DWORD n = 0; n < pExportDir->NumberOfNames; n++) {
if (pwOrdinals[n] == nFunc) {
pszName = (pdwNames != NULL)
? (PCHAR)RvaAdjust(pDosHeader, pdwNames[n]) : NULL;
break;
}
}
ULONG nOrdinal = pExportDir->Base + nFunc;
if (!pfExport(pContext, nOrdinal, pszName, pbCode)) {
break;
}
}
SetLastError(NO_ERROR);
return TRUE;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return NULL;
}
}
BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule,
_In_opt_ PVOID pContext,
_In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
_In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFunc)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
if (hModule == NULL) {
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
}
__try {
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return FALSE;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
return FALSE;
}
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return FALSE;
}
PIMAGE_IMPORT_DESCRIPTOR iidp
= (PIMAGE_IMPORT_DESCRIPTOR)
RvaAdjust(pDosHeader,
pNtHeader->OptionalHeader
.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
if (iidp == NULL) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return FALSE;
}
for (; iidp->OriginalFirstThunk != 0; iidp++) {
PCSTR pszName = (PCHAR)RvaAdjust(pDosHeader, iidp->Name);
if (pszName == NULL) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return FALSE;
}
PIMAGE_THUNK_DATA pThunks = (PIMAGE_THUNK_DATA)
RvaAdjust(pDosHeader, iidp->OriginalFirstThunk);
PVOID * pAddrs = (PVOID *)
RvaAdjust(pDosHeader, iidp->FirstThunk);
HMODULE hFile = DetourGetContainingModule(pAddrs[0]);
if (pfImportFile != NULL) {
if (!pfImportFile(pContext, hFile, pszName)) {
break;
}
}
DWORD nNames = 0;
if (pThunks) {
for (; pThunks[nNames].u1.Ordinal; nNames++) {
DWORD nOrdinal = 0;
PCSTR pszFunc = NULL;
if (IMAGE_SNAP_BY_ORDINAL(pThunks[nNames].u1.Ordinal)) {
nOrdinal = (DWORD)IMAGE_ORDINAL(pThunks[nNames].u1.Ordinal);
}
else {
pszFunc = (PCSTR)RvaAdjust(pDosHeader,
(DWORD)pThunks[nNames].u1.AddressOfData + 2);
}
if (pfImportFunc != NULL) {
if (!pfImportFunc(pContext,
nOrdinal,
pszFunc,
&pAddrs[nNames])) {
break;
}
}
}
if (pfImportFunc != NULL) {
pfImportFunc(pContext, 0, NULL, NULL);
}
}
}
if (pfImportFile != NULL) {
pfImportFile(pContext, NULL, NULL);
}
SetLastError(NO_ERROR);
return TRUE;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return FALSE;
}
}
// Context for DetourEnumerateImportsThunk, which adapts "regular" callbacks for use with "Ex".
struct _DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT
{
PVOID pContext;
PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc;
};
// Callback for DetourEnumerateImportsEx that adapts DetourEnumerateImportsEx
// for use with a DetourEnumerateImports callback -- derefence the IAT and pass the value on.
static
BOOL
CALLBACK
DetourEnumerateImportsThunk(_In_ PVOID VoidContext,
_In_ DWORD nOrdinal,
_In_opt_ PCSTR pszFunc,
_In_opt_ PVOID* ppvFunc)
{
_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT const * const
pContext = (_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT*)VoidContext;
return pContext->pfImportFunc(pContext->pContext, nOrdinal, pszFunc, ppvFunc ? *ppvFunc : NULL);
}
BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule,
_In_opt_ PVOID pContext,
_In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
_In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc)
{
_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT const context = { pContext, pfImportFunc };
return DetourEnumerateImportsEx(hModule,
(PVOID)&context,
pfImportFile,
&DetourEnumerateImportsThunk);
}
static PDETOUR_LOADED_BINARY WINAPI GetPayloadSectionFromModule(HMODULE hModule)
{
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule;
if (hModule == NULL) {
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL);
}
__try {
#pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL.
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return NULL;
}
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader +
pDosHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) {
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
return NULL;
}
if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return NULL;
}
PIMAGE_SECTION_HEADER pSectionHeaders
= (PIMAGE_SECTION_HEADER)((PBYTE)pNtHeader
+ sizeof(pNtHeader->Signature)
+ sizeof(pNtHeader->FileHeader)
+ pNtHeader->FileHeader.SizeOfOptionalHeader);
for (DWORD n = 0; n < pNtHeader->FileHeader.NumberOfSections; n++) {
if (strcmp((PCHAR)pSectionHeaders[n].Name, ".detour") == 0) {
if (pSectionHeaders[n].VirtualAddress == 0 ||
pSectionHeaders[n].SizeOfRawData == 0) {
break;
}
PBYTE pbData = (PBYTE)pDosHeader + pSectionHeaders[n].VirtualAddress;
DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pbData;
if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
break;
}
if (pHeader->nDataOffset == 0) {
pHeader->nDataOffset = pHeader->cbHeaderSize;
}
SetLastError(NO_ERROR);
return (PBYTE)pHeader;
}
}
SetLastError(ERROR_EXE_MARKED_INVALID);
return NULL;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
SetLastError(ERROR_EXE_MARKED_INVALID);
return NULL;
}
}
DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule)
{
PDETOUR_LOADED_BINARY pBinary = GetPayloadSectionFromModule(hModule);
if (pBinary == NULL) {
// Error set by GetPayloadSectionFromModule.
return 0;
}
__try {
DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary;
if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
SetLastError(NO_ERROR);
return pHeader->cbDataSize;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
SetLastError(ERROR_INVALID_HANDLE);
return 0;
}
}
_Writable_bytes_(*pcbData)
_Readable_bytes_(*pcbData)
_Success_(return != NULL)
PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule,
_In_ REFGUID rguid,
_Out_ DWORD *pcbData)
{
PBYTE pbData = NULL;
if (pcbData) {
*pcbData = 0;
}
PDETOUR_LOADED_BINARY pBinary = GetPayloadSectionFromModule(hModule);
if (pBinary == NULL) {
// Error set by GetPayloadSectionFromModule.
return NULL;
}
__try {
DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary;
if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) ||
pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) {
SetLastError(ERROR_INVALID_EXE_SIGNATURE);
return NULL;
}
PBYTE pbBeg = ((PBYTE)pHeader) + pHeader->nDataOffset;
PBYTE pbEnd = ((PBYTE)pHeader) + pHeader->cbDataSize;
for (pbData = pbBeg; pbData < pbEnd;) {
DETOUR_SECTION_RECORD *pSection = (DETOUR_SECTION_RECORD *)pbData;
if (pSection->guid.Data1 == rguid.Data1 &&
pSection->guid.Data2 == rguid.Data2 &&
pSection->guid.Data3 == rguid.Data3 &&
pSection->guid.Data4[0] == rguid.Data4[0] &&
pSection->guid.Data4[1] == rguid.Data4[1] &&
pSection->guid.Data4[2] == rguid.Data4[2] &&
pSection->guid.Data4[3] == rguid.Data4[3] &&
pSection->guid.Data4[4] == rguid.Data4[4] &&
pSection->guid.Data4[5] == rguid.Data4[5] &&
pSection->guid.Data4[6] == rguid.Data4[6] &&
pSection->guid.Data4[7] == rguid.Data4[7]) {
if (pcbData) {
*pcbData = pSection->cbBytes - sizeof(*pSection);
SetLastError(NO_ERROR);
return (PBYTE)(pSection + 1);
}
}
pbData = (PBYTE)pSection + pSection->cbBytes;
}
SetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
SetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
}
_Writable_bytes_(*pcbData)
_Readable_bytes_(*pcbData)
_Success_(return != NULL)
PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid,
_Out_ DWORD * pcbData)
{
for (HMODULE hMod = NULL; (hMod = DetourEnumerateModules(hMod)) != NULL;) {
PVOID pvData;
pvData = DetourFindPayload(hMod, rguid, pcbData);
if (pvData != NULL) {
return pvData;
}
}
SetLastError(ERROR_MOD_NOT_FOUND);
return NULL;
}
BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData,
_In_ DWORD cbData)
{
PDETOUR_EXE_RESTORE pder = (PDETOUR_EXE_RESTORE)pvData;
if (pder->cb != sizeof(*pder) || pder->cb > cbData) {
SetLastError(ERROR_BAD_EXE_FORMAT);
return FALSE;
}
DWORD dwPermIdh = ~0u;
DWORD dwPermInh = ~0u;
DWORD dwPermClr = ~0u;
DWORD dwIgnore;
BOOL fSucceeded = FALSE;
BOOL fUpdated32To64 = FALSE;
if (pder->pclr != NULL && pder->clr.Flags != ((PDETOUR_CLR_HEADER)pder->pclr)->Flags) {
// If we had to promote the 32/64-bit agnostic IL to 64-bit, we can't restore
// that.
fUpdated32To64 = TRUE;
}
if (DetourVirtualProtectSameExecute(pder->pidh, pder->cbidh,
PAGE_EXECUTE_READWRITE, &dwPermIdh)) {
if (DetourVirtualProtectSameExecute(pder->pinh, pder->cbinh,
PAGE_EXECUTE_READWRITE, &dwPermInh)) {
CopyMemory(pder->pidh, &pder->idh, pder->cbidh);
CopyMemory(pder->pinh, &pder->inh, pder->cbinh);
if (pder->pclr != NULL && !fUpdated32To64) {
if (DetourVirtualProtectSameExecute(pder->pclr, pder->cbclr,
PAGE_EXECUTE_READWRITE, &dwPermClr)) {
CopyMemory(pder->pclr, &pder->clr, pder->cbclr);
VirtualProtect(pder->pclr, pder->cbclr, dwPermClr, &dwIgnore);
fSucceeded = TRUE;
}
}
else {
fSucceeded = TRUE;
}
VirtualProtect(pder->pinh, pder->cbinh, dwPermInh, &dwIgnore);
}
VirtualProtect(pder->pidh, pder->cbidh, dwPermIdh, &dwIgnore);
}
return fSucceeded;
}
BOOL WINAPI DetourRestoreAfterWith()
{
PVOID pvData;
DWORD cbData;
pvData = DetourFindPayloadEx(DETOUR_EXE_RESTORE_GUID, &cbData);
if (pvData != NULL && cbData != 0) {
return DetourRestoreAfterWithEx(pvData, cbData);
}
SetLastError(ERROR_MOD_NOT_FOUND);
return FALSE;
}
// End of File

269
src/detours/uimports.cpp Normal file
View File

@ -0,0 +1,269 @@
//////////////////////////////////////////////////////////////////////////////
//
// Add DLLs to a module import table (uimports.cpp of detours.lib)
//
// Microsoft Research Detours Package, Version 4.0.1
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Note that this file is included into creatwth.cpp one or more times
// (once for each supported module format).
//
#if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH
#error detours.h version mismatch
#endif
// UpdateImports32 aka UpdateImports64
static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess,
HMODULE hModule,
__in_ecount(nDlls) LPCSTR *plpDlls,
DWORD nDlls)
{
BOOL fSucceeded = FALSE;
DWORD cbNew = 0;
BYTE * pbNew = NULL;
DWORD i;
SIZE_T cbRead;
DWORD n;
PBYTE pbModule = (PBYTE)hModule;
IMAGE_DOS_HEADER idh;
ZeroMemory(&idh, sizeof(idh));
if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), &cbRead)
|| cbRead < sizeof(idh)) {
DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p) failed: %d\n",
pbModule, pbModule + sizeof(idh), GetLastError()));
finish:
if (pbNew != NULL) {
delete[] pbNew;
pbNew = NULL;
}
return fSucceeded;
}
IMAGE_NT_HEADERS_XX inh;
ZeroMemory(&inh, sizeof(inh));
if (!ReadProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), &cbRead)
|| cbRead < sizeof(inh)) {
DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p) failed: %d\n",
pbModule + idh.e_lfanew,
pbModule + idh.e_lfanew + sizeof(inh),
GetLastError()));
goto finish;
}
if (inh.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC_XX) {
DETOUR_TRACE(("Wrong size image (%04x != %04x).\n",
inh.OptionalHeader.Magic, IMAGE_NT_OPTIONAL_HDR_MAGIC_XX));
SetLastError(ERROR_INVALID_BLOCK);
goto finish;
}
// Zero out the bound table so loader doesn't use it instead of our new table.
inh.BOUND_DIRECTORY.VirtualAddress = 0;
inh.BOUND_DIRECTORY.Size = 0;
// Find the size of the mapped file.
DWORD dwSec = idh.e_lfanew +
FIELD_OFFSET(IMAGE_NT_HEADERS_XX, OptionalHeader) +
inh.FileHeader.SizeOfOptionalHeader;
for (i = 0; i < inh.FileHeader.NumberOfSections; i++) {
IMAGE_SECTION_HEADER ish;
ZeroMemory(&ish, sizeof(ish));
if (!ReadProcessMemory(hProcess, pbModule + dwSec + sizeof(ish) * i, &ish,
sizeof(ish), &cbRead)
|| cbRead < sizeof(ish)) {
DETOUR_TRACE(("ReadProcessMemory(ish@%p..%p) failed: %d\n",
pbModule + dwSec + sizeof(ish) * i,
pbModule + dwSec + sizeof(ish) * (i + 1),
GetLastError()));
goto finish;
}
DETOUR_TRACE(("ish[%d] : va=%08x sr=%d\n", i, ish.VirtualAddress, ish.SizeOfRawData));
// If the file didn't have an IAT_DIRECTORY, we assign it...
if (inh.IAT_DIRECTORY.VirtualAddress == 0 &&
inh.IMPORT_DIRECTORY.VirtualAddress >= ish.VirtualAddress &&
inh.IMPORT_DIRECTORY.VirtualAddress < ish.VirtualAddress + ish.SizeOfRawData) {
inh.IAT_DIRECTORY.VirtualAddress = ish.VirtualAddress;
inh.IAT_DIRECTORY.Size = ish.SizeOfRawData;
}
}
DETOUR_TRACE((" Imports: %p..%p\n",
(DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,
(DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress +
inh.IMPORT_DIRECTORY.Size));
DWORD nOldDlls = inh.IMPORT_DIRECTORY.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
DWORD obRem = sizeof(IMAGE_IMPORT_DESCRIPTOR) * nDlls;
DWORD obOld = obRem + sizeof(IMAGE_IMPORT_DESCRIPTOR) * nOldDlls;
DWORD obTab = PadToDwordPtr(obOld);
DWORD obDll = obTab + sizeof(DWORD_XX) * 4 * nDlls;
DWORD obStr = obDll;
cbNew = obStr;
for (n = 0; n < nDlls; n++) {
cbNew += PadToDword((DWORD)strlen(plpDlls[n]) + 1);
}
_Analysis_assume_(cbNew >
sizeof(IMAGE_IMPORT_DESCRIPTOR) * (nDlls + nOldDlls)
+ sizeof(DWORD_XX) * 4 * nDlls);
pbNew = new BYTE [cbNew];
if (pbNew == NULL) {
DETOUR_TRACE(("new BYTE [cbNew] failed.\n"));
goto finish;
}
ZeroMemory(pbNew, cbNew);
PBYTE pbBase = pbModule;
PBYTE pbNext = pbBase
+ inh.OptionalHeader.BaseOfCode
+ inh.OptionalHeader.SizeOfCode
+ inh.OptionalHeader.SizeOfInitializedData
+ inh.OptionalHeader.SizeOfUninitializedData;
if (pbBase < pbNext) {
pbBase = pbNext;
}
DETOUR_TRACE(("pbBase = %p\n", pbBase));
PBYTE pbNewIid = FindAndAllocateNearBase(hProcess, pbModule, pbBase, cbNew);
if (pbNewIid == NULL) {
DETOUR_TRACE(("FindAndAllocateNearBase failed.\n"));
goto finish;
}
PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)pbNew;
DWORD_XX *pt;
DWORD obBase = (DWORD)(pbNewIid - pbModule);
DWORD dwProtect = 0;
if (inh.IMPORT_DIRECTORY.VirtualAddress != 0) {
// Read the old import directory if it exists.
DETOUR_TRACE(("IMPORT_DIRECTORY perms=%x\n", dwProtect));
if (!ReadProcessMemory(hProcess,
pbModule + inh.IMPORT_DIRECTORY.VirtualAddress,
&piid[nDlls],
nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR), &cbRead)
|| cbRead < nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR)) {
DETOUR_TRACE(("ReadProcessMemory(imports) failed: %d\n", GetLastError()));
goto finish;
}
}
for (n = 0; n < nDlls; n++) {
HRESULT hrRet = StringCchCopyA((char*)pbNew + obStr, cbNew - obStr, plpDlls[n]);
if (FAILED(hrRet)) {
DETOUR_TRACE(("StringCchCopyA failed: %d\n", GetLastError()));
goto finish;
}
// After copying the string, we patch up the size "??" bits if any.
hrRet = ReplaceOptionalSizeA((char*)pbNew + obStr,
cbNew - obStr,
DETOURS_STRINGIFY(DETOURS_BITS_XX));
if (FAILED(hrRet)) {
DETOUR_TRACE(("ReplaceOptionalSizeA failed: %d\n", GetLastError()));
goto finish;
}
DWORD nOffset = obTab + (sizeof(DWORD_XX) * (4 * n));
piid[n].OriginalFirstThunk = obBase + nOffset;
pt = ((DWORD_XX*)(pbNew + nOffset));
pt[0] = IMAGE_ORDINAL_FLAG_XX + 1;
pt[1] = 0;
nOffset = obTab + (sizeof(DWORD_XX) * ((4 * n) + 2));
piid[n].FirstThunk = obBase + nOffset;
pt = ((DWORD_XX*)(pbNew + nOffset));
pt[0] = IMAGE_ORDINAL_FLAG_XX + 1;
pt[1] = 0;
piid[n].TimeDateStamp = 0;
piid[n].ForwarderChain = 0;
piid[n].Name = obBase + obStr;
obStr += PadToDword((DWORD)strlen(plpDlls[n]) + 1);
}
_Analysis_assume_(obStr <= cbNew);
#if 0
for (i = 0; i < nDlls + nOldDlls; i++) {
DETOUR_TRACE(("%8d. Look=%08x Time=%08x Fore=%08x Name=%08x Addr=%08x\n",
i,
piid[i].OriginalFirstThunk,
piid[i].TimeDateStamp,
piid[i].ForwarderChain,
piid[i].Name,
piid[i].FirstThunk));
if (piid[i].OriginalFirstThunk == 0 && piid[i].FirstThunk == 0) {
break;
}
}
#endif
if (!WriteProcessMemory(hProcess, pbNewIid, pbNew, obStr, NULL)) {
DETOUR_TRACE(("WriteProcessMemory(iid) failed: %d\n", GetLastError()));
goto finish;
}
DETOUR_TRACE(("obBaseBef = %08x..%08x\n",
inh.IMPORT_DIRECTORY.VirtualAddress,
inh.IMPORT_DIRECTORY.VirtualAddress + inh.IMPORT_DIRECTORY.Size));
DETOUR_TRACE(("obBaseAft = %08x..%08x\n", obBase, obBase + obStr));
// If the file doesn't have an IAT_DIRECTORY, we create it...
if (inh.IAT_DIRECTORY.VirtualAddress == 0) {
inh.IAT_DIRECTORY.VirtualAddress = obBase;
inh.IAT_DIRECTORY.Size = cbNew;
}
inh.IMPORT_DIRECTORY.VirtualAddress = obBase;
inh.IMPORT_DIRECTORY.Size = cbNew;
/////////////////////// Update the NT header for the new import directory.
//
if (!DetourVirtualProtectSameExecuteEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,
PAGE_EXECUTE_READWRITE, &dwProtect)) {
DETOUR_TRACE(("VirtualProtectEx(inh) write failed: %d\n", GetLastError()));
goto finish;
}
inh.OptionalHeader.CheckSum = 0;
if (!WriteProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) {
DETOUR_TRACE(("WriteProcessMemory(idh) failed: %d\n", GetLastError()));
goto finish;
}
DETOUR_TRACE(("WriteProcessMemory(idh:%p..%p)\n", pbModule, pbModule + sizeof(idh)));
if (!WriteProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) {
DETOUR_TRACE(("WriteProcessMemory(inh) failed: %d\n", GetLastError()));
goto finish;
}
DETOUR_TRACE(("WriteProcessMemory(inh:%p..%p)\n",
pbModule + idh.e_lfanew,
pbModule + idh.e_lfanew + sizeof(inh)));
if (!VirtualProtectEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders,
dwProtect, &dwProtect)) {
DETOUR_TRACE(("VirtualProtectEx(idh) restore failed: %d\n", GetLastError()));
goto finish;
}
fSucceeded = TRUE;
goto finish;
}

View File

@ -2,13 +2,13 @@
#include <dinput.h>
#include "hook.h"
typedef HRESULT (WINAPI *DInputCreateA)(HINSTANCE, DWORD, LPDIRECTINPUTA*, LPUNKNOWN);
typedef HRESULT (WINAPI *DICreateDevice)(IDirectInputA*, REFGUID, LPDIRECTINPUTDEVICEA *, LPUNKNOWN);
typedef HRESULT (WINAPI *DIDSetCooperativeLevel)(IDirectInputDeviceA *, HWND, DWORD);
typedef HRESULT (WINAPI *DIRECTINPUTCREATEAPROC)(HINSTANCE, DWORD, LPDIRECTINPUTA*, LPUNKNOWN);
typedef HRESULT (WINAPI *DICREATEDEVICEPROC)(IDirectInputA*, REFGUID, LPDIRECTINPUTDEVICEA *, LPUNKNOWN);
typedef HRESULT (WINAPI *DIDSETCOOPERATIVELEVELPROC)(IDirectInputDeviceA *, HWND, DWORD);
static DInputCreateA DInputCreateA_;
static DICreateDevice DICreateDevice_;
static DIDSetCooperativeLevel DIDSetCooperativeLevel_;
static DIRECTINPUTCREATEAPROC DInputCreateA;
static DICREATEDEVICEPROC DICreateDevice;
static DIDSETCOOPERATIVELEVELPROC DIDSetCooperativeLevel;
static PROC HookFunc(PROC *orgFunc, PROC newFunc)
{
@ -27,17 +27,17 @@ static PROC HookFunc(PROC *orgFunc, PROC newFunc)
static HRESULT WINAPI fake_DIDSetCooperativeLevel(IDirectInputDeviceA *This, HWND hwnd, DWORD dwFlags)
{
return DIDSetCooperativeLevel_(This, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
return DIDSetCooperativeLevel(This, hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
}
static HRESULT WINAPI fake_DICreateDevice(IDirectInputA *This, REFGUID rguid, LPDIRECTINPUTDEVICEA * lplpDIDevice, LPUNKNOWN pUnkOuter)
{
HRESULT result = DICreateDevice_(This, rguid, lplpDIDevice, pUnkOuter);
HRESULT result = DICreateDevice(This, rguid, lplpDIDevice, pUnkOuter);
if (SUCCEEDED(result) && !DIDSetCooperativeLevel_)
if (SUCCEEDED(result) && !DIDSetCooperativeLevel)
{
DIDSetCooperativeLevel_ =
(DIDSetCooperativeLevel)HookFunc(
DIDSetCooperativeLevel =
(DIDSETCOOPERATIVELEVELPROC)HookFunc(
(PROC *)&(*lplpDIDevice)->lpVtbl->SetCooperativeLevel, (PROC)fake_DIDSetCooperativeLevel);
}
@ -46,22 +46,33 @@ static HRESULT WINAPI fake_DICreateDevice(IDirectInputA *This, REFGUID rguid, LP
static HRESULT WINAPI fake_DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA* lplpDirectInput, LPUNKNOWN punkOuter)
{
DInputCreateA_ = (DInputCreateA)GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA");
if (!DInputCreateA_)
DInputCreateA =
(DIRECTINPUTCREATEAPROC)GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA");
if (!DInputCreateA)
return DIERR_GENERIC;
HRESULT result = DInputCreateA_(hinst, dwVersion, lplpDirectInput, punkOuter);
HRESULT result = DInputCreateA(hinst, dwVersion, lplpDirectInput, punkOuter);
if (SUCCEEDED(result) && !DICreateDevice_)
if (SUCCEEDED(result) && !DICreateDevice)
{
DICreateDevice_ =
(DICreateDevice)HookFunc((PROC *)&(*lplpDirectInput)->lpVtbl->CreateDevice, (PROC)fake_DICreateDevice);
DICreateDevice =
(DICREATEDEVICEPROC)HookFunc((PROC *)&(*lplpDirectInput)->lpVtbl->CreateDevice, (PROC)fake_DICreateDevice);
}
return result;
}
void dinput_init()
void DInput_Hook()
{
Hook_PatchIAT(GetModuleHandle(NULL), "dinput.dll", "DirectInputCreateA", (PROC)fake_DirectInputCreateA);
}
void DInput_UnHook()
{
Hook_PatchIAT(
GetModuleHandle(NULL),
"dinput.dll",
"DirectInputCreateA",
(PROC)GetProcAddress(GetModuleHandle("dinput.dll"), "DirectInputCreateA"));
}

View File

@ -4,7 +4,12 @@
#include "mouse.h"
#include "hook.h"
#ifdef _MSC_VER
#include "detours.h"
#endif
BOOL Hook_Active;
int HookingMethod = 1;
GETCURSORPOSPROC real_GetCursorPos = GetCursorPos;
CLIPCURSORPROC real_ClipCursor = ClipCursor;
SHOWCURSORPROC real_ShowCursor = ShowCursor;
@ -82,75 +87,41 @@ void Hook_PatchIAT(HMODULE hMod, char *moduleName, char *functionName, PROC newF
}
}
PROC Hook_HotPatch(PROC function, PROC newFunction)
{
PROC result = function;
if (!function)
return result;
unsigned short *bytes = (unsigned short *)function;
if (*bytes == 0x25FF) // JMP DWORD PTR
{
char *address = (char *)function;
DWORD oldProtect;
if (VirtualProtect(address, 8, PAGE_EXECUTE_READWRITE, &oldProtect))
{
if (memcmp(address + 6, (const char[]) { 0xCC, 0xCC }, 2) == 0 ||
memcmp(address + 6, (const char[]) { 0x90, 0x90 }, 2) == 0)
{
memmove(address + 2, address, 6);
*((WORD *)(&address[0])) = 0xFF8B; // mov edi, edi
}
VirtualProtect(address, 8, oldProtect, &oldProtect);
}
}
if (*bytes == 0xFF8B) // mov edi, edi
{
char *address = ((char *)function) - 5;
DWORD oldProtect;
if (VirtualProtect(address, 7, PAGE_EXECUTE_READWRITE, &oldProtect))
{
if (memcmp(address, (const char[]) { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }, 5) == 0 ||
memcmp(address, (const char[]) { 0x90, 0x90, 0x90, 0x90, 0x90 }, 5) == 0)
{
address[0] = 0xE9; // long jump
*((DWORD *)(&address[1])) = ((char *)newFunction) - address - 5;
*((WORD *)(&address[5])) = 0xF9EB; // short jump to our long jump
result = (PROC)(((char *)function) + 2);
}
VirtualProtect(address, 7, oldProtect, &oldProtect);
}
}
return result;
}
void Hook_Create(char *moduleName, char *functionName, PROC newFunction, PROC *function)
{
if (!ddraw->hook)
return;
if (ddraw->hook >= 2)
#ifdef _MSC_VER
if (HookingMethod == 2)
{
FARPROC org = GetProcAddress(GetModuleHandle(moduleName), functionName);
if (org)
*function = Hook_HotPatch(org, newFunction);
if ((!org || *function == org) && ddraw->hook == 3) // hotpatch failed...
Hook_PatchIAT(GetModuleHandle(NULL), moduleName, functionName, newFunction);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID *)function, (PVOID)newFunction);
DetourTransactionCommit();
}
else
{
#endif
if (HookingMethod == 1)
Hook_PatchIAT(GetModuleHandle(NULL), moduleName, functionName, newFunction);
}
void Hook_Revert(char *moduleName, char *functionName, PROC newFunction, PROC *function)
{
#ifdef _MSC_VER
if (HookingMethod == 2)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach((PVOID *)function, (PVOID)newFunction);
DetourTransactionCommit();
}
#endif
if (HookingMethod == 1)
{
Hook_PatchIAT(
GetModuleHandle(NULL),
moduleName,
functionName,
GetProcAddress(GetModuleHandle(moduleName), functionName));
}
}
@ -177,7 +148,31 @@ void Hook_Init()
Hook_Create("user32.dll", "MoveWindow", (PROC)fake_MoveWindow, (PROC *)&real_MoveWindow);
Hook_Create("user32.dll", "SendMessageA", (PROC)fake_SendMessageA, (PROC *)&real_SendMessageA);
Hook_Create("user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC *)&real_SetWindowLongA);
//Hook_PatchIAT(GetModuleHandle(NULL), "user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos);
}
}
void Hook_Exit()
{
if (Hook_Active)
{
Hook_Active = FALSE;
Hook_Revert("user32.dll", "GetCursorPos", (PROC)fake_GetCursorPos, (PROC *)&real_GetCursorPos);
Hook_Revert("user32.dll", "ClipCursor", (PROC)fake_ClipCursor, (PROC *)&real_ClipCursor);
Hook_Revert("user32.dll", "ShowCursor", (PROC)fake_ShowCursor, (PROC *)&real_ShowCursor);
Hook_Revert("user32.dll", "SetCursor", (PROC)fake_SetCursor, (PROC *)&real_SetCursor);
Hook_Revert("user32.dll", "GetWindowRect", (PROC)fake_GetWindowRect, (PROC *)&real_GetWindowRect);
Hook_Revert("user32.dll", "GetClientRect", (PROC)fake_GetClientRect, (PROC *)&real_GetClientRect);
Hook_Revert("user32.dll", "ClientToScreen", (PROC)fake_ClientToScreen, (PROC *)&real_ClientToScreen);
Hook_Revert("user32.dll", "ScreenToClient", (PROC)fake_ScreenToClient, (PROC *)&real_ScreenToClient);
Hook_Revert("user32.dll", "SetCursorPos", (PROC)fake_SetCursorPos, (PROC *)&real_SetCursorPos);
Hook_Revert("user32.dll", "GetClipCursor", (PROC)fake_GetClipCursor, (PROC *)&real_GetClipCursor);
Hook_Revert("user32.dll", "WindowFromPoint", (PROC)fake_WindowFromPoint, (PROC *)&real_WindowFromPoint);
Hook_Revert("user32.dll", "GetCursorInfo", (PROC)fake_GetCursorInfo, (PROC *)&real_GetCursorInfo);
Hook_Revert("user32.dll", "GetSystemMetrics", (PROC)fake_GetSystemMetrics, (PROC *)&real_GetSystemMetrics);
Hook_Revert("user32.dll", "SetWindowPos", (PROC)fake_SetWindowPos, (PROC *)&real_SetWindowPos);
Hook_Revert("user32.dll", "MoveWindow", (PROC)fake_MoveWindow, (PROC *)&real_MoveWindow);
Hook_Revert("user32.dll", "SendMessageA", (PROC)fake_SendMessageA, (PROC *)&real_SendMessageA);
Hook_Revert("user32.dll", "SetWindowLongA", (PROC)fake_SetWindowLongA, (PROC *)&real_SetWindowLongA);
}
}

View File

@ -36,7 +36,8 @@
BOOL screenshot(struct IDirectDrawSurfaceImpl *);
void Settings_Load();
void Settings_Save(RECT *lpRect, int windowState);
void dinput_init();
void DInput_Hook();
void DInput_UnHook();
IDirectDrawImpl *ddraw = NULL;
@ -112,7 +113,7 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
}
timeBeginPeriod(1);
dinput_init();
DInput_Hook();
break;
}
case DLL_PROCESS_DETACH:
@ -122,6 +123,8 @@ BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
Settings_Save(&WindowRect, WindowState);
timeEndPeriod(1);
Hook_Exit();
DInput_UnHook();
break;
}
}

View File

@ -5,6 +5,7 @@
#include "main.h"
#include "opengl.h"
#include "render_d3d9.h"
#include "hook.h"
static char SettingsIniPath[MAX_PATH];
static char ProcessFileName[96];
@ -47,7 +48,10 @@ void Settings_Load()
WindowRect.left = GetInt("posX", -32000);
WindowRect.top = GetInt("posY", -32000);
ddraw->hook = GetInt("hook", 1);
#ifndef _DEBUG
HookingMethod = GetInt("hook", 1);
#endif
ddraw->render.maxfps = GetInt("maxfps", 125);
if (ddraw->accurateTimers || ddraw->vsync)
@ -275,7 +279,7 @@ static void CreateSettingsIni()
"; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n"
"singlecpu=true\n"
"\n"
"; Windows API Hooking, Possible values: 0 = disabled, 1 = IAT Hooking, 2 = HotPatch, 3 = Try HotPatch / fallback = IAT Hooking\n"
"; Windows API Hooking, Possible values: 0 = disabled, 1 = IAT Hooking, 2 = Microsoft Detours\n"
"; Note: Can be used to fix issues related to new features added by cnc-ddraw such as windowed mode or stretching\n"
"hook=1\n"
"\n"