├── .gitignore ├── Detours-4.0.1 ├── CREDITS.TXT ├── LICENSE.md ├── Makefile ├── README.md ├── include │ ├── detours.h │ └── detver.h ├── lib.X64 │ ├── detours.lib │ └── detours.pdb ├── lib.X86 │ ├── detours.lib │ └── detours.pdb ├── src │ ├── Makefile │ ├── creatwth.cpp │ ├── detours.cpp │ ├── detours.h │ ├── detver.h │ ├── disasm.cpp │ ├── disolarm.cpp │ ├── disolarm64.cpp │ ├── disolia64.cpp │ ├── disolx64.cpp │ ├── disolx86.cpp │ ├── image.cpp │ ├── modules.cpp │ └── uimports.cpp └── system.mak ├── Makefile ├── README ├── bin ├── x64 │ ├── mstscdump.exe │ └── mstschook.dll └── x86 │ ├── mstscdump.exe │ └── mstschook.dll ├── build.bat ├── mstscax.tlh ├── mstscax.tli ├── mstscdump.cpp ├── mstscdump.sln ├── mstscdump ├── mstscdump.vcxproj └── mstscdump.vcxproj.filters ├── mstschook.cpp └── mstschook ├── mstschook.vcxproj └── mstschook.vcxproj.filters /.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | *.vcxproj.user 3 | x86 4 | x64 -------------------------------------------------------------------------------- /Detours-4.0.1/CREDITS.TXT: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | The following individuals have helped identify specific bugs and improvements 3 | in Detours. The entire Detours community has benefited from their help. 4 | ============================================================================== 5 | 6 | * Jay Krell: Identified issue with VirtualSize == 0 files created in 7 | NT 3.1 images. (Build_339) 8 | 9 | * Igor Odnovorov: Identified an issue with the placement of the trampoline 10 | region when a function is detoured twice and the second 11 | trampoline region is outside of the +/- 2GB range of 12 | the target. (Build_337) 13 | 14 | * Jay Krell: Identified need for some programs to enumerate the 15 | address of IAT entries. (Build_336) 16 | 17 | * Calvin Hsia: Identified need for some program to change the excluded 18 | system region. (Build_336) 19 | 20 | * Adam Smith: Identified error in failure handling when VirtualProect 21 | cannot make pages executable because the Prohibit 22 | Dynamic Code Generation mitigation policy has been 23 | applied to a process. (Build_335) 24 | 25 | * Ben Faull: Identified fix to detour_alloc_region_from_lo and 26 | detour_alloc_region_from_hi that preserves ASLR entropy. 27 | (Build_334) 28 | 29 | * Shaoxiang Su: Reported errors building with Visual Studio 2015. 30 | (Build_332) 31 | 32 | * Jay Krell: Identified and resolved significant gaps in the X86, X64 33 | and IA64 disassemblers for instruction found in code, 34 | but seldom found in function prologues. (Build_331) 35 | 36 | * Allan Murphy: Identify error in rep and jmp ds: encodings. (Build_331) 37 | 38 | * Philip Bacon: Identified incorrect entry point return for pure 39 | resource-only binaries. (Build_330) 40 | 41 | * Jay Krell: Identified failure in DetourAttachEx to update nAlign. 42 | (Build_330) 43 | 44 | * Sumit Sarin: Helped debug error with packed binaries. 45 | (Build_329) 46 | 47 | * Nitya Kumar Sharma: Reported bug in DetourAfterWithDll for 32/64 agnostic 48 | EXEs. 49 | (Build_327) 50 | 51 | * Richard Black: Identified a large number of typos in documentation. 52 | (Build_326) 53 | 54 | * Michael Bilodeau: Identified bug in DetourUpdateProcessWithDll when the 55 | target process contains a Detours payload *after* all 56 | valid PE binaries. 57 | (Build_324) 58 | 59 | * Meera Jindal: Reported bug in identification of target address in 60 | DetourCopyInstruction for jmp[] and call[] on x86 & x64, 61 | the ff15 and ff25 opcodes. 62 | (Build_323) 63 | 64 | * Ken Johnson: Assistance with SAL 2.0 annotations. 65 | (Build_319) 66 | 67 | * Nick Wood: Identified bug in DetourFindFunction on ARM. 68 | (Build_314) 69 | 70 | * Mark Russinovich: Helped debug DetourCreateProcessWithDllEx. 71 | (Build_314) 72 | 73 | * John Lin: Implementation idea for DetoursCreateProcessWithDllEx. 74 | (Build_314) 75 | 76 | * Andrew Zawadowskiy Reported an improper memory page permissions 77 | vulnerability in Detours 2.1. (Vulnerability does not 78 | exist in versions later than Detours 2.1.) 79 | (Build_223) 80 | 81 | * Nightxie: Identified bug in detour_alloc_round_up_to_region. 82 | (Build_310) 83 | 84 | * Diana Milirud: Identified bug in B* instructions on ARM. 85 | (Build_309) 86 | 87 | * Juan Carlos Identified correct MSIL entry point for unsigned MSIL. 88 | Luciani: (Build_308) 89 | 90 | * Lee Hunt Suggested improvements in algorithm for allocation of 91 | Lawrence Landauer trampoline regions on x64 to avoid collisions with 92 | Joe Laughlin: system DLLs. 93 | (Build_307) 94 | 95 | * Tyler Sims Identified bug in handling of "anycpu" MSIL binaries 96 | Darren Kennedy: on x64. 97 | (Build_307) 98 | 99 | * Andre Vachon: Help with optimized binaries. 100 | (Build 301) 101 | 102 | * Chris Mann: Identified fix not forward ported from 2.2 to 3.0. 103 | (Build_301) 104 | 105 | * Mark Irving: Identified bug with EXEs missing second import table. 106 | (Build_300) 107 | 108 | * Ben Schwarz: Identified bug in handling of multi-byte NOPs. 109 | (Build_300) 110 | 111 | * Aaron Giles Coded initial ARM/Thumb2 disassembler. 112 | Jared Henderson: (Build_300) 113 | 114 | * Doug Brubacher: Coded initial x86 disassembler. 115 | (Build_100) 116 | -------------------------------------------------------------------------------- /Detours-4.0.1/LICENSE.md: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation 2 | 3 | All rights reserved. 4 | 5 | # MIT License 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 11 | of the Software, and to permit persons to whom the Software is furnished to do 12 | so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /Detours-4.0.1/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | ## 3 | ## Makefile for Detours. 4 | ## 5 | ## Microsoft Research Detours Package 6 | ## 7 | ## Copyright (c) Microsoft Corporation. All rights reserved. 8 | ## 9 | 10 | ROOT = . 11 | !include "$(ROOT)\system.mak" 12 | 13 | all: 14 | cd "$(MAKEDIR)" 15 | @if exist "$(MAKEDIR)\core\makefile" cd "$(MAKEDIR)\core" && $(MAKE) /NOLOGO /$(MAKEFLAGS) 16 | cd "$(MAKEDIR)\src" 17 | @$(MAKE) /NOLOGO /$(MAKEFLAGS) 18 | cd "$(MAKEDIR)\samples" 19 | @$(MAKE) /NOLOGO /$(MAKEFLAGS) 20 | @if exist "$(MAKEDIR)\bugs\makefile" cd "$(MAKEDIR)\bugs" && $(MAKE) /NOLOGO /$(MAKEFLAGS) 21 | cd "$(MAKEDIR)" 22 | 23 | clean: 24 | cd "$(MAKEDIR)" 25 | @if exist "$(MAKEDIR)\core\makefile" cd "$(MAKEDIR)\core" && $(MAKE) /NOLOGO /$(MAKEFLAGS) clean 26 | cd "$(MAKEDIR)\src" 27 | @$(MAKE) /NOLOGO /$(MAKEFLAGS) clean 28 | cd "$(MAKEDIR)\samples" 29 | @$(MAKE) /NOLOGO /$(MAKEFLAGS) clean 30 | @if exist "$(MAKEDIR)\bugs\makefile" cd "$(MAKEDIR)\bugs" && $(MAKE) /NOLOGO /$(MAKEFLAGS) clean 31 | cd "$(MAKEDIR)" 32 | 33 | realclean: clean 34 | cd "$(MAKEDIR)" 35 | @if exist "$(MAKEDIR)\core\makefile" cd "$(MAKEDIR)\core" && $(MAKE) /NOLOGO /$(MAKEFLAGS) realclean 36 | cd "$(MAKEDIR)\src" 37 | @$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean 38 | cd "$(MAKEDIR)\samples" 39 | @$(MAKE) /NOLOGO /$(MAKEFLAGS) realclean 40 | @if exist "$(MAKEDIR)\bugs\makefile" cd "$(MAKEDIR)\bugs" && $(MAKE) /NOLOGO /$(MAKEFLAGS) realclean 41 | cd "$(MAKEDIR)" 42 | -rmdir /q /s $(INCDS) 2> nul 43 | -rmdir /q /s $(LIBDS) 2> nul 44 | -rmdir /q /s $(BINDS) 2> nul 45 | -rmdir /q /s dist 2> nul 46 | -del docsrc\detours.chm 2> nul 47 | -del /q *.msi 2>nul 48 | -del /q /f /s *~ 2>nul 49 | 50 | test: 51 | cd "$(MAKEDIR)\samples" 52 | @$(MAKE) /NOLOGO /$(MAKEFLAGS) test 53 | cd "$(MAKEDIR)" 54 | 55 | ################################################################# End of File. 56 | -------------------------------------------------------------------------------- /Detours-4.0.1/README.md: -------------------------------------------------------------------------------- 1 | # Microsoft Research Detours Package 2 | 3 | Detours is a software package for monitoring and instrumenting API calls on Windows. Detours 4 | has been used by many ISVs and is also used by product teams at Microsoft. Detours is now available under 5 | a standard open source license (MIT). This simplifies licensing for programmers using Detours 6 | and allows the community to support Detours using open source tools and processes. 7 | 8 | Detours is compatible with the Windows NT family of 9 | operating systems: Windows NT, Windows XP, Windows Server 2003, Windows 7, 10 | Windows 8, and Windows 10. It cannot be used by Window Store apps 11 | because Detours requires APIs not available to those applications. 12 | This repo contains the source code for version 4.0.1 of Detours. 13 | 14 | For technical documentation on Detours, see the [Detours Wiki](https://github.com/microsoft/Detours/wiki). 15 | For directions on how to build and run samples, see the 16 | samples [README.txt](https://github.com/Microsoft/Detours/blob/master/samples/README.TXT) file. 17 | 18 | ## Contributing 19 | 20 | The [`Detours`](https://github.com/microsoft/detours) repository is where development is done. 21 | Here are some ways you can participate in the project: 22 | 23 | * [Answer questions](https://github.com/microsoft/detours/issues) about using Detours. 24 | * [Improve the Wiki](https://github.com/microsoft/detours/Wiki). 25 | * [Submit bugs](https://github.com/microsoft/detours/issues) and help us verify fixes and changes as they are checked in. 26 | * Review [source code changes](https://github.com/microsoft/detours/pulls). 27 | 28 | 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. 29 | 30 | ## Issues, questions, and feedback 31 | 32 | * Open an issue on [GitHub Issues](https://github.com/Microsoft/detours/issues). 33 | 34 | ## License 35 | 36 | Copyright (c) Microsoft Corporation. All rights reserved. 37 | 38 | Licensed under the [MIT](LICENSE.txt) License. 39 | -------------------------------------------------------------------------------- /Detours-4.0.1/include/detours.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Core Detours Functionality (detours.h of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #pragma once 11 | #ifndef _DETOURS_H_ 12 | #define _DETOURS_H_ 13 | 14 | #define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH 15 | 16 | ////////////////////////////////////////////////////////////////////////////// 17 | // 18 | 19 | #undef DETOURS_X64 20 | #undef DETOURS_X86 21 | #undef DETOURS_IA64 22 | #undef DETOURS_ARM 23 | #undef DETOURS_ARM64 24 | #undef DETOURS_BITS 25 | #undef DETOURS_32BIT 26 | #undef DETOURS_64BIT 27 | 28 | #if defined(_X86_) 29 | #define DETOURS_X86 30 | #define DETOURS_OPTION_BITS 64 31 | 32 | #elif defined(_AMD64_) 33 | #define DETOURS_X64 34 | #define DETOURS_OPTION_BITS 32 35 | 36 | #elif defined(_IA64_) 37 | #define DETOURS_IA64 38 | #define DETOURS_OPTION_BITS 32 39 | 40 | #elif defined(_ARM_) 41 | #define DETOURS_ARM 42 | 43 | #elif defined(_ARM64_) 44 | #define DETOURS_ARM64 45 | 46 | #else 47 | #error Unknown architecture (x86, amd64, ia64, arm, arm64) 48 | #endif 49 | 50 | #ifdef _WIN64 51 | #undef DETOURS_32BIT 52 | #define DETOURS_64BIT 1 53 | #define DETOURS_BITS 64 54 | // If all 64bit kernels can run one and only one 32bit architecture. 55 | //#define DETOURS_OPTION_BITS 32 56 | #else 57 | #define DETOURS_32BIT 1 58 | #undef DETOURS_64BIT 59 | #define DETOURS_BITS 32 60 | // If all 64bit kernels can run one and only one 32bit architecture. 61 | //#define DETOURS_OPTION_BITS 32 62 | #endif 63 | 64 | #define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS) 65 | 66 | ////////////////////////////////////////////////////////////////////////////// 67 | // 68 | 69 | #if (_MSC_VER < 1299) 70 | typedef LONG LONG_PTR; 71 | typedef ULONG ULONG_PTR; 72 | #endif 73 | 74 | ///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. 75 | // 76 | // These definitions are include so that Detours will build even if the 77 | // compiler doesn't have full SAL 2.0 support. 78 | // 79 | #ifndef DETOURS_DONT_REMOVE_SAL_20 80 | 81 | #ifdef DETOURS_TEST_REMOVE_SAL_20 82 | #undef _Analysis_assume_ 83 | #undef _Benign_race_begin_ 84 | #undef _Benign_race_end_ 85 | #undef _Field_range_ 86 | #undef _Field_size_ 87 | #undef _In_ 88 | #undef _In_bytecount_ 89 | #undef _In_count_ 90 | #undef _In_opt_ 91 | #undef _In_opt_bytecount_ 92 | #undef _In_opt_count_ 93 | #undef _In_opt_z_ 94 | #undef _In_range_ 95 | #undef _In_reads_ 96 | #undef _In_reads_bytes_ 97 | #undef _In_reads_opt_ 98 | #undef _In_reads_opt_bytes_ 99 | #undef _In_reads_or_z_ 100 | #undef _In_z_ 101 | #undef _Inout_ 102 | #undef _Inout_opt_ 103 | #undef _Inout_z_count_ 104 | #undef _Out_ 105 | #undef _Out_opt_ 106 | #undef _Out_writes_ 107 | #undef _Outptr_result_maybenull_ 108 | #undef _Readable_bytes_ 109 | #undef _Success_ 110 | #undef _Writable_bytes_ 111 | #undef _Pre_notnull_ 112 | #endif 113 | 114 | #if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) 115 | #define _Outptr_result_maybenull_ _Deref_out_opt_z_ 116 | #endif 117 | 118 | #if defined(_In_count_) && !defined(_In_reads_) 119 | #define _In_reads_(x) _In_count_(x) 120 | #endif 121 | 122 | #if defined(_In_opt_count_) && !defined(_In_reads_opt_) 123 | #define _In_reads_opt_(x) _In_opt_count_(x) 124 | #endif 125 | 126 | #if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) 127 | #define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) 128 | #endif 129 | 130 | #if defined(_In_bytecount_) && !defined(_In_reads_bytes_) 131 | #define _In_reads_bytes_(x) _In_bytecount_(x) 132 | #endif 133 | 134 | #ifndef _In_ 135 | #define _In_ 136 | #endif 137 | 138 | #ifndef _In_bytecount_ 139 | #define _In_bytecount_(x) 140 | #endif 141 | 142 | #ifndef _In_count_ 143 | #define _In_count_(x) 144 | #endif 145 | 146 | #ifndef _In_opt_ 147 | #define _In_opt_ 148 | #endif 149 | 150 | #ifndef _In_opt_bytecount_ 151 | #define _In_opt_bytecount_(x) 152 | #endif 153 | 154 | #ifndef _In_opt_count_ 155 | #define _In_opt_count_(x) 156 | #endif 157 | 158 | #ifndef _In_opt_z_ 159 | #define _In_opt_z_ 160 | #endif 161 | 162 | #ifndef _In_range_ 163 | #define _In_range_(x,y) 164 | #endif 165 | 166 | #ifndef _In_reads_ 167 | #define _In_reads_(x) 168 | #endif 169 | 170 | #ifndef _In_reads_bytes_ 171 | #define _In_reads_bytes_(x) 172 | #endif 173 | 174 | #ifndef _In_reads_opt_ 175 | #define _In_reads_opt_(x) 176 | #endif 177 | 178 | #ifndef _In_reads_opt_bytes_ 179 | #define _In_reads_opt_bytes_(x) 180 | #endif 181 | 182 | #ifndef _In_reads_or_z_ 183 | #define _In_reads_or_z_ 184 | #endif 185 | 186 | #ifndef _In_z_ 187 | #define _In_z_ 188 | #endif 189 | 190 | #ifndef _Inout_ 191 | #define _Inout_ 192 | #endif 193 | 194 | #ifndef _Inout_opt_ 195 | #define _Inout_opt_ 196 | #endif 197 | 198 | #ifndef _Inout_z_count_ 199 | #define _Inout_z_count_(x) 200 | #endif 201 | 202 | #ifndef _Out_ 203 | #define _Out_ 204 | #endif 205 | 206 | #ifndef _Out_opt_ 207 | #define _Out_opt_ 208 | #endif 209 | 210 | #ifndef _Out_writes_ 211 | #define _Out_writes_(x) 212 | #endif 213 | 214 | #ifndef _Outptr_result_maybenull_ 215 | #define _Outptr_result_maybenull_ 216 | #endif 217 | 218 | #ifndef _Writable_bytes_ 219 | #define _Writable_bytes_(x) 220 | #endif 221 | 222 | #ifndef _Readable_bytes_ 223 | #define _Readable_bytes_(x) 224 | #endif 225 | 226 | #ifndef _Success_ 227 | #define _Success_(x) 228 | #endif 229 | 230 | #ifndef _Pre_notnull_ 231 | #define _Pre_notnull_ 232 | #endif 233 | 234 | #ifdef DETOURS_INTERNAL 235 | 236 | #pragma warning(disable:4615) // unknown warning type (suppress with older compilers) 237 | 238 | #ifndef _Benign_race_begin_ 239 | #define _Benign_race_begin_ 240 | #endif 241 | 242 | #ifndef _Benign_race_end_ 243 | #define _Benign_race_end_ 244 | #endif 245 | 246 | #ifndef _Field_size_ 247 | #define _Field_size_(x) 248 | #endif 249 | 250 | #ifndef _Field_range_ 251 | #define _Field_range_(x,y) 252 | #endif 253 | 254 | #ifndef _Analysis_assume_ 255 | #define _Analysis_assume_(x) 256 | #endif 257 | 258 | #endif // DETOURS_INTERNAL 259 | #endif // DETOURS_DONT_REMOVE_SAL_20 260 | 261 | ////////////////////////////////////////////////////////////////////////////// 262 | // 263 | #ifndef GUID_DEFINED 264 | #define GUID_DEFINED 265 | typedef struct _GUID 266 | { 267 | DWORD Data1; 268 | WORD Data2; 269 | WORD Data3; 270 | BYTE Data4[ 8 ]; 271 | } GUID; 272 | 273 | #ifdef INITGUID 274 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 275 | const GUID name \ 276 | = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } 277 | #else 278 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 279 | const GUID name 280 | #endif // INITGUID 281 | #endif // !GUID_DEFINED 282 | 283 | #if defined(__cplusplus) 284 | #ifndef _REFGUID_DEFINED 285 | #define _REFGUID_DEFINED 286 | #define REFGUID const GUID & 287 | #endif // !_REFGUID_DEFINED 288 | #else // !__cplusplus 289 | #ifndef _REFGUID_DEFINED 290 | #define _REFGUID_DEFINED 291 | #define REFGUID const GUID * const 292 | #endif // !_REFGUID_DEFINED 293 | #endif // !__cplusplus 294 | 295 | #ifndef ARRAYSIZE 296 | #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) 297 | #endif 298 | 299 | // 300 | ////////////////////////////////////////////////////////////////////////////// 301 | 302 | #ifdef __cplusplus 303 | extern "C" { 304 | #endif // __cplusplus 305 | 306 | /////////////////////////////////////////////////// Instruction Target Macros. 307 | // 308 | #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) 309 | #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) 310 | #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" 311 | 312 | extern const GUID DETOUR_EXE_RESTORE_GUID; 313 | extern const GUID DETOUR_EXE_HELPER_GUID; 314 | 315 | #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! 316 | typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; 317 | 318 | /////////////////////////////////////////////////////////// Binary Structures. 319 | // 320 | #pragma pack(push, 8) 321 | typedef struct _DETOUR_SECTION_HEADER 322 | { 323 | DWORD cbHeaderSize; 324 | DWORD nSignature; 325 | DWORD nDataOffset; 326 | DWORD cbDataSize; 327 | 328 | DWORD nOriginalImportVirtualAddress; 329 | DWORD nOriginalImportSize; 330 | DWORD nOriginalBoundImportVirtualAddress; 331 | DWORD nOriginalBoundImportSize; 332 | 333 | DWORD nOriginalIatVirtualAddress; 334 | DWORD nOriginalIatSize; 335 | DWORD nOriginalSizeOfImage; 336 | DWORD cbPrePE; 337 | 338 | DWORD nOriginalClrFlags; 339 | DWORD reserved1; 340 | DWORD reserved2; 341 | DWORD reserved3; 342 | 343 | // Followed by cbPrePE bytes of data. 344 | } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; 345 | 346 | typedef struct _DETOUR_SECTION_RECORD 347 | { 348 | DWORD cbBytes; 349 | DWORD nReserved; 350 | GUID guid; 351 | } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; 352 | 353 | typedef struct _DETOUR_CLR_HEADER 354 | { 355 | // Header versioning 356 | ULONG cb; 357 | USHORT MajorRuntimeVersion; 358 | USHORT MinorRuntimeVersion; 359 | 360 | // Symbol table and startup information 361 | IMAGE_DATA_DIRECTORY MetaData; 362 | ULONG Flags; 363 | 364 | // Followed by the rest of the IMAGE_COR20_HEADER 365 | } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; 366 | 367 | typedef struct _DETOUR_EXE_RESTORE 368 | { 369 | DWORD cb; 370 | DWORD cbidh; 371 | DWORD cbinh; 372 | DWORD cbclr; 373 | 374 | PBYTE pidh; 375 | PBYTE pinh; 376 | PBYTE pclr; 377 | 378 | IMAGE_DOS_HEADER idh; 379 | union { 380 | IMAGE_NT_HEADERS inh; 381 | IMAGE_NT_HEADERS32 inh32; 382 | IMAGE_NT_HEADERS64 inh64; 383 | BYTE raw[sizeof(IMAGE_NT_HEADERS64) + 384 | sizeof(IMAGE_SECTION_HEADER) * 32]; 385 | }; 386 | DETOUR_CLR_HEADER clr; 387 | 388 | } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; 389 | 390 | typedef struct _DETOUR_EXE_HELPER 391 | { 392 | DWORD cb; 393 | DWORD pid; 394 | DWORD nDlls; 395 | CHAR rDlls[4]; 396 | } DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; 397 | 398 | #pragma pack(pop) 399 | 400 | #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ 401 | { \ 402 | sizeof(DETOUR_SECTION_HEADER),\ 403 | DETOUR_SECTION_HEADER_SIGNATURE,\ 404 | sizeof(DETOUR_SECTION_HEADER),\ 405 | (cbSectionSize),\ 406 | \ 407 | 0,\ 408 | 0,\ 409 | 0,\ 410 | 0,\ 411 | \ 412 | 0,\ 413 | 0,\ 414 | 0,\ 415 | 0,\ 416 | } 417 | 418 | /////////////////////////////////////////////////////////////// Helper Macros. 419 | // 420 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 421 | #define DETOURS_STRINGIFY_(x) #x 422 | 423 | ///////////////////////////////////////////////////////////// Binary Typedefs. 424 | // 425 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( 426 | _In_opt_ PVOID pContext, 427 | _In_opt_ LPCSTR pszFile, 428 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 429 | 430 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( 431 | _In_opt_ PVOID pContext, 432 | _In_ LPCSTR pszOrigFile, 433 | _In_ LPCSTR pszFile, 434 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 435 | 436 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( 437 | _In_opt_ PVOID pContext, 438 | _In_ ULONG nOrigOrdinal, 439 | _In_ ULONG nOrdinal, 440 | _Out_ ULONG *pnOutOrdinal, 441 | _In_opt_ LPCSTR pszOrigSymbol, 442 | _In_opt_ LPCSTR pszSymbol, 443 | _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); 444 | 445 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( 446 | _In_opt_ PVOID pContext); 447 | 448 | typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, 449 | _In_ ULONG nOrdinal, 450 | _In_opt_ LPCSTR pszName, 451 | _In_opt_ PVOID pCode); 452 | 453 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, 454 | _In_opt_ HMODULE hModule, 455 | _In_opt_ LPCSTR pszFile); 456 | 457 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, 458 | _In_ DWORD nOrdinal, 459 | _In_opt_ LPCSTR pszFunc, 460 | _In_opt_ PVOID pvFunc); 461 | 462 | // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. 463 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, 464 | _In_ DWORD nOrdinal, 465 | _In_opt_ LPCSTR pszFunc, 466 | _In_opt_ PVOID* ppvFunc); 467 | 468 | typedef VOID * PDETOUR_BINARY; 469 | typedef VOID * PDETOUR_LOADED_BINARY; 470 | 471 | //////////////////////////////////////////////////////////// Transaction APIs. 472 | // 473 | LONG WINAPI DetourTransactionBegin(VOID); 474 | LONG WINAPI DetourTransactionAbort(VOID); 475 | LONG WINAPI DetourTransactionCommit(VOID); 476 | LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); 477 | 478 | LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); 479 | 480 | LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, 481 | _In_ PVOID pDetour); 482 | 483 | LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, 484 | _In_ PVOID pDetour, 485 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 486 | _Out_opt_ PVOID *ppRealTarget, 487 | _Out_opt_ PVOID *ppRealDetour); 488 | 489 | LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, 490 | _In_ PVOID pDetour); 491 | 492 | BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); 493 | BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); 494 | PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); 495 | PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); 496 | 497 | ////////////////////////////////////////////////////////////// Code Functions. 498 | // 499 | PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, 500 | _In_ LPCSTR pszFunction); 501 | PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, 502 | _Out_opt_ PVOID *ppGlobals); 503 | PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, 504 | _Inout_opt_ PVOID *ppDstPool, 505 | _In_ PVOID pSrc, 506 | _Out_opt_ PVOID *ppTarget, 507 | _Out_opt_ LONG *plExtra); 508 | BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, 509 | _In_ BOOL fLimitReferencesToModule); 510 | 511 | ///////////////////////////////////////////////////// Loaded Binary Functions. 512 | // 513 | HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); 514 | HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); 515 | PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); 516 | ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); 517 | BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, 518 | _In_opt_ PVOID pContext, 519 | _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); 520 | BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, 521 | _In_opt_ PVOID pContext, 522 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 523 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); 524 | 525 | BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, 526 | _In_opt_ PVOID pContext, 527 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 528 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); 529 | 530 | _Writable_bytes_(*pcbData) 531 | _Readable_bytes_(*pcbData) 532 | _Success_(return != NULL) 533 | PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, 534 | _In_ REFGUID rguid, 535 | _Out_ DWORD *pcbData); 536 | 537 | _Writable_bytes_(*pcbData) 538 | _Readable_bytes_(*pcbData) 539 | _Success_(return != NULL) 540 | PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, 541 | _Out_ DWORD * pcbData); 542 | 543 | DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); 544 | 545 | ///////////////////////////////////////////////// Persistent Binary Functions. 546 | // 547 | 548 | PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); 549 | 550 | _Writable_bytes_(*pcbData) 551 | _Readable_bytes_(*pcbData) 552 | _Success_(return != NULL) 553 | PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, 554 | _Out_opt_ GUID *pGuid, 555 | _Out_ DWORD *pcbData, 556 | _Inout_ DWORD *pnIterator); 557 | 558 | _Writable_bytes_(*pcbData) 559 | _Readable_bytes_(*pcbData) 560 | _Success_(return != NULL) 561 | PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, 562 | _In_ REFGUID rguid, 563 | _Out_ DWORD *pcbData); 564 | 565 | PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, 566 | _In_ REFGUID rguid, 567 | _In_reads_opt_(cbData) PVOID pData, 568 | _In_ DWORD cbData); 569 | BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); 570 | BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); 571 | BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); 572 | BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, 573 | _In_opt_ PVOID pContext, 574 | _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, 575 | _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, 576 | _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, 577 | _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); 578 | BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); 579 | BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); 580 | 581 | /////////////////////////////////////////////////// Create Process & Load Dll. 582 | // 583 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( 584 | _In_opt_ LPCSTR lpApplicationName, 585 | _Inout_opt_ LPSTR lpCommandLine, 586 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 587 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 588 | _In_ BOOL bInheritHandles, 589 | _In_ DWORD dwCreationFlags, 590 | _In_opt_ LPVOID lpEnvironment, 591 | _In_opt_ LPCSTR lpCurrentDirectory, 592 | _In_ LPSTARTUPINFOA lpStartupInfo, 593 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 594 | 595 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( 596 | _In_opt_ LPCWSTR lpApplicationName, 597 | _Inout_opt_ LPWSTR lpCommandLine, 598 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 599 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 600 | _In_ BOOL bInheritHandles, 601 | _In_ DWORD dwCreationFlags, 602 | _In_opt_ LPVOID lpEnvironment, 603 | _In_opt_ LPCWSTR lpCurrentDirectory, 604 | _In_ LPSTARTUPINFOW lpStartupInfo, 605 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 606 | 607 | BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, 608 | _Inout_opt_ LPSTR lpCommandLine, 609 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 610 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 611 | _In_ BOOL bInheritHandles, 612 | _In_ DWORD dwCreationFlags, 613 | _In_opt_ LPVOID lpEnvironment, 614 | _In_opt_ LPCSTR lpCurrentDirectory, 615 | _In_ LPSTARTUPINFOA lpStartupInfo, 616 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 617 | _In_ LPCSTR lpDllName, 618 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 619 | 620 | BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, 621 | _Inout_opt_ LPWSTR lpCommandLine, 622 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 623 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 624 | _In_ BOOL bInheritHandles, 625 | _In_ DWORD dwCreationFlags, 626 | _In_opt_ LPVOID lpEnvironment, 627 | _In_opt_ LPCWSTR lpCurrentDirectory, 628 | _In_ LPSTARTUPINFOW lpStartupInfo, 629 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 630 | _In_ LPCSTR lpDllName, 631 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 632 | 633 | #ifdef UNICODE 634 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllW 635 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW 636 | #else 637 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllA 638 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA 639 | #endif // !UNICODE 640 | 641 | BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, 642 | _Inout_opt_ LPSTR lpCommandLine, 643 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 644 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 645 | _In_ BOOL bInheritHandles, 646 | _In_ DWORD dwCreationFlags, 647 | _In_opt_ LPVOID lpEnvironment, 648 | _In_opt_ LPCSTR lpCurrentDirectory, 649 | _In_ LPSTARTUPINFOA lpStartupInfo, 650 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 651 | _In_ LPCSTR lpDllName, 652 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 653 | 654 | BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, 655 | _Inout_opt_ LPWSTR lpCommandLine, 656 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 657 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 658 | _In_ BOOL bInheritHandles, 659 | _In_ DWORD dwCreationFlags, 660 | _In_opt_ LPVOID lpEnvironment, 661 | _In_opt_ LPCWSTR lpCurrentDirectory, 662 | _In_ LPSTARTUPINFOW lpStartupInfo, 663 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 664 | _In_ LPCSTR lpDllName, 665 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 666 | 667 | #ifdef UNICODE 668 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW 669 | #else 670 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA 671 | #endif // !UNICODE 672 | 673 | BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, 674 | _Inout_opt_ LPSTR lpCommandLine, 675 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 676 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 677 | _In_ BOOL bInheritHandles, 678 | _In_ DWORD dwCreationFlags, 679 | _In_opt_ LPVOID lpEnvironment, 680 | _In_opt_ LPCSTR lpCurrentDirectory, 681 | _In_ LPSTARTUPINFOA lpStartupInfo, 682 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 683 | _In_ DWORD nDlls, 684 | _In_reads_(nDlls) LPCSTR *rlpDlls, 685 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 686 | 687 | BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, 688 | _Inout_opt_ LPWSTR lpCommandLine, 689 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 690 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 691 | _In_ BOOL bInheritHandles, 692 | _In_ DWORD dwCreationFlags, 693 | _In_opt_ LPVOID lpEnvironment, 694 | _In_opt_ LPCWSTR lpCurrentDirectory, 695 | _In_ LPSTARTUPINFOW lpStartupInfo, 696 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 697 | _In_ DWORD nDlls, 698 | _In_reads_(nDlls) LPCSTR *rlpDlls, 699 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 700 | 701 | #ifdef UNICODE 702 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW 703 | #else 704 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA 705 | #endif // !UNICODE 706 | 707 | BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, 708 | _In_ LPCSTR lpDllName, 709 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 710 | 711 | BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, 712 | _In_ LPCSTR lpDllName, 713 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 714 | 715 | #ifdef UNICODE 716 | #define DetourProcessViaHelper DetourProcessViaHelperW 717 | #else 718 | #define DetourProcessViaHelper DetourProcessViaHelperA 719 | #endif // !UNICODE 720 | 721 | BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, 722 | _In_ DWORD nDlls, 723 | _In_reads_(nDlls) LPCSTR *rlpDlls, 724 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 725 | 726 | BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, 727 | _In_ DWORD nDlls, 728 | _In_reads_(nDlls) LPCSTR *rlpDlls, 729 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 730 | 731 | #ifdef UNICODE 732 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW 733 | #else 734 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA 735 | #endif // !UNICODE 736 | 737 | BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, 738 | _In_reads_(nDlls) LPCSTR *rlpDlls, 739 | _In_ DWORD nDlls); 740 | 741 | BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, 742 | _In_ HMODULE hImage, 743 | _In_ BOOL bIs32Bit, 744 | _In_reads_(nDlls) LPCSTR *rlpDlls, 745 | _In_ DWORD nDlls); 746 | 747 | BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, 748 | _In_ REFGUID rguid, 749 | _In_reads_bytes_(cbData) PVOID pvData, 750 | _In_ DWORD cbData); 751 | BOOL WINAPI DetourRestoreAfterWith(VOID); 752 | BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 753 | _In_ DWORD cbData); 754 | BOOL WINAPI DetourIsHelperProcess(VOID); 755 | VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, 756 | _In_ HINSTANCE, 757 | _In_ LPSTR, 758 | _In_ INT); 759 | 760 | // 761 | ////////////////////////////////////////////////////////////////////////////// 762 | #ifdef __cplusplus 763 | } 764 | #endif // __cplusplus 765 | 766 | //////////////////////////////////////////////// Detours Internal Definitions. 767 | // 768 | #ifdef __cplusplus 769 | #ifdef DETOURS_INTERNAL 770 | 771 | #define NOTHROW 772 | // #define NOTHROW (nothrow) 773 | 774 | ////////////////////////////////////////////////////////////////////////////// 775 | // 776 | #if (_MSC_VER < 1299) 777 | #include 778 | typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; 779 | typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; 780 | typedef IMAGEHLP_SYMBOL SYMBOL_INFO; 781 | typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; 782 | 783 | static inline 784 | LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) 785 | { 786 | return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); 787 | } 788 | #else 789 | #pragma warning(push) 790 | #pragma warning(disable:4091) // empty typedef 791 | #include 792 | #pragma warning(pop) 793 | #endif 794 | 795 | #ifdef IMAGEAPI // defined by DBGHELP.H 796 | typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); 797 | 798 | typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, 799 | _In_opt_ LPCSTR UserSearchPath, 800 | _In_ BOOL fInvadeProcess); 801 | typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); 802 | typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); 803 | typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, 804 | _In_opt_ HANDLE hFile, 805 | _In_ LPSTR ImageName, 806 | _In_opt_ LPSTR ModuleName, 807 | _In_ DWORD64 BaseOfDll, 808 | _In_opt_ DWORD SizeOfDll); 809 | typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, 810 | _In_ DWORD64 qwAddr, 811 | _Out_ PIMAGEHLP_MODULE64 ModuleInfo); 812 | typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, 813 | _In_ LPSTR Name, 814 | _Out_ PSYMBOL_INFO Symbol); 815 | 816 | typedef struct _DETOUR_SYM_INFO 817 | { 818 | HANDLE hProcess; 819 | HMODULE hDbgHelp; 820 | PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; 821 | PF_SymInitialize pfSymInitialize; 822 | PF_SymSetOptions pfSymSetOptions; 823 | PF_SymGetOptions pfSymGetOptions; 824 | PF_SymLoadModule64 pfSymLoadModule64; 825 | PF_SymGetModuleInfo64 pfSymGetModuleInfo64; 826 | PF_SymFromName pfSymFromName; 827 | } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; 828 | 829 | PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); 830 | 831 | #endif // IMAGEAPI 832 | 833 | #if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) 834 | #error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) 835 | #endif 836 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 837 | 838 | #ifndef DETOUR_TRACE 839 | #if DETOUR_DEBUG 840 | #define DETOUR_TRACE(x) printf x 841 | #define DETOUR_BREAK() __debugbreak() 842 | #include 843 | #include 844 | #else 845 | #define DETOUR_TRACE(x) 846 | #define DETOUR_BREAK() 847 | #endif 848 | #endif 849 | 850 | #if 1 || defined(DETOURS_IA64) 851 | 852 | // 853 | // IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. 854 | // 855 | 856 | #define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) 857 | 858 | #define DETOUR_IA64_TEMPLATE_OFFSET (0) 859 | #define DETOUR_IA64_TEMPLATE_SIZE (5) 860 | 861 | #define DETOUR_IA64_INSTRUCTION_SIZE (41) 862 | #define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) 863 | #define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 864 | #define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 865 | 866 | C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); 867 | 868 | __declspec(align(16)) struct DETOUR_IA64_BUNDLE 869 | { 870 | public: 871 | union 872 | { 873 | BYTE data[16]; 874 | UINT64 wide[2]; 875 | }; 876 | 877 | enum { 878 | A_UNIT = 1u, 879 | I_UNIT = 2u, 880 | M_UNIT = 3u, 881 | B_UNIT = 4u, 882 | F_UNIT = 5u, 883 | L_UNIT = 6u, 884 | X_UNIT = 7u, 885 | }; 886 | struct DETOUR_IA64_METADATA 887 | { 888 | ULONG nTemplate : 8; // Instruction template. 889 | ULONG nUnit0 : 4; // Unit for slot 0 890 | ULONG nUnit1 : 4; // Unit for slot 1 891 | ULONG nUnit2 : 4; // Unit for slot 2 892 | }; 893 | 894 | protected: 895 | static const DETOUR_IA64_METADATA s_rceCopyTable[33]; 896 | 897 | UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 898 | 899 | bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, 900 | _In_ BYTE slot, 901 | _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 902 | 903 | // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 904 | // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. 905 | 906 | // 00 907 | // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. 908 | // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] 909 | // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] 910 | // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] 911 | // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] 912 | // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] 913 | // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] 914 | // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] 915 | BYTE GetTemplate() const; 916 | // Get 4 bit opcodes. 917 | BYTE GetInst0() const; 918 | BYTE GetInst1() const; 919 | BYTE GetInst2() const; 920 | BYTE GetUnit(BYTE slot) const; 921 | BYTE GetUnit0() const; 922 | BYTE GetUnit1() const; 923 | BYTE GetUnit2() const; 924 | // Get 37 bit data. 925 | UINT64 GetData0() const; 926 | UINT64 GetData1() const; 927 | UINT64 GetData2() const; 928 | 929 | // Get/set the full 41 bit instructions. 930 | UINT64 GetInstruction(BYTE slot) const; 931 | UINT64 GetInstruction0() const; 932 | UINT64 GetInstruction1() const; 933 | UINT64 GetInstruction2() const; 934 | void SetInstruction(BYTE slot, UINT64 instruction); 935 | void SetInstruction0(UINT64 instruction); 936 | void SetInstruction1(UINT64 instruction); 937 | void SetInstruction2(UINT64 instruction); 938 | 939 | // Get/set bitfields. 940 | static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); 941 | static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); 942 | 943 | // Get specific read-only fields. 944 | static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode 945 | static UINT64 GetX(UINT64 instruction); // 1bit opcode extension 946 | static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension 947 | static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension 948 | 949 | // Get/set specific fields. 950 | static UINT64 GetImm7a(UINT64 instruction); 951 | static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); 952 | static UINT64 GetImm13c(UINT64 instruction); 953 | static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); 954 | static UINT64 GetSignBit(UINT64 instruction); 955 | static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); 956 | static UINT64 GetImm20a(UINT64 instruction); 957 | static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); 958 | static UINT64 GetImm20b(UINT64 instruction); 959 | static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); 960 | 961 | static UINT64 SignExtend(UINT64 Value, UINT64 Offset); 962 | 963 | BOOL IsMovlGp() const; 964 | 965 | VOID SetInst(BYTE Slot, BYTE nInst); 966 | VOID SetInst0(BYTE nInst); 967 | VOID SetInst1(BYTE nInst); 968 | VOID SetInst2(BYTE nInst); 969 | VOID SetData(BYTE Slot, UINT64 nData); 970 | VOID SetData0(UINT64 nData); 971 | VOID SetData1(UINT64 nData); 972 | VOID SetData2(UINT64 nData); 973 | BOOL SetNop(BYTE Slot); 974 | BOOL SetNop0(); 975 | BOOL SetNop1(); 976 | BOOL SetNop2(); 977 | 978 | public: 979 | BOOL IsBrl() const; 980 | VOID SetBrl(); 981 | VOID SetBrl(UINT64 target); 982 | UINT64 GetBrlTarget() const; 983 | VOID SetBrlTarget(UINT64 target); 984 | VOID SetBrlImm(UINT64 imm); 985 | UINT64 GetBrlImm() const; 986 | 987 | UINT64 GetMovlGp() const; 988 | VOID SetMovlGp(UINT64 gp); 989 | 990 | VOID SetStop(); 991 | 992 | UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; 993 | }; 994 | #endif // DETOURS_IA64 995 | 996 | #ifdef DETOURS_ARM 997 | 998 | #define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) 999 | #define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) 1000 | 1001 | #endif // DETOURS_ARM 1002 | 1003 | ////////////////////////////////////////////////////////////////////////////// 1004 | 1005 | #ifdef __cplusplus 1006 | extern "C" { 1007 | #endif // __cplusplus 1008 | 1009 | #define DETOUR_OFFLINE_LIBRARY(x) \ 1010 | PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ 1011 | _Inout_opt_ PVOID *ppDstPool, \ 1012 | _In_ PVOID pSrc, \ 1013 | _Out_opt_ PVOID *ppTarget, \ 1014 | _Out_opt_ LONG *plExtra); \ 1015 | \ 1016 | BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ 1017 | _In_ BOOL fLimitReferencesToModule); \ 1018 | 1019 | DETOUR_OFFLINE_LIBRARY(X86) 1020 | DETOUR_OFFLINE_LIBRARY(X64) 1021 | DETOUR_OFFLINE_LIBRARY(ARM) 1022 | DETOUR_OFFLINE_LIBRARY(ARM64) 1023 | DETOUR_OFFLINE_LIBRARY(IA64) 1024 | 1025 | #undef DETOUR_OFFLINE_LIBRARY 1026 | 1027 | ////////////////////////////////////////////////////////////////////////////// 1028 | // 1029 | // Helpers for manipulating page protection. 1030 | // 1031 | 1032 | _Success_(return != FALSE) 1033 | BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, 1034 | _In_ PVOID pAddress, 1035 | _In_ SIZE_T nSize, 1036 | _In_ DWORD dwNewProtect, 1037 | _Out_ PDWORD pdwOldProtect); 1038 | 1039 | _Success_(return != FALSE) 1040 | BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, 1041 | _In_ SIZE_T nSize, 1042 | _In_ DWORD dwNewProtect, 1043 | _Out_ PDWORD pdwOldProtect); 1044 | #ifdef __cplusplus 1045 | } 1046 | #endif // __cplusplus 1047 | 1048 | ////////////////////////////////////////////////////////////////////////////// 1049 | 1050 | #define MM_ALLOCATION_GRANULARITY 0x10000 1051 | 1052 | ////////////////////////////////////////////////////////////////////////////// 1053 | 1054 | #endif // DETOURS_INTERNAL 1055 | #endif // __cplusplus 1056 | 1057 | #endif // _DETOURS_H_ 1058 | // 1059 | //////////////////////////////////////////////////////////////// End of File. 1060 | -------------------------------------------------------------------------------- /Detours-4.0.1/include/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 18 | #define DETOURS_STRINGIFY_(x) #x 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /Detours-4.0.1/lib.X64/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nogginware/mstscdump/724ad756c81ed28793213f34d827bd00330db54d/Detours-4.0.1/lib.X64/detours.lib -------------------------------------------------------------------------------- /Detours-4.0.1/lib.X64/detours.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nogginware/mstscdump/724ad756c81ed28793213f34d827bd00330db54d/Detours-4.0.1/lib.X64/detours.pdb -------------------------------------------------------------------------------- /Detours-4.0.1/lib.X86/detours.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nogginware/mstscdump/724ad756c81ed28793213f34d827bd00330db54d/Detours-4.0.1/lib.X86/detours.lib -------------------------------------------------------------------------------- /Detours-4.0.1/lib.X86/detours.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nogginware/mstscdump/724ad756c81ed28793213f34d827bd00330db54d/Detours-4.0.1/lib.X86/detours.pdb -------------------------------------------------------------------------------- /Detours-4.0.1/src/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | ## 3 | ## Makefile for Detours. 4 | ## 5 | ## Microsoft Research Detours Package, Version 4.0.1 6 | ## 7 | ## Copyright (c) Microsoft Corporation. All rights reserved. 8 | ## 9 | 10 | ROOT = .. 11 | !include "$(ROOT)\system.mak" 12 | 13 | !IF "$(DETOURS_SOURCE_BROWSING)" == "" 14 | DETOURS_SOURCE_BROWSING = 0 15 | !ENDIF 16 | 17 | #######################/####################################################### 18 | ## 19 | CFLAGS=/W4 /WX /Zi /MT /Gy /Gm- /Zl /Od 20 | 21 | !IF $(DETOURS_SOURCE_BROWSING)==1 22 | CFLAGS=$(CFLAGS) /FR 23 | !ELSE 24 | CFLAGS=$(CFLAGS) /DWIN32_LEAN_AND_MEAN /D_WIN32_WINNT=0x501 25 | !ENDIF 26 | 27 | !IF "$(DETOURS_TARGET_PROCESSOR)" == "IA64" 28 | CFLAGS=$(CFLAGS) /wd4163 # intrinsic rdtebex not available; using newer Windows headers with older compiler 29 | !ENDIF 30 | 31 | !if defined(DETOURS_WIN_7) && defined(DETOURS_CL_17_OR_NEWER) 32 | CFLAGS=$(CFLAGS) /D_USING_V110_SDK71_ 33 | !elseif defined(DETOURS_ANALYZE) 34 | CFLAGS=$(CFLAGS) /analyze 35 | !endif 36 | 37 | OBJS = \ 38 | $(OBJD)\detours.obj \ 39 | $(OBJD)\modules.obj \ 40 | $(OBJD)\disasm.obj \ 41 | $(OBJD)\image.obj \ 42 | $(OBJD)\creatwth.obj \ 43 | $(OBJD)\disolx86.obj \ 44 | $(OBJD)\disolx64.obj \ 45 | $(OBJD)\disolia64.obj \ 46 | $(OBJD)\disolarm.obj \ 47 | $(OBJD)\disolarm64.obj \ 48 | 49 | ############################################################################## 50 | ## 51 | .SUFFIXES: .cpp .h .obj 52 | 53 | !ifdef DETOURS_ANALYZE 54 | .cpp{$(OBJD)}.obj: 55 | $(CC) $(CFLAGS) /Fd$(LIBD)\detours.pdb /Fo$(OBJD)\ /c $< 56 | !else 57 | .cpp{$(OBJD)}.obj:: 58 | $(CC) $(CFLAGS) /Fd$(LIBD)\detours.pdb /Fo$(OBJD)\ /c $< 59 | !endif 60 | 61 | ############################################################################## 62 | 63 | all: dirs \ 64 | $(LIBD)\detours.lib \ 65 | $(INCD)\detours.h \ 66 | $(INCD)\detver.h \ 67 | !IF $(DETOURS_SOURCE_BROWSING)==1 68 | $(OBJD)\detours.bsc \ 69 | !endif 70 | 71 | ############################################################################## 72 | 73 | clean: 74 | -del *~ 2>nul 75 | -del $(LIBD)\detours.pdb $(LIBD)\detours.lib 2>nul 76 | -rmdir /q /s $(OBJD) 2>nul 77 | 78 | realclean: clean 79 | -rmdir /q /s $(OBJDS) 2>nul 80 | 81 | ############################################################################## 82 | 83 | dirs: 84 | @if not exist "$(INCD)" mkdir "$(INCD)" && echo. Created $(INCD) 85 | @if not exist "$(LIBD)" mkdir "$(LIBD)" && echo. Created $(LIBD) 86 | @if not exist "$(BIND)" mkdir "$(BIND)" && echo. Created $(BIND) 87 | @if not exist "$(OBJD)" mkdir "$(OBJD)" && echo. Created $(OBJD) 88 | 89 | $(OBJD)\detours.bsc : $(OBJS) 90 | bscmake /v /n /o $@ $(OBJS:.obj=.sbr) 91 | 92 | $(LIBD)\detours.lib : $(OBJS) 93 | link /lib /out:$@ $(OBJS) 94 | 95 | $(INCD)\detours.h : detours.h 96 | copy detours.h $@ 97 | 98 | $(INCD)\detver.h : detver.h 99 | copy detver.h $@ 100 | 101 | $(OBJD)\detours.obj : detours.cpp detours.h 102 | $(OBJD)\modules.obj : modules.cpp detours.h 103 | $(OBJD)\disasm.obj : disasm.cpp detours.h 104 | $(OBJD)\image.obj : image.cpp detours.h 105 | $(OBJD)\creatwth.obj : creatwth.cpp uimports.cpp detours.h 106 | $(OBJD)\disolx86.obj: disasm.cpp detours.h 107 | $(OBJD)\disolx64.obj: disasm.cpp detours.h 108 | $(OBJD)\disolia64.obj: disasm.cpp detours.h 109 | $(OBJD)\disolarm.obj: disasm.cpp detours.h 110 | $(OBJD)\disolarm64.obj: disasm.cpp detours.h 111 | 112 | test: all 113 | cd $(MAKEDIR)\..\samples\slept 114 | nmake /nologo test 115 | cd $(MAKEDIR) 116 | 117 | ################################################################# End of File. 118 | -------------------------------------------------------------------------------- /Detours-4.0.1/src/detours.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Core Detours Functionality (detours.h of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #pragma once 11 | #ifndef _DETOURS_H_ 12 | #define _DETOURS_H_ 13 | 14 | #define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH 15 | 16 | ////////////////////////////////////////////////////////////////////////////// 17 | // 18 | 19 | #undef DETOURS_X64 20 | #undef DETOURS_X86 21 | #undef DETOURS_IA64 22 | #undef DETOURS_ARM 23 | #undef DETOURS_ARM64 24 | #undef DETOURS_BITS 25 | #undef DETOURS_32BIT 26 | #undef DETOURS_64BIT 27 | 28 | #if defined(_X86_) 29 | #define DETOURS_X86 30 | #define DETOURS_OPTION_BITS 64 31 | 32 | #elif defined(_AMD64_) 33 | #define DETOURS_X64 34 | #define DETOURS_OPTION_BITS 32 35 | 36 | #elif defined(_IA64_) 37 | #define DETOURS_IA64 38 | #define DETOURS_OPTION_BITS 32 39 | 40 | #elif defined(_ARM_) 41 | #define DETOURS_ARM 42 | 43 | #elif defined(_ARM64_) 44 | #define DETOURS_ARM64 45 | 46 | #else 47 | #error Unknown architecture (x86, amd64, ia64, arm, arm64) 48 | #endif 49 | 50 | #ifdef _WIN64 51 | #undef DETOURS_32BIT 52 | #define DETOURS_64BIT 1 53 | #define DETOURS_BITS 64 54 | // If all 64bit kernels can run one and only one 32bit architecture. 55 | //#define DETOURS_OPTION_BITS 32 56 | #else 57 | #define DETOURS_32BIT 1 58 | #undef DETOURS_64BIT 59 | #define DETOURS_BITS 32 60 | // If all 64bit kernels can run one and only one 32bit architecture. 61 | //#define DETOURS_OPTION_BITS 32 62 | #endif 63 | 64 | #define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS) 65 | 66 | ////////////////////////////////////////////////////////////////////////////// 67 | // 68 | 69 | #if (_MSC_VER < 1299) 70 | typedef LONG LONG_PTR; 71 | typedef ULONG ULONG_PTR; 72 | #endif 73 | 74 | ///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL. 75 | // 76 | // These definitions are include so that Detours will build even if the 77 | // compiler doesn't have full SAL 2.0 support. 78 | // 79 | #ifndef DETOURS_DONT_REMOVE_SAL_20 80 | 81 | #ifdef DETOURS_TEST_REMOVE_SAL_20 82 | #undef _Analysis_assume_ 83 | #undef _Benign_race_begin_ 84 | #undef _Benign_race_end_ 85 | #undef _Field_range_ 86 | #undef _Field_size_ 87 | #undef _In_ 88 | #undef _In_bytecount_ 89 | #undef _In_count_ 90 | #undef _In_opt_ 91 | #undef _In_opt_bytecount_ 92 | #undef _In_opt_count_ 93 | #undef _In_opt_z_ 94 | #undef _In_range_ 95 | #undef _In_reads_ 96 | #undef _In_reads_bytes_ 97 | #undef _In_reads_opt_ 98 | #undef _In_reads_opt_bytes_ 99 | #undef _In_reads_or_z_ 100 | #undef _In_z_ 101 | #undef _Inout_ 102 | #undef _Inout_opt_ 103 | #undef _Inout_z_count_ 104 | #undef _Out_ 105 | #undef _Out_opt_ 106 | #undef _Out_writes_ 107 | #undef _Outptr_result_maybenull_ 108 | #undef _Readable_bytes_ 109 | #undef _Success_ 110 | #undef _Writable_bytes_ 111 | #undef _Pre_notnull_ 112 | #endif 113 | 114 | #if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_) 115 | #define _Outptr_result_maybenull_ _Deref_out_opt_z_ 116 | #endif 117 | 118 | #if defined(_In_count_) && !defined(_In_reads_) 119 | #define _In_reads_(x) _In_count_(x) 120 | #endif 121 | 122 | #if defined(_In_opt_count_) && !defined(_In_reads_opt_) 123 | #define _In_reads_opt_(x) _In_opt_count_(x) 124 | #endif 125 | 126 | #if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_) 127 | #define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x) 128 | #endif 129 | 130 | #if defined(_In_bytecount_) && !defined(_In_reads_bytes_) 131 | #define _In_reads_bytes_(x) _In_bytecount_(x) 132 | #endif 133 | 134 | #ifndef _In_ 135 | #define _In_ 136 | #endif 137 | 138 | #ifndef _In_bytecount_ 139 | #define _In_bytecount_(x) 140 | #endif 141 | 142 | #ifndef _In_count_ 143 | #define _In_count_(x) 144 | #endif 145 | 146 | #ifndef _In_opt_ 147 | #define _In_opt_ 148 | #endif 149 | 150 | #ifndef _In_opt_bytecount_ 151 | #define _In_opt_bytecount_(x) 152 | #endif 153 | 154 | #ifndef _In_opt_count_ 155 | #define _In_opt_count_(x) 156 | #endif 157 | 158 | #ifndef _In_opt_z_ 159 | #define _In_opt_z_ 160 | #endif 161 | 162 | #ifndef _In_range_ 163 | #define _In_range_(x,y) 164 | #endif 165 | 166 | #ifndef _In_reads_ 167 | #define _In_reads_(x) 168 | #endif 169 | 170 | #ifndef _In_reads_bytes_ 171 | #define _In_reads_bytes_(x) 172 | #endif 173 | 174 | #ifndef _In_reads_opt_ 175 | #define _In_reads_opt_(x) 176 | #endif 177 | 178 | #ifndef _In_reads_opt_bytes_ 179 | #define _In_reads_opt_bytes_(x) 180 | #endif 181 | 182 | #ifndef _In_reads_or_z_ 183 | #define _In_reads_or_z_ 184 | #endif 185 | 186 | #ifndef _In_z_ 187 | #define _In_z_ 188 | #endif 189 | 190 | #ifndef _Inout_ 191 | #define _Inout_ 192 | #endif 193 | 194 | #ifndef _Inout_opt_ 195 | #define _Inout_opt_ 196 | #endif 197 | 198 | #ifndef _Inout_z_count_ 199 | #define _Inout_z_count_(x) 200 | #endif 201 | 202 | #ifndef _Out_ 203 | #define _Out_ 204 | #endif 205 | 206 | #ifndef _Out_opt_ 207 | #define _Out_opt_ 208 | #endif 209 | 210 | #ifndef _Out_writes_ 211 | #define _Out_writes_(x) 212 | #endif 213 | 214 | #ifndef _Outptr_result_maybenull_ 215 | #define _Outptr_result_maybenull_ 216 | #endif 217 | 218 | #ifndef _Writable_bytes_ 219 | #define _Writable_bytes_(x) 220 | #endif 221 | 222 | #ifndef _Readable_bytes_ 223 | #define _Readable_bytes_(x) 224 | #endif 225 | 226 | #ifndef _Success_ 227 | #define _Success_(x) 228 | #endif 229 | 230 | #ifndef _Pre_notnull_ 231 | #define _Pre_notnull_ 232 | #endif 233 | 234 | #ifdef DETOURS_INTERNAL 235 | 236 | #pragma warning(disable:4615) // unknown warning type (suppress with older compilers) 237 | 238 | #ifndef _Benign_race_begin_ 239 | #define _Benign_race_begin_ 240 | #endif 241 | 242 | #ifndef _Benign_race_end_ 243 | #define _Benign_race_end_ 244 | #endif 245 | 246 | #ifndef _Field_size_ 247 | #define _Field_size_(x) 248 | #endif 249 | 250 | #ifndef _Field_range_ 251 | #define _Field_range_(x,y) 252 | #endif 253 | 254 | #ifndef _Analysis_assume_ 255 | #define _Analysis_assume_(x) 256 | #endif 257 | 258 | #endif // DETOURS_INTERNAL 259 | #endif // DETOURS_DONT_REMOVE_SAL_20 260 | 261 | ////////////////////////////////////////////////////////////////////////////// 262 | // 263 | #ifndef GUID_DEFINED 264 | #define GUID_DEFINED 265 | typedef struct _GUID 266 | { 267 | DWORD Data1; 268 | WORD Data2; 269 | WORD Data3; 270 | BYTE Data4[ 8 ]; 271 | } GUID; 272 | 273 | #ifdef INITGUID 274 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 275 | const GUID name \ 276 | = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } 277 | #else 278 | #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ 279 | const GUID name 280 | #endif // INITGUID 281 | #endif // !GUID_DEFINED 282 | 283 | #if defined(__cplusplus) 284 | #ifndef _REFGUID_DEFINED 285 | #define _REFGUID_DEFINED 286 | #define REFGUID const GUID & 287 | #endif // !_REFGUID_DEFINED 288 | #else // !__cplusplus 289 | #ifndef _REFGUID_DEFINED 290 | #define _REFGUID_DEFINED 291 | #define REFGUID const GUID * const 292 | #endif // !_REFGUID_DEFINED 293 | #endif // !__cplusplus 294 | 295 | #ifndef ARRAYSIZE 296 | #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) 297 | #endif 298 | 299 | // 300 | ////////////////////////////////////////////////////////////////////////////// 301 | 302 | #ifdef __cplusplus 303 | extern "C" { 304 | #endif // __cplusplus 305 | 306 | /////////////////////////////////////////////////// Instruction Target Macros. 307 | // 308 | #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) 309 | #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) 310 | #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" 311 | 312 | extern const GUID DETOUR_EXE_RESTORE_GUID; 313 | extern const GUID DETOUR_EXE_HELPER_GUID; 314 | 315 | #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! 316 | typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; 317 | 318 | /////////////////////////////////////////////////////////// Binary Structures. 319 | // 320 | #pragma pack(push, 8) 321 | typedef struct _DETOUR_SECTION_HEADER 322 | { 323 | DWORD cbHeaderSize; 324 | DWORD nSignature; 325 | DWORD nDataOffset; 326 | DWORD cbDataSize; 327 | 328 | DWORD nOriginalImportVirtualAddress; 329 | DWORD nOriginalImportSize; 330 | DWORD nOriginalBoundImportVirtualAddress; 331 | DWORD nOriginalBoundImportSize; 332 | 333 | DWORD nOriginalIatVirtualAddress; 334 | DWORD nOriginalIatSize; 335 | DWORD nOriginalSizeOfImage; 336 | DWORD cbPrePE; 337 | 338 | DWORD nOriginalClrFlags; 339 | DWORD reserved1; 340 | DWORD reserved2; 341 | DWORD reserved3; 342 | 343 | // Followed by cbPrePE bytes of data. 344 | } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; 345 | 346 | typedef struct _DETOUR_SECTION_RECORD 347 | { 348 | DWORD cbBytes; 349 | DWORD nReserved; 350 | GUID guid; 351 | } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; 352 | 353 | typedef struct _DETOUR_CLR_HEADER 354 | { 355 | // Header versioning 356 | ULONG cb; 357 | USHORT MajorRuntimeVersion; 358 | USHORT MinorRuntimeVersion; 359 | 360 | // Symbol table and startup information 361 | IMAGE_DATA_DIRECTORY MetaData; 362 | ULONG Flags; 363 | 364 | // Followed by the rest of the IMAGE_COR20_HEADER 365 | } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; 366 | 367 | typedef struct _DETOUR_EXE_RESTORE 368 | { 369 | DWORD cb; 370 | DWORD cbidh; 371 | DWORD cbinh; 372 | DWORD cbclr; 373 | 374 | PBYTE pidh; 375 | PBYTE pinh; 376 | PBYTE pclr; 377 | 378 | IMAGE_DOS_HEADER idh; 379 | union { 380 | IMAGE_NT_HEADERS inh; 381 | IMAGE_NT_HEADERS32 inh32; 382 | IMAGE_NT_HEADERS64 inh64; 383 | BYTE raw[sizeof(IMAGE_NT_HEADERS64) + 384 | sizeof(IMAGE_SECTION_HEADER) * 32]; 385 | }; 386 | DETOUR_CLR_HEADER clr; 387 | 388 | } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; 389 | 390 | typedef struct _DETOUR_EXE_HELPER 391 | { 392 | DWORD cb; 393 | DWORD pid; 394 | DWORD nDlls; 395 | CHAR rDlls[4]; 396 | } DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER; 397 | 398 | #pragma pack(pop) 399 | 400 | #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ 401 | { \ 402 | sizeof(DETOUR_SECTION_HEADER),\ 403 | DETOUR_SECTION_HEADER_SIGNATURE,\ 404 | sizeof(DETOUR_SECTION_HEADER),\ 405 | (cbSectionSize),\ 406 | \ 407 | 0,\ 408 | 0,\ 409 | 0,\ 410 | 0,\ 411 | \ 412 | 0,\ 413 | 0,\ 414 | 0,\ 415 | 0,\ 416 | } 417 | 418 | /////////////////////////////////////////////////////////////// Helper Macros. 419 | // 420 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 421 | #define DETOURS_STRINGIFY_(x) #x 422 | 423 | ///////////////////////////////////////////////////////////// Binary Typedefs. 424 | // 425 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)( 426 | _In_opt_ PVOID pContext, 427 | _In_opt_ LPCSTR pszFile, 428 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 429 | 430 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)( 431 | _In_opt_ PVOID pContext, 432 | _In_ LPCSTR pszOrigFile, 433 | _In_ LPCSTR pszFile, 434 | _Outptr_result_maybenull_ LPCSTR *ppszOutFile); 435 | 436 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)( 437 | _In_opt_ PVOID pContext, 438 | _In_ ULONG nOrigOrdinal, 439 | _In_ ULONG nOrdinal, 440 | _Out_ ULONG *pnOutOrdinal, 441 | _In_opt_ LPCSTR pszOrigSymbol, 442 | _In_opt_ LPCSTR pszSymbol, 443 | _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol); 444 | 445 | typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)( 446 | _In_opt_ PVOID pContext); 447 | 448 | typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext, 449 | _In_ ULONG nOrdinal, 450 | _In_opt_ LPCSTR pszName, 451 | _In_opt_ PVOID pCode); 452 | 453 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext, 454 | _In_opt_ HMODULE hModule, 455 | _In_opt_ LPCSTR pszFile); 456 | 457 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext, 458 | _In_ DWORD nOrdinal, 459 | _In_opt_ LPCSTR pszFunc, 460 | _In_opt_ PVOID pvFunc); 461 | 462 | // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter. 463 | typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext, 464 | _In_ DWORD nOrdinal, 465 | _In_opt_ LPCSTR pszFunc, 466 | _In_opt_ PVOID* ppvFunc); 467 | 468 | typedef VOID * PDETOUR_BINARY; 469 | typedef VOID * PDETOUR_LOADED_BINARY; 470 | 471 | //////////////////////////////////////////////////////////// Transaction APIs. 472 | // 473 | LONG WINAPI DetourTransactionBegin(VOID); 474 | LONG WINAPI DetourTransactionAbort(VOID); 475 | LONG WINAPI DetourTransactionCommit(VOID); 476 | LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer); 477 | 478 | LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread); 479 | 480 | LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer, 481 | _In_ PVOID pDetour); 482 | 483 | LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer, 484 | _In_ PVOID pDetour, 485 | _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline, 486 | _Out_opt_ PVOID *ppRealTarget, 487 | _Out_opt_ PVOID *ppRealDetour); 488 | 489 | LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer, 490 | _In_ PVOID pDetour); 491 | 492 | BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore); 493 | BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain); 494 | PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound); 495 | PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound); 496 | 497 | ////////////////////////////////////////////////////////////// Code Functions. 498 | // 499 | PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule, 500 | _In_ LPCSTR pszFunction); 501 | PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer, 502 | _Out_opt_ PVOID *ppGlobals); 503 | PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst, 504 | _Inout_opt_ PVOID *ppDstPool, 505 | _In_ PVOID pSrc, 506 | _Out_opt_ PVOID *ppTarget, 507 | _Out_opt_ LONG *plExtra); 508 | BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule, 509 | _In_ BOOL fLimitReferencesToModule); 510 | 511 | ///////////////////////////////////////////////////// Loaded Binary Functions. 512 | // 513 | HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr); 514 | HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast); 515 | PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule); 516 | ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule); 517 | BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, 518 | _In_opt_ PVOID pContext, 519 | _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); 520 | BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, 521 | _In_opt_ PVOID pContext, 522 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 523 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc); 524 | 525 | BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, 526 | _In_opt_ PVOID pContext, 527 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 528 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx); 529 | 530 | _Writable_bytes_(*pcbData) 531 | _Readable_bytes_(*pcbData) 532 | _Success_(return != NULL) 533 | PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, 534 | _In_ REFGUID rguid, 535 | _Out_ DWORD *pcbData); 536 | 537 | _Writable_bytes_(*pcbData) 538 | _Readable_bytes_(*pcbData) 539 | _Success_(return != NULL) 540 | PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, 541 | _Out_ DWORD * pcbData); 542 | 543 | DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule); 544 | 545 | ///////////////////////////////////////////////// Persistent Binary Functions. 546 | // 547 | 548 | PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile); 549 | 550 | _Writable_bytes_(*pcbData) 551 | _Readable_bytes_(*pcbData) 552 | _Success_(return != NULL) 553 | PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary, 554 | _Out_opt_ GUID *pGuid, 555 | _Out_ DWORD *pcbData, 556 | _Inout_ DWORD *pnIterator); 557 | 558 | _Writable_bytes_(*pcbData) 559 | _Readable_bytes_(*pcbData) 560 | _Success_(return != NULL) 561 | PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary, 562 | _In_ REFGUID rguid, 563 | _Out_ DWORD *pcbData); 564 | 565 | PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary, 566 | _In_ REFGUID rguid, 567 | _In_reads_opt_(cbData) PVOID pData, 568 | _In_ DWORD cbData); 569 | BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid); 570 | BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary); 571 | BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary); 572 | BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary, 573 | _In_opt_ PVOID pContext, 574 | _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, 575 | _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile, 576 | _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, 577 | _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); 578 | BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile); 579 | BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary); 580 | 581 | /////////////////////////////////////////////////// Create Process & Load Dll. 582 | // 583 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)( 584 | _In_opt_ LPCSTR lpApplicationName, 585 | _Inout_opt_ LPSTR lpCommandLine, 586 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 587 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 588 | _In_ BOOL bInheritHandles, 589 | _In_ DWORD dwCreationFlags, 590 | _In_opt_ LPVOID lpEnvironment, 591 | _In_opt_ LPCSTR lpCurrentDirectory, 592 | _In_ LPSTARTUPINFOA lpStartupInfo, 593 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 594 | 595 | typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)( 596 | _In_opt_ LPCWSTR lpApplicationName, 597 | _Inout_opt_ LPWSTR lpCommandLine, 598 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 599 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 600 | _In_ BOOL bInheritHandles, 601 | _In_ DWORD dwCreationFlags, 602 | _In_opt_ LPVOID lpEnvironment, 603 | _In_opt_ LPCWSTR lpCurrentDirectory, 604 | _In_ LPSTARTUPINFOW lpStartupInfo, 605 | _Out_ LPPROCESS_INFORMATION lpProcessInformation); 606 | 607 | BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName, 608 | _Inout_opt_ LPSTR lpCommandLine, 609 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 610 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 611 | _In_ BOOL bInheritHandles, 612 | _In_ DWORD dwCreationFlags, 613 | _In_opt_ LPVOID lpEnvironment, 614 | _In_opt_ LPCSTR lpCurrentDirectory, 615 | _In_ LPSTARTUPINFOA lpStartupInfo, 616 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 617 | _In_ LPCSTR lpDllName, 618 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 619 | 620 | BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName, 621 | _Inout_opt_ LPWSTR lpCommandLine, 622 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 623 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 624 | _In_ BOOL bInheritHandles, 625 | _In_ DWORD dwCreationFlags, 626 | _In_opt_ LPVOID lpEnvironment, 627 | _In_opt_ LPCWSTR lpCurrentDirectory, 628 | _In_ LPSTARTUPINFOW lpStartupInfo, 629 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 630 | _In_ LPCSTR lpDllName, 631 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 632 | 633 | #ifdef UNICODE 634 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllW 635 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW 636 | #else 637 | #define DetourCreateProcessWithDll DetourCreateProcessWithDllA 638 | #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA 639 | #endif // !UNICODE 640 | 641 | BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName, 642 | _Inout_opt_ LPSTR lpCommandLine, 643 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 644 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 645 | _In_ BOOL bInheritHandles, 646 | _In_ DWORD dwCreationFlags, 647 | _In_opt_ LPVOID lpEnvironment, 648 | _In_opt_ LPCSTR lpCurrentDirectory, 649 | _In_ LPSTARTUPINFOA lpStartupInfo, 650 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 651 | _In_ LPCSTR lpDllName, 652 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 653 | 654 | BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName, 655 | _Inout_opt_ LPWSTR lpCommandLine, 656 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 657 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 658 | _In_ BOOL bInheritHandles, 659 | _In_ DWORD dwCreationFlags, 660 | _In_opt_ LPVOID lpEnvironment, 661 | _In_opt_ LPCWSTR lpCurrentDirectory, 662 | _In_ LPSTARTUPINFOW lpStartupInfo, 663 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 664 | _In_ LPCSTR lpDllName, 665 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 666 | 667 | #ifdef UNICODE 668 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW 669 | #else 670 | #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA 671 | #endif // !UNICODE 672 | 673 | BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName, 674 | _Inout_opt_ LPSTR lpCommandLine, 675 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 676 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 677 | _In_ BOOL bInheritHandles, 678 | _In_ DWORD dwCreationFlags, 679 | _In_opt_ LPVOID lpEnvironment, 680 | _In_opt_ LPCSTR lpCurrentDirectory, 681 | _In_ LPSTARTUPINFOA lpStartupInfo, 682 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 683 | _In_ DWORD nDlls, 684 | _In_reads_(nDlls) LPCSTR *rlpDlls, 685 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 686 | 687 | BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName, 688 | _Inout_opt_ LPWSTR lpCommandLine, 689 | _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, 690 | _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, 691 | _In_ BOOL bInheritHandles, 692 | _In_ DWORD dwCreationFlags, 693 | _In_opt_ LPVOID lpEnvironment, 694 | _In_opt_ LPCWSTR lpCurrentDirectory, 695 | _In_ LPSTARTUPINFOW lpStartupInfo, 696 | _Out_ LPPROCESS_INFORMATION lpProcessInformation, 697 | _In_ DWORD nDlls, 698 | _In_reads_(nDlls) LPCSTR *rlpDlls, 699 | _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 700 | 701 | #ifdef UNICODE 702 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW 703 | #else 704 | #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA 705 | #endif // !UNICODE 706 | 707 | BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid, 708 | _In_ LPCSTR lpDllName, 709 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 710 | 711 | BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid, 712 | _In_ LPCSTR lpDllName, 713 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 714 | 715 | #ifdef UNICODE 716 | #define DetourProcessViaHelper DetourProcessViaHelperW 717 | #else 718 | #define DetourProcessViaHelper DetourProcessViaHelperA 719 | #endif // !UNICODE 720 | 721 | BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid, 722 | _In_ DWORD nDlls, 723 | _In_reads_(nDlls) LPCSTR *rlpDlls, 724 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); 725 | 726 | BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid, 727 | _In_ DWORD nDlls, 728 | _In_reads_(nDlls) LPCSTR *rlpDlls, 729 | _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 730 | 731 | #ifdef UNICODE 732 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW 733 | #else 734 | #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA 735 | #endif // !UNICODE 736 | 737 | BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, 738 | _In_reads_(nDlls) LPCSTR *rlpDlls, 739 | _In_ DWORD nDlls); 740 | 741 | BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, 742 | _In_ HMODULE hImage, 743 | _In_ BOOL bIs32Bit, 744 | _In_reads_(nDlls) LPCSTR *rlpDlls, 745 | _In_ DWORD nDlls); 746 | 747 | BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess, 748 | _In_ REFGUID rguid, 749 | _In_reads_bytes_(cbData) PVOID pvData, 750 | _In_ DWORD cbData); 751 | BOOL WINAPI DetourRestoreAfterWith(VOID); 752 | BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 753 | _In_ DWORD cbData); 754 | BOOL WINAPI DetourIsHelperProcess(VOID); 755 | VOID CALLBACK DetourFinishHelperProcess(_In_ HWND, 756 | _In_ HINSTANCE, 757 | _In_ LPSTR, 758 | _In_ INT); 759 | 760 | // 761 | ////////////////////////////////////////////////////////////////////////////// 762 | #ifdef __cplusplus 763 | } 764 | #endif // __cplusplus 765 | 766 | //////////////////////////////////////////////// Detours Internal Definitions. 767 | // 768 | #ifdef __cplusplus 769 | #ifdef DETOURS_INTERNAL 770 | 771 | #define NOTHROW 772 | // #define NOTHROW (nothrow) 773 | 774 | ////////////////////////////////////////////////////////////////////////////// 775 | // 776 | #if (_MSC_VER < 1299) 777 | #include 778 | typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; 779 | typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; 780 | typedef IMAGEHLP_SYMBOL SYMBOL_INFO; 781 | typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; 782 | 783 | static inline 784 | LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval) 785 | { 786 | return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); 787 | } 788 | #else 789 | #pragma warning(push) 790 | #pragma warning(disable:4091) // empty typedef 791 | #include 792 | #pragma warning(pop) 793 | #endif 794 | 795 | #ifdef IMAGEAPI // defined by DBGHELP.H 796 | typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion); 797 | 798 | typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess, 799 | _In_opt_ LPCSTR UserSearchPath, 800 | _In_ BOOL fInvadeProcess); 801 | typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions); 802 | typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); 803 | typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess, 804 | _In_opt_ HANDLE hFile, 805 | _In_ LPSTR ImageName, 806 | _In_opt_ LPSTR ModuleName, 807 | _In_ DWORD64 BaseOfDll, 808 | _In_opt_ DWORD SizeOfDll); 809 | typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess, 810 | _In_ DWORD64 qwAddr, 811 | _Out_ PIMAGEHLP_MODULE64 ModuleInfo); 812 | typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess, 813 | _In_ LPSTR Name, 814 | _Out_ PSYMBOL_INFO Symbol); 815 | 816 | typedef struct _DETOUR_SYM_INFO 817 | { 818 | HANDLE hProcess; 819 | HMODULE hDbgHelp; 820 | PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; 821 | PF_SymInitialize pfSymInitialize; 822 | PF_SymSetOptions pfSymSetOptions; 823 | PF_SymGetOptions pfSymGetOptions; 824 | PF_SymLoadModule64 pfSymLoadModule64; 825 | PF_SymGetModuleInfo64 pfSymGetModuleInfo64; 826 | PF_SymFromName pfSymFromName; 827 | } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; 828 | 829 | PDETOUR_SYM_INFO DetourLoadImageHlp(VOID); 830 | 831 | #endif // IMAGEAPI 832 | 833 | #if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS) 834 | #error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier) 835 | #endif 836 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 837 | 838 | #ifndef DETOUR_TRACE 839 | #if DETOUR_DEBUG 840 | #define DETOUR_TRACE(x) printf x 841 | #define DETOUR_BREAK() __debugbreak() 842 | #include 843 | #include 844 | #else 845 | #define DETOUR_TRACE(x) 846 | #define DETOUR_BREAK() 847 | #endif 848 | #endif 849 | 850 | #if 1 || defined(DETOURS_IA64) 851 | 852 | // 853 | // IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle. 854 | // 855 | 856 | #define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3) 857 | 858 | #define DETOUR_IA64_TEMPLATE_OFFSET (0) 859 | #define DETOUR_IA64_TEMPLATE_SIZE (5) 860 | 861 | #define DETOUR_IA64_INSTRUCTION_SIZE (41) 862 | #define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE) 863 | #define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 864 | #define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE) 865 | 866 | C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128); 867 | 868 | __declspec(align(16)) struct DETOUR_IA64_BUNDLE 869 | { 870 | public: 871 | union 872 | { 873 | BYTE data[16]; 874 | UINT64 wide[2]; 875 | }; 876 | 877 | enum { 878 | A_UNIT = 1u, 879 | I_UNIT = 2u, 880 | M_UNIT = 3u, 881 | B_UNIT = 4u, 882 | F_UNIT = 5u, 883 | L_UNIT = 6u, 884 | X_UNIT = 7u, 885 | }; 886 | struct DETOUR_IA64_METADATA 887 | { 888 | ULONG nTemplate : 8; // Instruction template. 889 | ULONG nUnit0 : 4; // Unit for slot 0 890 | ULONG nUnit1 : 4; // Unit for slot 1 891 | ULONG nUnit2 : 4; // Unit for slot 2 892 | }; 893 | 894 | protected: 895 | static const DETOUR_IA64_METADATA s_rceCopyTable[33]; 896 | 897 | UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 898 | 899 | bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst, 900 | _In_ BYTE slot, 901 | _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const; 902 | 903 | // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 904 | // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. 905 | 906 | // 00 907 | // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. 908 | // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] 909 | // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] 910 | // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] 911 | // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] 912 | // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] 913 | // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] 914 | // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] 915 | BYTE GetTemplate() const; 916 | // Get 4 bit opcodes. 917 | BYTE GetInst0() const; 918 | BYTE GetInst1() const; 919 | BYTE GetInst2() const; 920 | BYTE GetUnit(BYTE slot) const; 921 | BYTE GetUnit0() const; 922 | BYTE GetUnit1() const; 923 | BYTE GetUnit2() const; 924 | // Get 37 bit data. 925 | UINT64 GetData0() const; 926 | UINT64 GetData1() const; 927 | UINT64 GetData2() const; 928 | 929 | // Get/set the full 41 bit instructions. 930 | UINT64 GetInstruction(BYTE slot) const; 931 | UINT64 GetInstruction0() const; 932 | UINT64 GetInstruction1() const; 933 | UINT64 GetInstruction2() const; 934 | void SetInstruction(BYTE slot, UINT64 instruction); 935 | void SetInstruction0(UINT64 instruction); 936 | void SetInstruction1(UINT64 instruction); 937 | void SetInstruction2(UINT64 instruction); 938 | 939 | // Get/set bitfields. 940 | static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count); 941 | static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field); 942 | 943 | // Get specific read-only fields. 944 | static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode 945 | static UINT64 GetX(UINT64 instruction); // 1bit opcode extension 946 | static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension 947 | static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension 948 | 949 | // Get/set specific fields. 950 | static UINT64 GetImm7a(UINT64 instruction); 951 | static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a); 952 | static UINT64 GetImm13c(UINT64 instruction); 953 | static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c); 954 | static UINT64 GetSignBit(UINT64 instruction); 955 | static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit); 956 | static UINT64 GetImm20a(UINT64 instruction); 957 | static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a); 958 | static UINT64 GetImm20b(UINT64 instruction); 959 | static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b); 960 | 961 | static UINT64 SignExtend(UINT64 Value, UINT64 Offset); 962 | 963 | BOOL IsMovlGp() const; 964 | 965 | VOID SetInst(BYTE Slot, BYTE nInst); 966 | VOID SetInst0(BYTE nInst); 967 | VOID SetInst1(BYTE nInst); 968 | VOID SetInst2(BYTE nInst); 969 | VOID SetData(BYTE Slot, UINT64 nData); 970 | VOID SetData0(UINT64 nData); 971 | VOID SetData1(UINT64 nData); 972 | VOID SetData2(UINT64 nData); 973 | BOOL SetNop(BYTE Slot); 974 | BOOL SetNop0(); 975 | BOOL SetNop1(); 976 | BOOL SetNop2(); 977 | 978 | public: 979 | BOOL IsBrl() const; 980 | VOID SetBrl(); 981 | VOID SetBrl(UINT64 target); 982 | UINT64 GetBrlTarget() const; 983 | VOID SetBrlTarget(UINT64 target); 984 | VOID SetBrlImm(UINT64 imm); 985 | UINT64 GetBrlImm() const; 986 | 987 | UINT64 GetMovlGp() const; 988 | VOID SetMovlGp(UINT64 gp); 989 | 990 | VOID SetStop(); 991 | 992 | UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const; 993 | }; 994 | #endif // DETOURS_IA64 995 | 996 | #ifdef DETOURS_ARM 997 | 998 | #define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1)) 999 | #define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1)) 1000 | 1001 | #endif // DETOURS_ARM 1002 | 1003 | ////////////////////////////////////////////////////////////////////////////// 1004 | 1005 | #ifdef __cplusplus 1006 | extern "C" { 1007 | #endif // __cplusplus 1008 | 1009 | #define DETOUR_OFFLINE_LIBRARY(x) \ 1010 | PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \ 1011 | _Inout_opt_ PVOID *ppDstPool, \ 1012 | _In_ PVOID pSrc, \ 1013 | _Out_opt_ PVOID *ppTarget, \ 1014 | _Out_opt_ LONG *plExtra); \ 1015 | \ 1016 | BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \ 1017 | _In_ BOOL fLimitReferencesToModule); \ 1018 | 1019 | DETOUR_OFFLINE_LIBRARY(X86) 1020 | DETOUR_OFFLINE_LIBRARY(X64) 1021 | DETOUR_OFFLINE_LIBRARY(ARM) 1022 | DETOUR_OFFLINE_LIBRARY(ARM64) 1023 | DETOUR_OFFLINE_LIBRARY(IA64) 1024 | 1025 | #undef DETOUR_OFFLINE_LIBRARY 1026 | 1027 | ////////////////////////////////////////////////////////////////////////////// 1028 | // 1029 | // Helpers for manipulating page protection. 1030 | // 1031 | 1032 | _Success_(return != FALSE) 1033 | BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess, 1034 | _In_ PVOID pAddress, 1035 | _In_ SIZE_T nSize, 1036 | _In_ DWORD dwNewProtect, 1037 | _Out_ PDWORD pdwOldProtect); 1038 | 1039 | _Success_(return != FALSE) 1040 | BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress, 1041 | _In_ SIZE_T nSize, 1042 | _In_ DWORD dwNewProtect, 1043 | _Out_ PDWORD pdwOldProtect); 1044 | #ifdef __cplusplus 1045 | } 1046 | #endif // __cplusplus 1047 | 1048 | ////////////////////////////////////////////////////////////////////////////// 1049 | 1050 | #define MM_ALLOCATION_GRANULARITY 0x10000 1051 | 1052 | ////////////////////////////////////////////////////////////////////////////// 1053 | 1054 | #endif // DETOURS_INTERNAL 1055 | #endif // __cplusplus 1056 | 1057 | #endif // _DETOURS_H_ 1058 | // 1059 | //////////////////////////////////////////////////////////////// End of File. 1060 | -------------------------------------------------------------------------------- /Detours-4.0.1/src/detver.h: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Common version parameters. 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | 10 | #define _USING_V110_SDK71_ 1 11 | #include "winver.h" 12 | #if 0 13 | #include 14 | #include 15 | #else 16 | #ifndef DETOURS_STRINGIFY 17 | #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x) 18 | #define DETOURS_STRINGIFY_(x) #x 19 | #endif 20 | 21 | #define VER_FILEFLAGSMASK 0x3fL 22 | #define VER_FILEFLAGS 0x0L 23 | #define VER_FILEOS 0x00040004L 24 | #define VER_FILETYPE 0x00000002L 25 | #define VER_FILESUBTYPE 0x00000000L 26 | #endif 27 | #define VER_DETOURS_BITS DETOUR_STRINGIFY(DETOURS_BITS) 28 | -------------------------------------------------------------------------------- /Detours-4.0.1/src/disolarm.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_ARM_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /Detours-4.0.1/src/disolarm64.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_ARM64_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /Detours-4.0.1/src/disolia64.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_IA64_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /Detours-4.0.1/src/disolx64.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_X64_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /Detours-4.0.1/src/disolx86.cpp: -------------------------------------------------------------------------------- 1 | #define DETOURS_X86_OFFLINE_LIBRARY 2 | #include "disasm.cpp" 3 | -------------------------------------------------------------------------------- /Detours-4.0.1/src/modules.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Module Enumeration Functions (modules.cpp of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | // Module enumeration functions. 10 | // 11 | 12 | #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1 13 | 14 | #pragma warning(disable:4068) // unknown pragma (suppress) 15 | 16 | #if _MSC_VER >= 1900 17 | #pragma warning(push) 18 | #pragma warning(disable:4091) // empty typedef 19 | #endif 20 | 21 | #define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1 22 | #include 23 | #if (_MSC_VER < 1310) 24 | #else 25 | #pragma warning(push) 26 | #if _MSC_VER > 1400 27 | #pragma warning(disable:6102 6103) // /analyze warnings 28 | #endif 29 | #include 30 | #pragma warning(pop) 31 | #endif 32 | 33 | // #define DETOUR_DEBUG 1 34 | #define DETOURS_INTERNAL 35 | #include "detours.h" 36 | 37 | #if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH 38 | #error detours.h version mismatch 39 | #endif 40 | 41 | #if _MSC_VER >= 1900 42 | #pragma warning(pop) 43 | #endif 44 | 45 | #define CLR_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR] 46 | #define IAT_DIRECTORY OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT] 47 | 48 | ////////////////////////////////////////////////////////////////////////////// 49 | // 50 | const GUID DETOUR_EXE_RESTORE_GUID = { 51 | 0x2ed7a3ff, 0x3339, 0x4a8d, 52 | { 0x80, 0x5c, 0xd4, 0x98, 0x15, 0x3f, 0xc2, 0x8f }}; 53 | 54 | ////////////////////////////////////////////////////////////////////////////// 55 | // 56 | PDETOUR_SYM_INFO DetourLoadImageHlp(VOID) 57 | { 58 | static DETOUR_SYM_INFO symInfo; 59 | static PDETOUR_SYM_INFO pSymInfo = NULL; 60 | static BOOL failed = false; 61 | 62 | if (failed) { 63 | return NULL; 64 | } 65 | if (pSymInfo != NULL) { 66 | return pSymInfo; 67 | } 68 | 69 | ZeroMemory(&symInfo, sizeof(symInfo)); 70 | // Create a real handle to the process. 71 | #if 0 72 | DuplicateHandle(GetCurrentProcess(), 73 | GetCurrentProcess(), 74 | GetCurrentProcess(), 75 | &symInfo.hProcess, 76 | 0, 77 | FALSE, 78 | DUPLICATE_SAME_ACCESS); 79 | #else 80 | symInfo.hProcess = GetCurrentProcess(); 81 | #endif 82 | 83 | symInfo.hDbgHelp = LoadLibraryExW(L"dbghelp.dll", NULL, 0); 84 | if (symInfo.hDbgHelp == NULL) { 85 | abort: 86 | failed = true; 87 | if (symInfo.hDbgHelp != NULL) { 88 | FreeLibrary(symInfo.hDbgHelp); 89 | } 90 | symInfo.pfImagehlpApiVersionEx = NULL; 91 | symInfo.pfSymInitialize = NULL; 92 | symInfo.pfSymSetOptions = NULL; 93 | symInfo.pfSymGetOptions = NULL; 94 | symInfo.pfSymLoadModule64 = NULL; 95 | symInfo.pfSymGetModuleInfo64 = NULL; 96 | symInfo.pfSymFromName = NULL; 97 | return NULL; 98 | } 99 | 100 | symInfo.pfImagehlpApiVersionEx 101 | = (PF_ImagehlpApiVersionEx)GetProcAddress(symInfo.hDbgHelp, 102 | "ImagehlpApiVersionEx"); 103 | symInfo.pfSymInitialize 104 | = (PF_SymInitialize)GetProcAddress(symInfo.hDbgHelp, "SymInitialize"); 105 | symInfo.pfSymSetOptions 106 | = (PF_SymSetOptions)GetProcAddress(symInfo.hDbgHelp, "SymSetOptions"); 107 | symInfo.pfSymGetOptions 108 | = (PF_SymGetOptions)GetProcAddress(symInfo.hDbgHelp, "SymGetOptions"); 109 | symInfo.pfSymLoadModule64 110 | = (PF_SymLoadModule64)GetProcAddress(symInfo.hDbgHelp, "SymLoadModule64"); 111 | symInfo.pfSymGetModuleInfo64 112 | = (PF_SymGetModuleInfo64)GetProcAddress(symInfo.hDbgHelp, "SymGetModuleInfo64"); 113 | symInfo.pfSymFromName 114 | = (PF_SymFromName)GetProcAddress(symInfo.hDbgHelp, "SymFromName"); 115 | 116 | API_VERSION av; 117 | ZeroMemory(&av, sizeof(av)); 118 | av.MajorVersion = API_VERSION_NUMBER; 119 | 120 | if (symInfo.pfImagehlpApiVersionEx == NULL || 121 | symInfo.pfSymInitialize == NULL || 122 | symInfo.pfSymLoadModule64 == NULL || 123 | symInfo.pfSymGetModuleInfo64 == NULL || 124 | symInfo.pfSymFromName == NULL) { 125 | goto abort; 126 | } 127 | 128 | symInfo.pfImagehlpApiVersionEx(&av); 129 | if (av.MajorVersion < API_VERSION_NUMBER) { 130 | goto abort; 131 | } 132 | 133 | if (!symInfo.pfSymInitialize(symInfo.hProcess, NULL, FALSE)) { 134 | // We won't retry the initialize if it fails. 135 | goto abort; 136 | } 137 | 138 | if (symInfo.pfSymGetOptions != NULL && symInfo.pfSymSetOptions != NULL) { 139 | DWORD dw = symInfo.pfSymGetOptions(); 140 | 141 | dw &= ~(SYMOPT_CASE_INSENSITIVE | 142 | SYMOPT_UNDNAME | 143 | SYMOPT_DEFERRED_LOADS | 144 | 0); 145 | dw |= ( 146 | #if defined(SYMOPT_EXACT_SYMBOLS) 147 | SYMOPT_EXACT_SYMBOLS | 148 | #endif 149 | #if defined(SYMOPT_NO_UNQUALIFIED_LOADS) 150 | SYMOPT_NO_UNQUALIFIED_LOADS | 151 | #endif 152 | SYMOPT_DEFERRED_LOADS | 153 | #if defined(SYMOPT_FAIL_CRITICAL_ERRORS) 154 | SYMOPT_FAIL_CRITICAL_ERRORS | 155 | #endif 156 | #if defined(SYMOPT_INCLUDE_32BIT_MODULES) 157 | SYMOPT_INCLUDE_32BIT_MODULES | 158 | #endif 159 | 0); 160 | symInfo.pfSymSetOptions(dw); 161 | } 162 | 163 | pSymInfo = &symInfo; 164 | return pSymInfo; 165 | } 166 | 167 | PVOID WINAPI DetourFindFunction(_In_ PCSTR pszModule, 168 | _In_ PCSTR pszFunction) 169 | { 170 | /////////////////////////////////////////////// First, try GetProcAddress. 171 | // 172 | #pragma prefast(suppress:28752, "We don't do the unicode conversion for LoadLibraryExA.") 173 | HMODULE hModule = LoadLibraryExA(pszModule, NULL, 0); 174 | if (hModule == NULL) { 175 | return NULL; 176 | } 177 | 178 | PBYTE pbCode = (PBYTE)GetProcAddress(hModule, pszFunction); 179 | if (pbCode) { 180 | return pbCode; 181 | } 182 | 183 | ////////////////////////////////////////////////////// Then try ImageHelp. 184 | // 185 | DETOUR_TRACE(("DetourFindFunction(%hs, %hs)\n", pszModule, pszFunction)); 186 | PDETOUR_SYM_INFO pSymInfo = DetourLoadImageHlp(); 187 | if (pSymInfo == NULL) { 188 | DETOUR_TRACE(("DetourLoadImageHlp failed: %d\n", 189 | GetLastError())); 190 | return NULL; 191 | } 192 | 193 | if (pSymInfo->pfSymLoadModule64(pSymInfo->hProcess, NULL, 194 | (PCHAR)pszModule, NULL, 195 | (DWORD64)hModule, 0) == 0) { 196 | if (ERROR_SUCCESS != GetLastError()) { 197 | DETOUR_TRACE(("SymLoadModule64(%p) failed: %d\n", 198 | pSymInfo->hProcess, GetLastError())); 199 | return NULL; 200 | } 201 | } 202 | 203 | HRESULT hrRet; 204 | CHAR szFullName[512]; 205 | IMAGEHLP_MODULE64 modinfo; 206 | ZeroMemory(&modinfo, sizeof(modinfo)); 207 | modinfo.SizeOfStruct = sizeof(modinfo); 208 | if (!pSymInfo->pfSymGetModuleInfo64(pSymInfo->hProcess, (DWORD64)hModule, &modinfo)) { 209 | DETOUR_TRACE(("SymGetModuleInfo64(%p, %p) failed: %d\n", 210 | pSymInfo->hProcess, hModule, GetLastError())); 211 | return NULL; 212 | } 213 | 214 | hrRet = StringCchCopyA(szFullName, sizeof(szFullName)/sizeof(CHAR), modinfo.ModuleName); 215 | if (FAILED(hrRet)) { 216 | DETOUR_TRACE(("StringCchCopyA failed: %08x\n", hrRet)); 217 | return NULL; 218 | } 219 | hrRet = StringCchCatA(szFullName, sizeof(szFullName)/sizeof(CHAR), "!"); 220 | if (FAILED(hrRet)) { 221 | DETOUR_TRACE(("StringCchCatA failed: %08x\n", hrRet)); 222 | return NULL; 223 | } 224 | hrRet = StringCchCatA(szFullName, sizeof(szFullName)/sizeof(CHAR), pszFunction); 225 | if (FAILED(hrRet)) { 226 | DETOUR_TRACE(("StringCchCatA failed: %08x\n", hrRet)); 227 | return NULL; 228 | } 229 | 230 | struct CFullSymbol : SYMBOL_INFO { 231 | CHAR szRestOfName[512]; 232 | } symbol; 233 | ZeroMemory(&symbol, sizeof(symbol)); 234 | //symbol.ModBase = (ULONG64)hModule; 235 | symbol.SizeOfStruct = sizeof(SYMBOL_INFO); 236 | #ifdef DBHLPAPI 237 | symbol.MaxNameLen = sizeof(symbol.szRestOfName)/sizeof(symbol.szRestOfName[0]); 238 | #else 239 | symbol.MaxNameLength = sizeof(symbol.szRestOfName)/sizeof(symbol.szRestOfName[0]); 240 | #endif 241 | 242 | if (!pSymInfo->pfSymFromName(pSymInfo->hProcess, szFullName, &symbol)) { 243 | DETOUR_TRACE(("SymFromName(%hs) failed: %d\n", szFullName, GetLastError())); 244 | return NULL; 245 | } 246 | 247 | #if defined(DETOURS_IA64) 248 | // On the IA64, we get a raw code pointer from the symbol engine 249 | // and have to convert it to a wrapped [code pointer, global pointer]. 250 | // 251 | PPLABEL_DESCRIPTOR pldEntry = (PPLABEL_DESCRIPTOR)DetourGetEntryPoint(hModule); 252 | PPLABEL_DESCRIPTOR pldSymbol = new PLABEL_DESCRIPTOR; 253 | 254 | pldSymbol->EntryPoint = symbol.Address; 255 | pldSymbol->GlobalPointer = pldEntry->GlobalPointer; 256 | return (PBYTE)pldSymbol; 257 | #elif defined(DETOURS_ARM) 258 | // On the ARM, we get a raw code pointer, which we must convert into a 259 | // valied Thumb2 function pointer. 260 | return DETOURS_PBYTE_TO_PFUNC(symbol.Address); 261 | #else 262 | return (PBYTE)symbol.Address; 263 | #endif 264 | } 265 | 266 | //////////////////////////////////////////////////// Module Image Functions. 267 | // 268 | 269 | HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast) 270 | { 271 | PBYTE pbLast = (PBYTE)hModuleLast + MM_ALLOCATION_GRANULARITY; 272 | 273 | MEMORY_BASIC_INFORMATION mbi; 274 | ZeroMemory(&mbi, sizeof(mbi)); 275 | 276 | // Find the next memory region that contains a mapped PE image. 277 | // 278 | for (;; pbLast = (PBYTE)mbi.BaseAddress + mbi.RegionSize) { 279 | if (VirtualQuery(pbLast, &mbi, sizeof(mbi)) <= 0) { 280 | break; 281 | } 282 | 283 | // Skip uncommitted regions and guard pages. 284 | // 285 | if ((mbi.State != MEM_COMMIT) || 286 | ((mbi.Protect & 0xff) == PAGE_NOACCESS) || 287 | (mbi.Protect & PAGE_GUARD)) { 288 | continue; 289 | } 290 | 291 | __try { 292 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pbLast; 293 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE || 294 | (DWORD)pDosHeader->e_lfanew > mbi.RegionSize || 295 | (DWORD)pDosHeader->e_lfanew < sizeof(*pDosHeader)) { 296 | continue; 297 | } 298 | 299 | PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + 300 | pDosHeader->e_lfanew); 301 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { 302 | continue; 303 | } 304 | 305 | return (HMODULE)pDosHeader; 306 | } 307 | #pragma prefast(suppress:28940, "A bad pointer means this probably isn't a PE header.") 308 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? 309 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 310 | continue; 311 | } 312 | } 313 | return NULL; 314 | } 315 | 316 | PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule) 317 | { 318 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule; 319 | if (hModule == NULL) { 320 | pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL); 321 | } 322 | 323 | __try { 324 | #pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL. 325 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { 326 | SetLastError(ERROR_BAD_EXE_FORMAT); 327 | return NULL; 328 | } 329 | 330 | PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + 331 | pDosHeader->e_lfanew); 332 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { 333 | SetLastError(ERROR_INVALID_EXE_SIGNATURE); 334 | return NULL; 335 | } 336 | if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) { 337 | SetLastError(ERROR_EXE_MARKED_INVALID); 338 | return NULL; 339 | } 340 | 341 | PDETOUR_CLR_HEADER pClrHeader = NULL; 342 | if (pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { 343 | if (((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.VirtualAddress != 0 && 344 | ((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.Size != 0) { 345 | pClrHeader = (PDETOUR_CLR_HEADER) 346 | (((PBYTE)pDosHeader) 347 | + ((PIMAGE_NT_HEADERS32)pNtHeader)->CLR_DIRECTORY.VirtualAddress); 348 | } 349 | } 350 | else if (pNtHeader->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { 351 | if (((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.VirtualAddress != 0 && 352 | ((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.Size != 0) { 353 | pClrHeader = (PDETOUR_CLR_HEADER) 354 | (((PBYTE)pDosHeader) 355 | + ((PIMAGE_NT_HEADERS64)pNtHeader)->CLR_DIRECTORY.VirtualAddress); 356 | } 357 | } 358 | 359 | if (pClrHeader != NULL) { 360 | // For MSIL assemblies, we want to use the _Cor entry points. 361 | 362 | HMODULE hClr = GetModuleHandleW(L"MSCOREE.DLL"); 363 | if (hClr == NULL) { 364 | return NULL; 365 | } 366 | 367 | SetLastError(NO_ERROR); 368 | return GetProcAddress(hClr, "_CorExeMain"); 369 | } 370 | 371 | SetLastError(NO_ERROR); 372 | 373 | // Pure resource DLLs have neither an entry point nor CLR information 374 | // so handle them by returning NULL (LastError is NO_ERROR) 375 | if (pNtHeader->OptionalHeader.AddressOfEntryPoint == 0) { 376 | return NULL; 377 | } 378 | 379 | return ((PBYTE)pDosHeader) + 380 | pNtHeader->OptionalHeader.AddressOfEntryPoint; 381 | } 382 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? 383 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 384 | SetLastError(ERROR_EXE_MARKED_INVALID); 385 | return NULL; 386 | } 387 | } 388 | 389 | ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule) 390 | { 391 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule; 392 | if (hModule == NULL) { 393 | pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL); 394 | } 395 | 396 | __try { 397 | #pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL. 398 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { 399 | SetLastError(ERROR_BAD_EXE_FORMAT); 400 | return NULL; 401 | } 402 | 403 | PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + 404 | pDosHeader->e_lfanew); 405 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { 406 | SetLastError(ERROR_INVALID_EXE_SIGNATURE); 407 | return NULL; 408 | } 409 | if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) { 410 | SetLastError(ERROR_EXE_MARKED_INVALID); 411 | return NULL; 412 | } 413 | SetLastError(NO_ERROR); 414 | 415 | return (pNtHeader->OptionalHeader.SizeOfImage); 416 | } 417 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? 418 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 419 | SetLastError(ERROR_EXE_MARKED_INVALID); 420 | return NULL; 421 | } 422 | } 423 | 424 | HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr) 425 | { 426 | MEMORY_BASIC_INFORMATION mbi; 427 | ZeroMemory(&mbi, sizeof(mbi)); 428 | 429 | __try { 430 | if (VirtualQuery(pvAddr, &mbi, sizeof(mbi)) <= 0) { 431 | SetLastError(ERROR_BAD_EXE_FORMAT); 432 | return NULL; 433 | } 434 | 435 | // Skip uncommitted regions and guard pages. 436 | // 437 | if ((mbi.State != MEM_COMMIT) || 438 | ((mbi.Protect & 0xff) == PAGE_NOACCESS) || 439 | (mbi.Protect & PAGE_GUARD)) { 440 | SetLastError(ERROR_BAD_EXE_FORMAT); 441 | return NULL; 442 | } 443 | 444 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)mbi.AllocationBase; 445 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { 446 | SetLastError(ERROR_BAD_EXE_FORMAT); 447 | return NULL; 448 | } 449 | 450 | PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + 451 | pDosHeader->e_lfanew); 452 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { 453 | SetLastError(ERROR_INVALID_EXE_SIGNATURE); 454 | return NULL; 455 | } 456 | if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) { 457 | SetLastError(ERROR_EXE_MARKED_INVALID); 458 | return NULL; 459 | } 460 | SetLastError(NO_ERROR); 461 | 462 | return (HMODULE)pDosHeader; 463 | } 464 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? 465 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 466 | SetLastError(ERROR_INVALID_EXE_SIGNATURE); 467 | return NULL; 468 | } 469 | } 470 | 471 | 472 | static inline PBYTE RvaAdjust(_Pre_notnull_ PIMAGE_DOS_HEADER pDosHeader, _In_ DWORD raddr) 473 | { 474 | if (raddr != NULL) { 475 | return ((PBYTE)pDosHeader) + raddr; 476 | } 477 | return NULL; 478 | } 479 | 480 | BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule, 481 | _In_opt_ PVOID pContext, 482 | _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport) 483 | { 484 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule; 485 | if (hModule == NULL) { 486 | pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL); 487 | } 488 | 489 | __try { 490 | #pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL. 491 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { 492 | SetLastError(ERROR_BAD_EXE_FORMAT); 493 | return NULL; 494 | } 495 | 496 | PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + 497 | pDosHeader->e_lfanew); 498 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { 499 | SetLastError(ERROR_INVALID_EXE_SIGNATURE); 500 | return FALSE; 501 | } 502 | if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) { 503 | SetLastError(ERROR_EXE_MARKED_INVALID); 504 | return FALSE; 505 | } 506 | 507 | PIMAGE_EXPORT_DIRECTORY pExportDir 508 | = (PIMAGE_EXPORT_DIRECTORY) 509 | RvaAdjust(pDosHeader, 510 | pNtHeader->OptionalHeader 511 | .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 512 | 513 | if (pExportDir == NULL) { 514 | SetLastError(ERROR_EXE_MARKED_INVALID); 515 | return FALSE; 516 | } 517 | 518 | PBYTE pExportDirEnd = (PBYTE)pExportDir + pNtHeader->OptionalHeader 519 | .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; 520 | PDWORD pdwFunctions = (PDWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfFunctions); 521 | PDWORD pdwNames = (PDWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfNames); 522 | PWORD pwOrdinals = (PWORD)RvaAdjust(pDosHeader, pExportDir->AddressOfNameOrdinals); 523 | 524 | for (DWORD nFunc = 0; nFunc < pExportDir->NumberOfFunctions; nFunc++) { 525 | PBYTE pbCode = (pdwFunctions != NULL) 526 | ? (PBYTE)RvaAdjust(pDosHeader, pdwFunctions[nFunc]) : NULL; 527 | PCHAR pszName = NULL; 528 | 529 | // if the pointer is in the export region, then it is a forwarder. 530 | if (pbCode > (PBYTE)pExportDir && pbCode < pExportDirEnd) { 531 | pbCode = NULL; 532 | } 533 | 534 | for (DWORD n = 0; n < pExportDir->NumberOfNames; n++) { 535 | if (pwOrdinals[n] == nFunc) { 536 | pszName = (pdwNames != NULL) 537 | ? (PCHAR)RvaAdjust(pDosHeader, pdwNames[n]) : NULL; 538 | break; 539 | } 540 | } 541 | ULONG nOrdinal = pExportDir->Base + nFunc; 542 | 543 | if (!pfExport(pContext, nOrdinal, pszName, pbCode)) { 544 | break; 545 | } 546 | } 547 | SetLastError(NO_ERROR); 548 | return TRUE; 549 | } 550 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? 551 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 552 | SetLastError(ERROR_EXE_MARKED_INVALID); 553 | return NULL; 554 | } 555 | } 556 | 557 | BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule, 558 | _In_opt_ PVOID pContext, 559 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 560 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFunc) 561 | { 562 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule; 563 | if (hModule == NULL) { 564 | pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL); 565 | } 566 | 567 | __try { 568 | #pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL. 569 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { 570 | SetLastError(ERROR_BAD_EXE_FORMAT); 571 | return FALSE; 572 | } 573 | 574 | PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + 575 | pDosHeader->e_lfanew); 576 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { 577 | SetLastError(ERROR_INVALID_EXE_SIGNATURE); 578 | return FALSE; 579 | } 580 | if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) { 581 | SetLastError(ERROR_EXE_MARKED_INVALID); 582 | return FALSE; 583 | } 584 | 585 | PIMAGE_IMPORT_DESCRIPTOR iidp 586 | = (PIMAGE_IMPORT_DESCRIPTOR) 587 | RvaAdjust(pDosHeader, 588 | pNtHeader->OptionalHeader 589 | .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 590 | 591 | if (iidp == NULL) { 592 | SetLastError(ERROR_EXE_MARKED_INVALID); 593 | return FALSE; 594 | } 595 | 596 | for (; iidp->OriginalFirstThunk != 0; iidp++) { 597 | 598 | PCSTR pszName = (PCHAR)RvaAdjust(pDosHeader, iidp->Name); 599 | if (pszName == NULL) { 600 | SetLastError(ERROR_EXE_MARKED_INVALID); 601 | return FALSE; 602 | } 603 | 604 | PIMAGE_THUNK_DATA pThunks = (PIMAGE_THUNK_DATA) 605 | RvaAdjust(pDosHeader, iidp->OriginalFirstThunk); 606 | PVOID * pAddrs = (PVOID *) 607 | RvaAdjust(pDosHeader, iidp->FirstThunk); 608 | 609 | HMODULE hFile = DetourGetContainingModule(pAddrs[0]); 610 | 611 | if (pfImportFile != NULL) { 612 | if (!pfImportFile(pContext, hFile, pszName)) { 613 | break; 614 | } 615 | } 616 | 617 | DWORD nNames = 0; 618 | if (pThunks) { 619 | for (; pThunks[nNames].u1.Ordinal; nNames++) { 620 | DWORD nOrdinal = 0; 621 | PCSTR pszFunc = NULL; 622 | 623 | if (IMAGE_SNAP_BY_ORDINAL(pThunks[nNames].u1.Ordinal)) { 624 | nOrdinal = (DWORD)IMAGE_ORDINAL(pThunks[nNames].u1.Ordinal); 625 | } 626 | else { 627 | pszFunc = (PCSTR)RvaAdjust(pDosHeader, 628 | (DWORD)pThunks[nNames].u1.AddressOfData + 2); 629 | } 630 | 631 | if (pfImportFunc != NULL) { 632 | if (!pfImportFunc(pContext, 633 | nOrdinal, 634 | pszFunc, 635 | &pAddrs[nNames])) { 636 | break; 637 | } 638 | } 639 | } 640 | if (pfImportFunc != NULL) { 641 | pfImportFunc(pContext, 0, NULL, NULL); 642 | } 643 | } 644 | } 645 | if (pfImportFile != NULL) { 646 | pfImportFile(pContext, NULL, NULL); 647 | } 648 | SetLastError(NO_ERROR); 649 | return TRUE; 650 | } 651 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? 652 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 653 | SetLastError(ERROR_EXE_MARKED_INVALID); 654 | return FALSE; 655 | } 656 | } 657 | 658 | // Context for DetourEnumerateImportsThunk, which adapts "regular" callbacks for use with "Ex". 659 | struct _DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT 660 | { 661 | PVOID pContext; 662 | PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc; 663 | }; 664 | 665 | // Callback for DetourEnumerateImportsEx that adapts DetourEnumerateImportsEx 666 | // for use with a DetourEnumerateImports callback -- derefence the IAT and pass the value on. 667 | 668 | static 669 | BOOL 670 | CALLBACK 671 | DetourEnumerateImportsThunk(_In_ PVOID VoidContext, 672 | _In_ DWORD nOrdinal, 673 | _In_opt_ PCSTR pszFunc, 674 | _In_opt_ PVOID* ppvFunc) 675 | { 676 | _DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT const * const 677 | pContext = (_DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT*)VoidContext; 678 | return pContext->pfImportFunc(pContext->pContext, nOrdinal, pszFunc, ppvFunc ? *ppvFunc : NULL); 679 | } 680 | 681 | BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule, 682 | _In_opt_ PVOID pContext, 683 | _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile, 684 | _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc) 685 | { 686 | _DETOUR_ENUMERATE_IMPORTS_THUNK_CONTEXT const context = { pContext, pfImportFunc }; 687 | 688 | return DetourEnumerateImportsEx(hModule, 689 | (PVOID)&context, 690 | pfImportFile, 691 | &DetourEnumerateImportsThunk); 692 | } 693 | 694 | static PDETOUR_LOADED_BINARY WINAPI GetPayloadSectionFromModule(HMODULE hModule) 695 | { 696 | PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)hModule; 697 | if (hModule == NULL) { 698 | pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandleW(NULL); 699 | } 700 | 701 | __try { 702 | #pragma warning(suppress:6011) // GetModuleHandleW(NULL) never returns NULL. 703 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { 704 | SetLastError(ERROR_BAD_EXE_FORMAT); 705 | return NULL; 706 | } 707 | 708 | PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)pDosHeader + 709 | pDosHeader->e_lfanew); 710 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) { 711 | SetLastError(ERROR_INVALID_EXE_SIGNATURE); 712 | return NULL; 713 | } 714 | if (pNtHeader->FileHeader.SizeOfOptionalHeader == 0) { 715 | SetLastError(ERROR_EXE_MARKED_INVALID); 716 | return NULL; 717 | } 718 | 719 | PIMAGE_SECTION_HEADER pSectionHeaders 720 | = (PIMAGE_SECTION_HEADER)((PBYTE)pNtHeader 721 | + sizeof(pNtHeader->Signature) 722 | + sizeof(pNtHeader->FileHeader) 723 | + pNtHeader->FileHeader.SizeOfOptionalHeader); 724 | 725 | for (DWORD n = 0; n < pNtHeader->FileHeader.NumberOfSections; n++) { 726 | if (strcmp((PCHAR)pSectionHeaders[n].Name, ".detour") == 0) { 727 | if (pSectionHeaders[n].VirtualAddress == 0 || 728 | pSectionHeaders[n].SizeOfRawData == 0) { 729 | 730 | break; 731 | } 732 | 733 | PBYTE pbData = (PBYTE)pDosHeader + pSectionHeaders[n].VirtualAddress; 734 | DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pbData; 735 | if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) || 736 | pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) { 737 | 738 | break; 739 | } 740 | 741 | if (pHeader->nDataOffset == 0) { 742 | pHeader->nDataOffset = pHeader->cbHeaderSize; 743 | } 744 | SetLastError(NO_ERROR); 745 | return (PBYTE)pHeader; 746 | } 747 | } 748 | SetLastError(ERROR_EXE_MARKED_INVALID); 749 | return NULL; 750 | } 751 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? 752 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 753 | SetLastError(ERROR_EXE_MARKED_INVALID); 754 | return NULL; 755 | } 756 | } 757 | 758 | DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule) 759 | { 760 | PDETOUR_LOADED_BINARY pBinary = GetPayloadSectionFromModule(hModule); 761 | if (pBinary == NULL) { 762 | // Error set by GetPayloadSectionFromModule. 763 | return 0; 764 | } 765 | 766 | __try { 767 | DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary; 768 | if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) || 769 | pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) { 770 | 771 | SetLastError(ERROR_INVALID_HANDLE); 772 | return 0; 773 | } 774 | SetLastError(NO_ERROR); 775 | return pHeader->cbDataSize; 776 | } 777 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? 778 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 779 | SetLastError(ERROR_INVALID_HANDLE); 780 | return 0; 781 | } 782 | } 783 | 784 | _Writable_bytes_(*pcbData) 785 | _Readable_bytes_(*pcbData) 786 | _Success_(return != NULL) 787 | PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule, 788 | _In_ REFGUID rguid, 789 | _Out_ DWORD *pcbData) 790 | { 791 | PBYTE pbData = NULL; 792 | if (pcbData) { 793 | *pcbData = 0; 794 | } 795 | 796 | PDETOUR_LOADED_BINARY pBinary = GetPayloadSectionFromModule(hModule); 797 | if (pBinary == NULL) { 798 | // Error set by GetPayloadSectionFromModule. 799 | return NULL; 800 | } 801 | 802 | __try { 803 | DETOUR_SECTION_HEADER *pHeader = (DETOUR_SECTION_HEADER *)pBinary; 804 | if (pHeader->cbHeaderSize < sizeof(DETOUR_SECTION_HEADER) || 805 | pHeader->nSignature != DETOUR_SECTION_HEADER_SIGNATURE) { 806 | 807 | SetLastError(ERROR_INVALID_EXE_SIGNATURE); 808 | return NULL; 809 | } 810 | 811 | PBYTE pbBeg = ((PBYTE)pHeader) + pHeader->nDataOffset; 812 | PBYTE pbEnd = ((PBYTE)pHeader) + pHeader->cbDataSize; 813 | 814 | for (pbData = pbBeg; pbData < pbEnd;) { 815 | DETOUR_SECTION_RECORD *pSection = (DETOUR_SECTION_RECORD *)pbData; 816 | 817 | if (pSection->guid.Data1 == rguid.Data1 && 818 | pSection->guid.Data2 == rguid.Data2 && 819 | pSection->guid.Data3 == rguid.Data3 && 820 | pSection->guid.Data4[0] == rguid.Data4[0] && 821 | pSection->guid.Data4[1] == rguid.Data4[1] && 822 | pSection->guid.Data4[2] == rguid.Data4[2] && 823 | pSection->guid.Data4[3] == rguid.Data4[3] && 824 | pSection->guid.Data4[4] == rguid.Data4[4] && 825 | pSection->guid.Data4[5] == rguid.Data4[5] && 826 | pSection->guid.Data4[6] == rguid.Data4[6] && 827 | pSection->guid.Data4[7] == rguid.Data4[7]) { 828 | 829 | if (pcbData) { 830 | *pcbData = pSection->cbBytes - sizeof(*pSection); 831 | SetLastError(NO_ERROR); 832 | return (PBYTE)(pSection + 1); 833 | } 834 | } 835 | 836 | pbData = (PBYTE)pSection + pSection->cbBytes; 837 | } 838 | SetLastError(ERROR_INVALID_HANDLE); 839 | return NULL; 840 | } 841 | __except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? 842 | EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { 843 | SetLastError(ERROR_INVALID_HANDLE); 844 | return NULL; 845 | } 846 | } 847 | 848 | _Writable_bytes_(*pcbData) 849 | _Readable_bytes_(*pcbData) 850 | _Success_(return != NULL) 851 | PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid, 852 | _Out_ DWORD * pcbData) 853 | { 854 | for (HMODULE hMod = NULL; (hMod = DetourEnumerateModules(hMod)) != NULL;) { 855 | PVOID pvData; 856 | 857 | pvData = DetourFindPayload(hMod, rguid, pcbData); 858 | if (pvData != NULL) { 859 | return pvData; 860 | } 861 | } 862 | SetLastError(ERROR_MOD_NOT_FOUND); 863 | return NULL; 864 | } 865 | 866 | BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, 867 | _In_ DWORD cbData) 868 | { 869 | PDETOUR_EXE_RESTORE pder = (PDETOUR_EXE_RESTORE)pvData; 870 | 871 | if (pder->cb != sizeof(*pder) || pder->cb > cbData) { 872 | SetLastError(ERROR_BAD_EXE_FORMAT); 873 | return FALSE; 874 | } 875 | 876 | DWORD dwPermIdh = ~0u; 877 | DWORD dwPermInh = ~0u; 878 | DWORD dwPermClr = ~0u; 879 | DWORD dwIgnore; 880 | BOOL fSucceeded = FALSE; 881 | BOOL fUpdated32To64 = FALSE; 882 | 883 | if (pder->pclr != NULL && pder->clr.Flags != ((PDETOUR_CLR_HEADER)pder->pclr)->Flags) { 884 | // If we had to promote the 32/64-bit agnostic IL to 64-bit, we can't restore 885 | // that. 886 | fUpdated32To64 = TRUE; 887 | } 888 | 889 | if (DetourVirtualProtectSameExecute(pder->pidh, pder->cbidh, 890 | PAGE_EXECUTE_READWRITE, &dwPermIdh)) { 891 | if (DetourVirtualProtectSameExecute(pder->pinh, pder->cbinh, 892 | PAGE_EXECUTE_READWRITE, &dwPermInh)) { 893 | 894 | CopyMemory(pder->pidh, &pder->idh, pder->cbidh); 895 | CopyMemory(pder->pinh, &pder->inh, pder->cbinh); 896 | 897 | if (pder->pclr != NULL && !fUpdated32To64) { 898 | if (DetourVirtualProtectSameExecute(pder->pclr, pder->cbclr, 899 | PAGE_EXECUTE_READWRITE, &dwPermClr)) { 900 | CopyMemory(pder->pclr, &pder->clr, pder->cbclr); 901 | VirtualProtect(pder->pclr, pder->cbclr, dwPermClr, &dwIgnore); 902 | fSucceeded = TRUE; 903 | } 904 | } 905 | else { 906 | fSucceeded = TRUE; 907 | } 908 | VirtualProtect(pder->pinh, pder->cbinh, dwPermInh, &dwIgnore); 909 | } 910 | VirtualProtect(pder->pidh, pder->cbidh, dwPermIdh, &dwIgnore); 911 | } 912 | return fSucceeded; 913 | } 914 | 915 | BOOL WINAPI DetourRestoreAfterWith() 916 | { 917 | PVOID pvData; 918 | DWORD cbData; 919 | 920 | pvData = DetourFindPayloadEx(DETOUR_EXE_RESTORE_GUID, &cbData); 921 | 922 | if (pvData != NULL && cbData != 0) { 923 | return DetourRestoreAfterWithEx(pvData, cbData); 924 | } 925 | SetLastError(ERROR_MOD_NOT_FOUND); 926 | return FALSE; 927 | } 928 | 929 | // End of File 930 | -------------------------------------------------------------------------------- /Detours-4.0.1/src/uimports.cpp: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Add DLLs to a module import table (uimports.cpp of detours.lib) 4 | // 5 | // Microsoft Research Detours Package, Version 4.0.1 6 | // 7 | // Copyright (c) Microsoft Corporation. All rights reserved. 8 | // 9 | // Note that this file is included into creatwth.cpp one or more times 10 | // (once for each supported module format). 11 | // 12 | 13 | #if DETOURS_VERSION != 0x4c0c1 // 0xMAJORcMINORcPATCH 14 | #error detours.h version mismatch 15 | #endif 16 | 17 | // UpdateImports32 aka UpdateImports64 18 | static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess, 19 | HMODULE hModule, 20 | __in_ecount(nDlls) LPCSTR *plpDlls, 21 | DWORD nDlls) 22 | { 23 | BOOL fSucceeded = FALSE; 24 | DWORD cbNew = 0; 25 | 26 | BYTE * pbNew = NULL; 27 | DWORD i; 28 | SIZE_T cbRead; 29 | DWORD n; 30 | 31 | PBYTE pbModule = (PBYTE)hModule; 32 | 33 | IMAGE_DOS_HEADER idh; 34 | ZeroMemory(&idh, sizeof(idh)); 35 | if (!ReadProcessMemory(hProcess, pbModule, &idh, sizeof(idh), &cbRead) 36 | || cbRead < sizeof(idh)) { 37 | 38 | DETOUR_TRACE(("ReadProcessMemory(idh@%p..%p) failed: %d\n", 39 | pbModule, pbModule + sizeof(idh), GetLastError())); 40 | 41 | finish: 42 | if (pbNew != NULL) { 43 | delete[] pbNew; 44 | pbNew = NULL; 45 | } 46 | return fSucceeded; 47 | } 48 | 49 | IMAGE_NT_HEADERS_XX inh; 50 | ZeroMemory(&inh, sizeof(inh)); 51 | 52 | if (!ReadProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), &cbRead) 53 | || cbRead < sizeof(inh)) { 54 | DETOUR_TRACE(("ReadProcessMemory(inh@%p..%p) failed: %d\n", 55 | pbModule + idh.e_lfanew, 56 | pbModule + idh.e_lfanew + sizeof(inh), 57 | GetLastError())); 58 | goto finish; 59 | } 60 | 61 | if (inh.OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC_XX) { 62 | DETOUR_TRACE(("Wrong size image (%04x != %04x).\n", 63 | inh.OptionalHeader.Magic, IMAGE_NT_OPTIONAL_HDR_MAGIC_XX)); 64 | SetLastError(ERROR_INVALID_BLOCK); 65 | goto finish; 66 | } 67 | 68 | // Zero out the bound table so loader doesn't use it instead of our new table. 69 | inh.BOUND_DIRECTORY.VirtualAddress = 0; 70 | inh.BOUND_DIRECTORY.Size = 0; 71 | 72 | // Find the size of the mapped file. 73 | DWORD dwSec = idh.e_lfanew + 74 | FIELD_OFFSET(IMAGE_NT_HEADERS_XX, OptionalHeader) + 75 | inh.FileHeader.SizeOfOptionalHeader; 76 | 77 | for (i = 0; i < inh.FileHeader.NumberOfSections; i++) { 78 | IMAGE_SECTION_HEADER ish; 79 | ZeroMemory(&ish, sizeof(ish)); 80 | 81 | if (!ReadProcessMemory(hProcess, pbModule + dwSec + sizeof(ish) * i, &ish, 82 | sizeof(ish), &cbRead) 83 | || cbRead < sizeof(ish)) { 84 | 85 | DETOUR_TRACE(("ReadProcessMemory(ish@%p..%p) failed: %d\n", 86 | pbModule + dwSec + sizeof(ish) * i, 87 | pbModule + dwSec + sizeof(ish) * (i + 1), 88 | GetLastError())); 89 | goto finish; 90 | } 91 | 92 | DETOUR_TRACE(("ish[%d] : va=%08x sr=%d\n", i, ish.VirtualAddress, ish.SizeOfRawData)); 93 | 94 | // If the file didn't have an IAT_DIRECTORY, we assign it... 95 | if (inh.IAT_DIRECTORY.VirtualAddress == 0 && 96 | inh.IMPORT_DIRECTORY.VirtualAddress >= ish.VirtualAddress && 97 | inh.IMPORT_DIRECTORY.VirtualAddress < ish.VirtualAddress + ish.SizeOfRawData) { 98 | 99 | inh.IAT_DIRECTORY.VirtualAddress = ish.VirtualAddress; 100 | inh.IAT_DIRECTORY.Size = ish.SizeOfRawData; 101 | } 102 | } 103 | 104 | DETOUR_TRACE((" Imports: %p..%p\n", 105 | (DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress, 106 | (DWORD_PTR)pbModule + inh.IMPORT_DIRECTORY.VirtualAddress + 107 | inh.IMPORT_DIRECTORY.Size)); 108 | 109 | DWORD nOldDlls = inh.IMPORT_DIRECTORY.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR); 110 | DWORD obRem = sizeof(IMAGE_IMPORT_DESCRIPTOR) * nDlls; 111 | DWORD obOld = obRem + sizeof(IMAGE_IMPORT_DESCRIPTOR) * nOldDlls; 112 | DWORD obTab = PadToDwordPtr(obOld); 113 | DWORD obDll = obTab + sizeof(DWORD_XX) * 4 * nDlls; 114 | DWORD obStr = obDll; 115 | cbNew = obStr; 116 | for (n = 0; n < nDlls; n++) { 117 | cbNew += PadToDword((DWORD)strlen(plpDlls[n]) + 1); 118 | } 119 | 120 | _Analysis_assume_(cbNew > 121 | sizeof(IMAGE_IMPORT_DESCRIPTOR) * (nDlls + nOldDlls) 122 | + sizeof(DWORD_XX) * 4 * nDlls); 123 | pbNew = new BYTE [cbNew]; 124 | if (pbNew == NULL) { 125 | DETOUR_TRACE(("new BYTE [cbNew] failed.\n")); 126 | goto finish; 127 | } 128 | ZeroMemory(pbNew, cbNew); 129 | 130 | PBYTE pbBase = pbModule; 131 | PBYTE pbNext = pbBase 132 | + inh.OptionalHeader.BaseOfCode 133 | + inh.OptionalHeader.SizeOfCode 134 | + inh.OptionalHeader.SizeOfInitializedData 135 | + inh.OptionalHeader.SizeOfUninitializedData; 136 | if (pbBase < pbNext) { 137 | pbBase = pbNext; 138 | } 139 | DETOUR_TRACE(("pbBase = %p\n", pbBase)); 140 | 141 | PBYTE pbNewIid = FindAndAllocateNearBase(hProcess, pbBase, cbNew); 142 | if (pbNewIid == NULL) { 143 | DETOUR_TRACE(("FindAndAllocateNearBase failed.\n")); 144 | goto finish; 145 | } 146 | 147 | PIMAGE_IMPORT_DESCRIPTOR piid = (PIMAGE_IMPORT_DESCRIPTOR)pbNew; 148 | DWORD_XX *pt; 149 | 150 | DWORD obBase = (DWORD)(pbNewIid - pbModule); 151 | DWORD dwProtect = 0; 152 | 153 | if (inh.IMPORT_DIRECTORY.VirtualAddress != 0) { 154 | // Read the old import directory if it exists. 155 | DETOUR_TRACE(("IMPORT_DIRECTORY perms=%x\n", dwProtect)); 156 | 157 | if (!ReadProcessMemory(hProcess, 158 | pbModule + inh.IMPORT_DIRECTORY.VirtualAddress, 159 | &piid[nDlls], 160 | nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR), &cbRead) 161 | || cbRead < nOldDlls * sizeof(IMAGE_IMPORT_DESCRIPTOR)) { 162 | 163 | DETOUR_TRACE(("ReadProcessMemory(imports) failed: %d\n", GetLastError())); 164 | goto finish; 165 | } 166 | } 167 | 168 | for (n = 0; n < nDlls; n++) { 169 | HRESULT hrRet = StringCchCopyA((char*)pbNew + obStr, cbNew - obStr, plpDlls[n]); 170 | if (FAILED(hrRet)) { 171 | DETOUR_TRACE(("StringCchCopyA failed: %d\n", GetLastError())); 172 | goto finish; 173 | } 174 | 175 | // After copying the string, we patch up the size "??" bits if any. 176 | hrRet = ReplaceOptionalSizeA((char*)pbNew + obStr, 177 | cbNew - obStr, 178 | DETOURS_STRINGIFY(DETOURS_BITS_XX)); 179 | if (FAILED(hrRet)) { 180 | DETOUR_TRACE(("ReplaceOptionalSizeA failed: %d\n", GetLastError())); 181 | goto finish; 182 | } 183 | 184 | DWORD nOffset = obTab + (sizeof(DWORD_XX) * (4 * n)); 185 | piid[n].OriginalFirstThunk = obBase + nOffset; 186 | pt = ((DWORD_XX*)(pbNew + nOffset)); 187 | pt[0] = IMAGE_ORDINAL_FLAG_XX + 1; 188 | pt[1] = 0; 189 | 190 | nOffset = obTab + (sizeof(DWORD_XX) * ((4 * n) + 2)); 191 | piid[n].FirstThunk = obBase + nOffset; 192 | pt = ((DWORD_XX*)(pbNew + nOffset)); 193 | pt[0] = IMAGE_ORDINAL_FLAG_XX + 1; 194 | pt[1] = 0; 195 | piid[n].TimeDateStamp = 0; 196 | piid[n].ForwarderChain = 0; 197 | piid[n].Name = obBase + obStr; 198 | 199 | obStr += PadToDword((DWORD)strlen(plpDlls[n]) + 1); 200 | } 201 | _Analysis_assume_(obStr <= cbNew); 202 | 203 | #if 0 204 | for (i = 0; i < nDlls + nOldDlls; i++) { 205 | DETOUR_TRACE(("%8d. Look=%08x Time=%08x Fore=%08x Name=%08x Addr=%08x\n", 206 | i, 207 | piid[i].OriginalFirstThunk, 208 | piid[i].TimeDateStamp, 209 | piid[i].ForwarderChain, 210 | piid[i].Name, 211 | piid[i].FirstThunk)); 212 | if (piid[i].OriginalFirstThunk == 0 && piid[i].FirstThunk == 0) { 213 | break; 214 | } 215 | } 216 | #endif 217 | 218 | if (!WriteProcessMemory(hProcess, pbNewIid, pbNew, obStr, NULL)) { 219 | DETOUR_TRACE(("WriteProcessMemory(iid) failed: %d\n", GetLastError())); 220 | goto finish; 221 | } 222 | 223 | DETOUR_TRACE(("obBaseBef = %08x..%08x\n", 224 | inh.IMPORT_DIRECTORY.VirtualAddress, 225 | inh.IMPORT_DIRECTORY.VirtualAddress + inh.IMPORT_DIRECTORY.Size)); 226 | DETOUR_TRACE(("obBaseAft = %08x..%08x\n", obBase, obBase + obStr)); 227 | 228 | // If the file doesn't have an IAT_DIRECTORY, we create it... 229 | if (inh.IAT_DIRECTORY.VirtualAddress == 0) { 230 | inh.IAT_DIRECTORY.VirtualAddress = obBase; 231 | inh.IAT_DIRECTORY.Size = cbNew; 232 | } 233 | 234 | inh.IMPORT_DIRECTORY.VirtualAddress = obBase; 235 | inh.IMPORT_DIRECTORY.Size = cbNew; 236 | 237 | /////////////////////// Update the NT header for the new import directory. 238 | // 239 | if (!DetourVirtualProtectSameExecuteEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders, 240 | PAGE_EXECUTE_READWRITE, &dwProtect)) { 241 | DETOUR_TRACE(("VirtualProtectEx(inh) write failed: %d\n", GetLastError())); 242 | goto finish; 243 | } 244 | 245 | inh.OptionalHeader.CheckSum = 0; 246 | 247 | if (!WriteProcessMemory(hProcess, pbModule, &idh, sizeof(idh), NULL)) { 248 | DETOUR_TRACE(("WriteProcessMemory(idh) failed: %d\n", GetLastError())); 249 | goto finish; 250 | } 251 | DETOUR_TRACE(("WriteProcessMemory(idh:%p..%p)\n", pbModule, pbModule + sizeof(idh))); 252 | 253 | if (!WriteProcessMemory(hProcess, pbModule + idh.e_lfanew, &inh, sizeof(inh), NULL)) { 254 | DETOUR_TRACE(("WriteProcessMemory(inh) failed: %d\n", GetLastError())); 255 | goto finish; 256 | } 257 | DETOUR_TRACE(("WriteProcessMemory(inh:%p..%p)\n", 258 | pbModule + idh.e_lfanew, 259 | pbModule + idh.e_lfanew + sizeof(inh))); 260 | 261 | if (!VirtualProtectEx(hProcess, pbModule, inh.OptionalHeader.SizeOfHeaders, 262 | dwProtect, &dwProtect)) { 263 | DETOUR_TRACE(("VirtualProtectEx(idh) restore failed: %d\n", GetLastError())); 264 | goto finish; 265 | } 266 | 267 | fSucceeded = TRUE; 268 | goto finish; 269 | } 270 | -------------------------------------------------------------------------------- /Detours-4.0.1/system.mak: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | ## 3 | ## Establish build target type for Detours. 4 | ## 5 | ## Microsoft Research Detours Package 6 | ## 7 | ## Copyright (c) Microsoft Corporation. All rights reserved. 8 | ## 9 | 10 | ############################################## Determine Processor Build Type. 11 | ## 12 | !IF "$(DETOURS_TARGET_PROCESSOR)" == "" && "$(PROCESSOR_ARCHITEW6432)" != "" 13 | DETOURS_TARGET_PROCESSOR = X86 14 | !ENDIF 15 | 16 | !IF "$(DETOURS_TARGET_PROCESSOR)" == "" 17 | DETOURS_TARGET_PROCESSOR = $(PROCESSOR_ARCHITECTURE) 18 | !ENDIF 19 | 20 | # uppercase DETOURS_TARGET_PROCESSOR 21 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:a=A) 22 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:b=B) 23 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:c=C) 24 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:d=D) 25 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:e=E) 26 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:f=F) 27 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:g=G) 28 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:h=H) 29 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:i=I) 30 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:j=J) 31 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:k=K) 32 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:l=L) 33 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:m=M) 34 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:n=N) 35 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:o=O) 36 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:p=P) 37 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:q=Q) 38 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:r=R) 39 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:s=S) 40 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:t=T) 41 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:u=U) 42 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:v=V) 43 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:w=W) 44 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:x=X) 45 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:y=Y) 46 | DETOURS_TARGET_PROCESSOR=$(DETOURS_TARGET_PROCESSOR:z=Z) 47 | 48 | !IF "$(DETOURS_TARGET_PROCESSOR)" == "AMD64" 49 | DETOURS_TARGET_PROCESSOR = X64 50 | !ENDIF 51 | 52 | 53 | !if "$(DETOURS_TARGET_PROCESSOR:64=)" == "$(DETOURS_TARGET_PROCESSOR)" 54 | DETOURS_32BIT=1 55 | DETOURS_BITS=32 56 | !else 57 | DETOURS_64BIT=1 58 | DETOURS_BITS=64 59 | !endif 60 | 61 | ########################################## Configure build based on Processor. 62 | ## 63 | ## DETOURS_OPTION_PROCESSOR: Set this macro if the processor *will* run code 64 | ## from another ISA (i.e. x86 on x64). 65 | ## 66 | ## DETOURS_OPTION_BITS: Set this macro if the processor *may* have an 67 | ## an alternative word size. 68 | ## 69 | !IF "$(DETOURS_TARGET_PROCESSOR)" == "X64" 70 | #!MESSAGE Building for 64-bit X64. 71 | DETOURS_SOURCE_BROWSING = 0 72 | DETOURS_OPTION_PROCESSOR=X86 73 | DETOURS_OPTION_BITS=32 74 | !ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "IA64" 75 | #!MESSAGE Building for 64-bit IA64. 76 | DETOURS_OPTION_PROCESSOR=X86 77 | DETOURS_OPTION_BITS=32 78 | !ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "X86" 79 | #!MESSAGE Building for 32-bit X86. 80 | DETOURS_OPTION_BITS=64 81 | # Don't set DETOURS_OPTION_PROCESSOR for x64 because we don't *know* that 82 | # we'll run on a 64-bit machine. 83 | !ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM" 84 | #!MESSAGE Building for 32-bit ARM. 85 | !ELSEIF "$(DETOURS_TARGET_PROCESSOR)" == "ARM64" 86 | #!MESSAGE Building for 64-bit ARM. 87 | !ELSE 88 | !MESSAGE Note: To select the target processor architecture set either 89 | !MESSAGE PROCESSOR_ARCHITECTURE or DETOURS_TARGET_PROCESSOR. 90 | !MESSAGE 91 | !ERROR Unknown target processor: $(DETOURS_TARGET_ARCHITECTURE) 92 | !ENDIF 93 | 94 | ############################################################################## 95 | ## 96 | INCD = $(ROOT)\include 97 | LIBD = $(ROOT)\lib.$(DETOURS_TARGET_PROCESSOR)$(DETOURS_CONFIG) 98 | BIND = $(ROOT)\bin.$(DETOURS_TARGET_PROCESSOR)$(DETOURS_CONFIG) 99 | OBJD = obj.$(DETOURS_TARGET_PROCESSOR)$(DETOURS_CONFIG) 100 | !IF "$(DETOURS_OPTION_PROCESSOR)" != "" 101 | OPTD = $(ROOT)\bin.$(DETOURS_OPTION_PROCESSOR)$(DETOURS_CONFIG) 102 | !ENDIF 103 | 104 | INCDS = $(ROOT)\include 105 | 106 | LIBDS = \ 107 | $(ROOT)\lib.x86$(DETOURS_CONFIG) \ 108 | $(ROOT)\lib.x64$(DETOURS_CONFIG) \ 109 | $(ROOT)\lib.ia64$(DETOURS_CONFIG) \ 110 | $(ROOT)\lib.arm$(DETOURS_CONFIG) \ 111 | $(ROOT)\lib.arm64$(DETOURS_CONFIG) \ 112 | 113 | BINDS = \ 114 | $(ROOT)\bin.x86$(DETOURS_CONFIG) \ 115 | $(ROOT)\bin.x64$(DETOURS_CONFIG) \ 116 | $(ROOT)\bin.ia64$(DETOURS_CONFIG) \ 117 | $(ROOT)\bin.arm$(DETOURS_CONFIG) \ 118 | $(ROOT)\bin.arm64$(DETOURS_CONFIG) \ 119 | 120 | OBJDS = \ 121 | obj.x86$(DETOURS_CONFIG) \ 122 | obj.x64$(DETOURS_CONFIG) \ 123 | obj.ia64$(DETOURS_CONFIG) \ 124 | obj.arm$(DETOURS_CONFIG) \ 125 | obj.arm64$(DETOURS_CONFIG) \ 126 | 127 | ############################################################################## 128 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | !IF "$(CFG)" == "" 2 | CFG=Release32 3 | !MESSAGE No configuration specified. Defaulting to Release32. 4 | !ENDIF 5 | 6 | !IF "$(USE_DETOURS)" == "1" 7 | CFLAGS=/DUSE_DETOURS /IDetours-4.0.1\include 8 | X86_LIBS=Detours-4.0.1\lib.X86\detours.lib 9 | X64_LIBS=Detours-4.0.1\lib.X64\detours.lib 10 | !ELSE 11 | CFLAGS=/DUSE_DEVIARE /Ideviare 12 | X86_LIBS=deviare\NktHookLib.lib 13 | X64_LIBS=deviare\NktHookLib64.lib 14 | !ENDIF 15 | 16 | !IF "$(CFG)" == "Release32" 17 | CFLAGS=/nologo /D_X86_ /EHsc /MT /Ox $(CFLAGS) 18 | LIBS=advapi32.lib secur32.lib user32.lib ws2_32.lib $(X86_LIBS) legacy_stdio_definitions.lib 19 | !ENDIF 20 | 21 | !IF "$(CFG)" == "Release64" 22 | CFLAGS=/nologo /D_AMD64_ /EHsc /MT /Ox $(CFLAGS) 23 | LIBS=advapi32.lib secur32.lib user32.lib ws2_32.lib $(X64_LIBS) 24 | !ENDIF 25 | 26 | all: mstscdump.exe mstschook.dll 27 | 28 | mstscdump.exe: mstscdump.cpp 29 | cl $(CFLAGS) mstscdump.cpp $(LIBS) 30 | 31 | mstschook.dll: mstschook.cpp 32 | cl $(CFLAGS) /LD /Femstschook.dll mstschook.cpp $(LIBS) 33 | 34 | clean: 35 | del /q *.obj 36 | del /q *.exe 37 | del /q *.dll 38 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | mstscdump: MSTSC Packet Dump Utility 2 | ==================================== 3 | 4 | The mstscdump utility allows unencrypted RDP packets being sent or received by 5 | MSTSC.EXE (or any other application that loads MSTSCAX.DLL) to be captured into 6 | a PCAP file for later analysis in various tools such as Microsoft Message Analyzer, 7 | Microsoft Network Monitor, or WireShark. It also demonstrates how to hook into the 8 | ActiveX interfaces exposed by MSTSCAX.DLL. 9 | 10 | 11 | How to use the utility 12 | ---------------------- 13 | 14 | Precompiled binaries for x86 and x64 are provided in the bin\x86 and bin\x64 15 | directories, respectively. Open a Command Prompt window and change directories 16 | to the appropriate directory. Two binaries are provided. 17 | 18 | mstscdump.exe - Main binary for the utility 19 | mstschook.dll - Hook module for hooking MSTSCAX.DLL 20 | 21 | When executed, the utility will create a mstscdump.pcap file containing the 22 | captured packets. This file will get written to the current directory. 23 | 24 | The following examples will cause mstscdump to execute MSTSC.EXE. 25 | 26 | mstscdump - runs MSTSC.EXE with no arguments 27 | mstscdump /v:MikeM-Win2012 - runs MSTSC.EXE with specified arguments 28 | mstscdump MikeM-Win2012.rdp - runs MSTSC.EXE with an RDP file as the argument 29 | 30 | The following example will cause mstscdump to execute VMCONNECT.EXE. 31 | 32 | mstscdump vmconnect localhost MikeM-Win2012 33 | 34 | Any application loading MSTSCAX.DLL can be analyzed by running "mstscdump " 35 | where is the application (plus command line arguments) to be analyzed. 36 | 37 | 38 | Building the utility from sources 39 | --------------------------------- 40 | 41 | A build.bat and Makefile have been provided to assist in building the software 42 | from sources. A proper installation of Visual Studio is required. Visual Studio 43 | 2012 was used for testing purposes. 44 | 45 | To build the software: 46 | 47 | 1. Open a Developer Command Prompt window for Visual Studio. 48 | 2. Change directories to the root directory for mstscdump. 49 | 3. Type "build" to execute the build.bat script. 50 | 51 | Resulting binaries are written to the bin\x86 and bin\x64 directories. 52 | 53 | 54 | Additional Information 55 | ---------------------- 56 | 57 | Feature requests, bug reports, or kudos can be sent to Mike McDonald at 58 | mikem@nogginware.com. 59 | -------------------------------------------------------------------------------- /bin/x64/mstscdump.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nogginware/mstscdump/724ad756c81ed28793213f34d827bd00330db54d/bin/x64/mstscdump.exe -------------------------------------------------------------------------------- /bin/x64/mstschook.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nogginware/mstscdump/724ad756c81ed28793213f34d827bd00330db54d/bin/x64/mstschook.dll -------------------------------------------------------------------------------- /bin/x86/mstscdump.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nogginware/mstscdump/724ad756c81ed28793213f34d827bd00330db54d/bin/x86/mstscdump.exe -------------------------------------------------------------------------------- /bin/x86/mstschook.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nogginware/mstscdump/724ad756c81ed28793213f34d827bd00330db54d/bin/x86/mstschook.dll -------------------------------------------------------------------------------- /build.bat: -------------------------------------------------------------------------------- 1 | @SETLOCAL 2 | 3 | @if "%VCINSTALLDIR%" == "" set VCINSTALLDIR=C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC 4 | 5 | @set USE_DETOURS=1 6 | 7 | @if not exist bin mkdir bin 8 | @if not exist bin\x86 mkdir bin\x86 9 | @if not exist bin\x64 mkdir bin\x64 10 | 11 | @del /q bin\x86\*.* 12 | @del /q bin\x64\*.* 13 | 14 | @echo !== Building MSTSCDUMP.EXE and MSTSCHOOK.DLL (32-bit)... 15 | @call "%VCINSTALLDIR%\Auxiliary\Build\vcvarsall.bat" x86 16 | @set 17 | @nmake /nologo clean all -f Makefile CFG="Release32" USE_DETOURS=%USE_DETOURS% || goto ERROR_EXIT 18 | @copy mstscdump.exe bin\x86 || goto ERROR_EXIT 19 | @copy mstschook.dll bin\x86 || goto ERROR_EXIT 20 | @nmake /nologo clean -f Makefile CFG="Release32" USE_DETOURS=%USE_DETOURS% || goto ERROR_EXIT 21 | 22 | @SETLOCAL 23 | 24 | @echo !== Building MSTSCDUMP.EXE and MSTSCHOOK.DLL (64-bit)... 25 | @call "%VCINSTALLDIR%\Auxiliary\Build\vcvarsall.bat" x64 26 | @nmake /nologo clean all -f Makefile CFG="Release64" USE_DETOURS=%USE_DETOURS% || goto ERROR_EXIT 27 | @copy mstscdump.exe bin\x64 || goto ERROR_EXIT 28 | @copy mstschook.dll bin\x64 || goto ERROR_EXIT 29 | @nmake /nologo clean -f Makefile CFG="Release64" USE_DETOURS=%USE_DETOURS% || goto ERROR_EXIT 30 | 31 | @ENDLOCAL 32 | 33 | :ERROR_EXIT 34 | @ENDLOCAL 35 | exit /b %ERRORLEVEL% -------------------------------------------------------------------------------- /mstscdump.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * mstscdump: MSTSC Packet Dump Utility 3 | * MSTSC Launch and Hook Process 4 | * 5 | * Copyright 2014-2022 Mike McDonald 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #define _CRT_SECURE_NO_WARNINGS 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | BOOL EnableSecurityRights(LPCTSTR DesiredAccess, BOOL bOn) 28 | { 29 | HANDLE hToken; 30 | TOKEN_PRIVILEGES tkp; 31 | 32 | /* Get a token for this process. */ 33 | if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 34 | { 35 | printf("EnableSecurityRights - OpenProcessToken failed (lastError=0x%08x)", GetLastError()); 36 | return FALSE; 37 | } 38 | 39 | /* Get the LUID for the desired privilege. */ 40 | if (!LookupPrivilegeValue(NULL, DesiredAccess, &tkp.Privileges[0].Luid)) 41 | { 42 | printf("EnableSecurityRights - LookupPrivilegeValue failed (lastError=0x%08x)", GetLastError()); 43 | CloseHandle(hToken); 44 | return FALSE; 45 | } 46 | tkp.PrivilegeCount = 1; /* one privilege to set */ 47 | tkp.Privileges[0].Attributes = bOn ? SE_PRIVILEGE_ENABLED : 0; 48 | 49 | /* Get the desired privilege for this process. */ 50 | if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL)) //(PTOKEN_PRIVILEGES) 51 | { 52 | printf("EnableSecurityRights - AdjustTokenPrivileges failed (lastError=0x%08x)", GetLastError()); 53 | CloseHandle(hToken); 54 | return FALSE; 55 | } 56 | 57 | CloseHandle(hToken); 58 | 59 | return TRUE; 60 | } 61 | 62 | BOOL InjectDll(DWORD dwProcessId, LPCSTR pszDllName) 63 | { 64 | BOOL bRetCode = FALSE; 65 | HMODULE hModKernel32 = NULL; 66 | LPVOID pLoadLibraryA = NULL; 67 | HANDLE hProcess = NULL; 68 | HANDLE hThread = NULL; 69 | LPVOID pszArgs = NULL; 70 | DWORD cbArgs; 71 | 72 | if (dwProcessId == 0) return FALSE; 73 | if (pszDllName == NULL) return FALSE; 74 | 75 | try 76 | { 77 | hModKernel32 = GetModuleHandle("KERNEL32.DLL"); 78 | pLoadLibraryA = GetProcAddress(hModKernel32, "LoadLibraryA"); 79 | 80 | EnableSecurityRights(SE_DEBUG_NAME, TRUE); 81 | EnableSecurityRights(SE_TCB_NAME, TRUE); 82 | 83 | // Open the remote process. 84 | hProcess = OpenProcess( 85 | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, 86 | FALSE, 87 | dwProcessId); 88 | if (hProcess == NULL) 89 | { 90 | printf("OpenProcess failed (LastError=%d)\n", GetLastError()); 91 | throw 0; 92 | } 93 | 94 | // Allocate the arguments in the remote process. 95 | cbArgs = lstrlen(pszDllName) + 1; 96 | pszArgs = VirtualAllocEx(hProcess, NULL, cbArgs, MEM_COMMIT, PAGE_READWRITE); 97 | if (pszArgs == NULL) 98 | { 99 | printf("VirtualAllocEx failed (LastError=%d)\n", GetLastError()); 100 | throw 0; 101 | } 102 | WriteProcessMemory(hProcess, pszArgs, pszDllName, cbArgs, NULL); 103 | 104 | // Create the remote thread. 105 | hThread = CreateRemoteThread( 106 | hProcess, 107 | NULL, 108 | 0, 109 | (LPTHREAD_START_ROUTINE)pLoadLibraryA, 110 | pszArgs, 111 | 0, 112 | NULL); 113 | if (hThread == NULL) 114 | { 115 | printf("CreateRemoteThread failed (LastError=%d)\n", GetLastError()); 116 | throw 0; 117 | } 118 | 119 | WaitForSingleObject(hThread, INFINITE); 120 | 121 | bRetCode = TRUE; 122 | } 123 | catch (...) {} 124 | 125 | // Clean up everything. 126 | if (hThread) 127 | { 128 | CloseHandle(hThread); 129 | } 130 | 131 | if (pszArgs) 132 | { 133 | VirtualFreeEx(hProcess, pszArgs, 0, MEM_RELEASE); 134 | } 135 | 136 | if (hProcess) 137 | { 138 | CloseHandle(hProcess); 139 | } 140 | 141 | return bRetCode; 142 | } 143 | 144 | static BOOL IsFile(char *arg) 145 | { 146 | FILE *fp = fopen(arg, "rb"); 147 | if (fp == NULL) return FALSE; 148 | fclose(fp); 149 | 150 | return TRUE; 151 | } 152 | 153 | int main(int argc, char **argv) 154 | { 155 | char szCommandLine[2048]; 156 | STARTUPINFOA StartupInfo; 157 | PROCESS_INFORMATION ProcessInfo; 158 | BOOL fSuccess; 159 | 160 | ZeroMemory(szCommandLine, sizeof(szCommandLine)); 161 | if ((argc == 1) || (argv[1][0] == '/') || IsFile(argv[1])) 162 | { 163 | strcpy(szCommandLine, "mstsc.exe "); 164 | } 165 | for (int i = 1; i < argc; i++) 166 | { 167 | strcat(szCommandLine, argv[i]); 168 | strcat(szCommandLine, " "); 169 | } 170 | 171 | ZeroMemory(&StartupInfo, sizeof(StartupInfo)); 172 | StartupInfo.cb = sizeof(StartupInfo); 173 | 174 | ZeroMemory(&ProcessInfo, sizeof(ProcessInfo)); 175 | 176 | fSuccess = CreateProcessA( 177 | NULL, 178 | szCommandLine, 179 | NULL, 180 | NULL, 181 | FALSE, 182 | CREATE_SUSPENDED, 183 | NULL, 184 | NULL, 185 | &StartupInfo, 186 | &ProcessInfo); 187 | if (!fSuccess) 188 | { 189 | printf("Could not start application (LastError=%d)\n", GetLastError()); 190 | exit(1); 191 | } 192 | InjectDll(ProcessInfo.dwProcessId, "mstschook.dll"); 193 | ResumeThread(ProcessInfo.hThread); 194 | WaitForSingleObject(ProcessInfo.hProcess, INFINITE); 195 | CloseHandle(ProcessInfo.hProcess); 196 | CloseHandle(ProcessInfo.hThread); 197 | 198 | return 0; 199 | } 200 | -------------------------------------------------------------------------------- /mstscdump.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.572 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mstscdump", "mstscdump\mstscdump.vcxproj", "{52C74D9F-C055-4AEB-9972-D443F114805F}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mstschook", "mstschook\mstschook.vcxproj", "{879BC406-82C3-49D8-8C72-0F8B97C04CD1}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|x64 = Debug|x64 13 | Debug|x86 = Debug|x86 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {52C74D9F-C055-4AEB-9972-D443F114805F}.Debug|x64.ActiveCfg = Debug|x64 19 | {52C74D9F-C055-4AEB-9972-D443F114805F}.Debug|x64.Build.0 = Debug|x64 20 | {52C74D9F-C055-4AEB-9972-D443F114805F}.Debug|x86.ActiveCfg = Debug|Win32 21 | {52C74D9F-C055-4AEB-9972-D443F114805F}.Debug|x86.Build.0 = Debug|Win32 22 | {52C74D9F-C055-4AEB-9972-D443F114805F}.Release|x64.ActiveCfg = Release|x64 23 | {52C74D9F-C055-4AEB-9972-D443F114805F}.Release|x64.Build.0 = Release|x64 24 | {52C74D9F-C055-4AEB-9972-D443F114805F}.Release|x86.ActiveCfg = Release|Win32 25 | {52C74D9F-C055-4AEB-9972-D443F114805F}.Release|x86.Build.0 = Release|Win32 26 | {879BC406-82C3-49D8-8C72-0F8B97C04CD1}.Debug|x64.ActiveCfg = Debug|x64 27 | {879BC406-82C3-49D8-8C72-0F8B97C04CD1}.Debug|x64.Build.0 = Debug|x64 28 | {879BC406-82C3-49D8-8C72-0F8B97C04CD1}.Debug|x86.ActiveCfg = Debug|Win32 29 | {879BC406-82C3-49D8-8C72-0F8B97C04CD1}.Debug|x86.Build.0 = Debug|Win32 30 | {879BC406-82C3-49D8-8C72-0F8B97C04CD1}.Release|x64.ActiveCfg = Release|x64 31 | {879BC406-82C3-49D8-8C72-0F8B97C04CD1}.Release|x64.Build.0 = Release|x64 32 | {879BC406-82C3-49D8-8C72-0F8B97C04CD1}.Release|x86.ActiveCfg = Release|Win32 33 | {879BC406-82C3-49D8-8C72-0F8B97C04CD1}.Release|x86.Build.0 = Release|Win32 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | GlobalSection(ExtensibilityGlobals) = postSolution 39 | SolutionGuid = {362406B8-A736-40C1-BC43-E2CE59C1D3CE} 40 | EndGlobalSection 41 | EndGlobal 42 | -------------------------------------------------------------------------------- /mstscdump/mstscdump.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 15.0 26 | {52C74D9F-C055-4AEB-9972-D443F114805F} 27 | Win32Proj 28 | mstscdump 29 | 10.0.17763.0 30 | 31 | 32 | 33 | Application 34 | true 35 | v141 36 | MultiByte 37 | 38 | 39 | Application 40 | false 41 | v141 42 | true 43 | MultiByte 44 | 45 | 46 | Application 47 | true 48 | v141 49 | MultiByte 50 | 51 | 52 | Application 53 | false 54 | v141 55 | true 56 | MultiByte 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | true 78 | $(PlatformTarget)\$(Configuration)\ 79 | $(PlatformTarget)\$(Configuration)\ 80 | 81 | 82 | true 83 | $(PlatformTarget)\$(Configuration)\ 84 | $(PlatformTarget)\$(Configuration)\ 85 | 86 | 87 | false 88 | $(PlatformTarget)\$(Configuration)\ 89 | $(PlatformTarget)\$(Configuration)\ 90 | 91 | 92 | false 93 | $(PlatformTarget)\$(Configuration)\ 94 | $(PlatformTarget)\$(Configuration)\ 95 | 96 | 97 | 98 | NotUsing 99 | Level3 100 | Disabled 101 | true 102 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 103 | true 104 | pch.h 105 | MultiThreadedDebug 106 | 107 | 108 | Console 109 | true 110 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 111 | 112 | 113 | copy /y $(PlatformTarget)\$(Configuration)\mstscdump.exe $(SolutionDir)\bin\$(PlatformTarget) 114 | 115 | 116 | 117 | 118 | NotUsing 119 | Level3 120 | Disabled 121 | true 122 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 123 | true 124 | pch.h 125 | MultiThreadedDebug 126 | 127 | 128 | Console 129 | true 130 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 131 | 132 | 133 | copy /y $(PlatformTarget)\$(Configuration)\mstscdump.exe $(SolutionDir)\bin\$(PlatformTarget) 134 | 135 | 136 | 137 | 138 | NotUsing 139 | Level3 140 | MaxSpeed 141 | true 142 | true 143 | true 144 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 145 | true 146 | pch.h 147 | MultiThreaded 148 | 149 | 150 | Console 151 | true 152 | true 153 | true 154 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 155 | 156 | 157 | copy /y $(PlatformTarget)\$(Configuration)\mstscdump.exe $(SolutionDir)\bin\$(PlatformTarget) 158 | 159 | 160 | 161 | 162 | NotUsing 163 | Level3 164 | MaxSpeed 165 | true 166 | true 167 | true 168 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 169 | true 170 | pch.h 171 | MultiThreaded 172 | 173 | 174 | Console 175 | true 176 | true 177 | true 178 | kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 179 | 180 | 181 | copy /y $(PlatformTarget)\$(Configuration)\mstscdump.exe $(SolutionDir)\bin\$(PlatformTarget) 182 | 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /mstscdump/mstscdump.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /mstschook/mstschook.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 15.0 26 | {879BC406-82C3-49D8-8C72-0F8B97C04CD1} 27 | Win32Proj 28 | mstschook 29 | 10.0.17763.0 30 | 31 | 32 | 33 | DynamicLibrary 34 | true 35 | v141 36 | MultiByte 37 | 38 | 39 | DynamicLibrary 40 | false 41 | v141 42 | true 43 | MultiByte 44 | 45 | 46 | DynamicLibrary 47 | true 48 | v141 49 | MultiByte 50 | 51 | 52 | DynamicLibrary 53 | false 54 | v141 55 | true 56 | MultiByte 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | true 78 | $(PlatformTarget)\$(Configuration)\ 79 | $(PlatformTarget)\$(Configuration)\ 80 | 81 | 82 | true 83 | $(PlatformTarget)\$(Configuration)\ 84 | $(PlatformTarget)\$(Configuration)\ 85 | 86 | 87 | false 88 | $(PlatformTarget)\$(Configuration)\ 89 | $(PlatformTarget)\$(Configuration)\ 90 | 91 | 92 | false 93 | $(PlatformTarget)\$(Configuration)\ 94 | $(PlatformTarget)\$(Configuration)\ 95 | 96 | 97 | 98 | NotUsing 99 | Level3 100 | Disabled 101 | true 102 | USE_DETOURS;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 103 | true 104 | MultiThreadedDebug 105 | $(SolutionDir)Detours-4.0.1\include 106 | 107 | 108 | Windows 109 | true 110 | $(SolutionDir)Detours-4.0.1\lib.X64\detours.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 111 | 112 | 113 | copy /y $(PlatformTarget)\$(Configuration)\mstschook.dll $(SolutionDir)\bin\$(PlatformTarget) 114 | 115 | 116 | 117 | 118 | NotUsing 119 | Level3 120 | Disabled 121 | true 122 | USE_DETOURS;WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 123 | true 124 | MultiThreadedDebug 125 | $(SolutionDir)Detours-4.0.1\include 126 | 127 | 128 | Windows 129 | true 130 | $(SolutionDir)Detours-4.0.1\lib.X86\detours.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 131 | 132 | 133 | copy /y $(PlatformTarget)\$(Configuration)\mstschook.dll $(SolutionDir)\bin\$(PlatformTarget) 134 | 135 | 136 | 137 | 138 | NotUsing 139 | Level3 140 | MaxSpeed 141 | true 142 | true 143 | true 144 | USE_DETOURS;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 145 | true 146 | MultiThreaded 147 | $(SolutionDir)Detours-4.0.1\include 148 | 149 | 150 | Windows 151 | true 152 | true 153 | true 154 | $(SolutionDir)Detours-4.0.1\lib.X86\detours.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 155 | 156 | 157 | copy /y $(PlatformTarget)\$(Configuration)\mstschook.dll $(SolutionDir)\bin\$(PlatformTarget) 158 | 159 | 160 | 161 | 162 | NotUsing 163 | Level3 164 | MaxSpeed 165 | true 166 | true 167 | true 168 | USE_DETOURS;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 169 | true 170 | MultiThreaded 171 | $(SolutionDir)Detours-4.0.1\include 172 | 173 | 174 | Windows 175 | true 176 | true 177 | true 178 | $(SolutionDir)Detours-4.0.1\lib.X64\detours.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) 179 | 180 | 181 | copy /y $(PlatformTarget)\$(Configuration)\mstschook.dll $(SolutionDir)\bin\$(PlatformTarget) 182 | 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /mstschook/mstschook.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | --------------------------------------------------------------------------------