X64 transport [Part 5] (Update plugins.cpp)
[xy_vsfilter.git] / include / detours / detours.h
blob3c0ce910f9472b9ecb505ee3d1bbd300b067ba6f
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // File: detours.h
4 // Module: detours.lib
5 //
6 // Detours for binary functions. Version 1.5 (Build 46)
7 //
8 // Copyright 1995-2001, Microsoft Corporation
9 //
11 #pragma once
12 #ifndef _DETOURS_H_
13 #define _DETOURS_H_
15 #pragma comment(lib, "detours")
17 //////////////////////////////////////////////////////////////////////////////
19 #ifndef GUID_DEFINED
20 #define GUID_DEFINED
21 typedef struct _GUID
23 DWORD Data1;
24 WORD Data2;
25 WORD Data3;
26 BYTE Data4[ 8 ];
27 } GUID;
28 #endif // !GUID_DEFINED
30 #if defined(__cplusplus)
31 #ifndef _REFGUID_DEFINED
32 #define _REFGUID_DEFINED
33 #define REFGUID const GUID &
34 #endif // !_REFGUID_DEFINED
35 #else // !__cplusplus
36 #ifndef _REFGUID_DEFINED
37 #define _REFGUID_DEFINED
38 #define REFGUID const GUID * const
39 #endif // !_REFGUID_DEFINED
40 #endif // !__cplusplus
42 //////////////////////////////////////////////////////////////////////////////
44 #ifdef __cplusplus
45 extern "C" {
46 #endif // __cplusplus
48 /////////////////////////////////////////////////// Instruction Target Macros.
50 #define DETOUR_INSTRUCTION_TARGET_NONE ((PBYTE)0)
51 #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PBYTE)~0ul)
53 /////////////////////////////////////////////////////////// Trampoline Macros.
55 // DETOUR_TRAMPOLINE(trampoline_prototype, target_name)
57 // The naked trampoline must be at least DETOUR_TRAMPOLINE_SIZE bytes.
59 #define DETOUR_TRAMPOLINE_SIZE 32
60 #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0"
62 #define DETOUR_TRAMPOLINE(trampoline,target) \
63 static PVOID __fastcall _Detours_GetVA_##target(VOID) \
64 { \
65 return ⌖ \
66 } \
68 __declspec(naked) trampoline \
69 { \
70 __asm { nop };\
71 __asm { nop };\
72 __asm { call _Detours_GetVA_##target };\
73 __asm { jmp eax };\
74 __asm { ret };\
75 __asm { nop };\
76 __asm { nop };\
77 __asm { nop };\
78 __asm { nop };\
79 __asm { nop };\
80 __asm { nop };\
81 __asm { nop };\
82 __asm { nop };\
83 __asm { nop };\
84 __asm { nop };\
85 __asm { nop };\
86 __asm { nop };\
87 __asm { nop };\
88 __asm { nop };\
89 __asm { nop };\
90 __asm { nop };\
91 __asm { nop };\
92 __asm { nop };\
93 __asm { nop };\
94 __asm { nop };\
95 __asm { nop };\
96 __asm { nop };\
99 #define DETOUR_TRAMPOLINE_EMPTY(trampoline) \
100 __declspec(naked) trampoline \
102 __asm { nop };\
103 __asm { nop };\
104 __asm { xor eax, eax };\
105 __asm { mov eax, [eax] };\
106 __asm { ret };\
107 __asm { nop };\
108 __asm { nop };\
109 __asm { nop };\
110 __asm { nop };\
111 __asm { nop };\
112 __asm { nop };\
113 __asm { nop };\
114 __asm { nop };\
115 __asm { nop };\
116 __asm { nop };\
117 __asm { nop };\
118 __asm { nop };\
119 __asm { nop };\
120 __asm { nop };\
121 __asm { nop };\
122 __asm { nop };\
123 __asm { nop };\
124 __asm { nop };\
125 __asm { nop };\
126 __asm { nop };\
127 __asm { nop };\
128 __asm { nop };\
129 __asm { nop };\
130 __asm { nop };\
131 __asm { nop };\
134 /////////////////////////////////////////////////////////// Binary Structures.
136 #pragma pack(push, 8)
137 typedef struct _DETOUR_SECTION_HEADER
139 DWORD cbHeaderSize;
140 DWORD nSignature;
141 DWORD nDataOffset;
142 DWORD cbDataSize;
144 DWORD nOriginalImportVirtualAddress;
145 DWORD nOriginalImportSize;
146 DWORD nOriginalBoundImportVirtualAddress;
147 DWORD nOriginalBoundImportSize;
149 DWORD nOriginalIatVirtualAddress;
150 DWORD nOriginalIatSize;
151 DWORD nOriginalSizeOfImage;
152 DWORD nReserve;
153 } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER;
155 typedef struct _DETOUR_SECTION_RECORD
157 DWORD cbBytes;
158 DWORD nReserved;
159 GUID guid;
160 } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD;
161 #pragma pack(pop)
163 #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \
165 sizeof(DETOUR_SECTION_HEADER),\
166 DETOUR_SECTION_HEADER_SIGNATURE,\
167 sizeof(DETOUR_SECTION_HEADER),\
168 (cbSectionSize),\
181 ///////////////////////////////////////////////////////////// Binary Typedefs.
183 typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)(PVOID pContext,
184 PCHAR pszFile,
185 PCHAR *ppszOutFile);
186 typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)(PVOID pContext,
187 PCHAR pszOrigFile,
188 PCHAR pszFile,
189 PCHAR *ppszOutFile);
190 typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)(PVOID pContext,
191 DWORD nOrdinal,
192 PCHAR pszOrigSymbol,
193 PCHAR pszSymbol,
194 PCHAR *ppszOutSymbol);
195 typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FINAL_CALLBACK)(PVOID pContext);
196 typedef BOOL (CALLBACK *PF_DETOUR_BINARY_EXPORT_CALLBACK)(PVOID pContext,
197 DWORD nOrdinal,
198 PCHAR pszName,
199 PBYTE pbCode);
201 typedef VOID * PDETOUR_BINARY;
202 typedef VOID * PDETOUR_LOADED_BINARY;
204 //////////////////////////////////////////////////////// Trampoline Functions.
206 PBYTE WINAPI DetourFunction(PBYTE pbTargetFunction,
207 PBYTE pbDetourFunction);
209 BOOL WINAPI DetourFunctionWithEmptyTrampoline(PBYTE pbTrampoline,
210 PBYTE pbTarget,
211 PBYTE pbDetour);
213 BOOL WINAPI DetourFunctionWithEmptyTrampolineEx(PBYTE pbTrampoline,
214 PBYTE pbTarget,
215 PBYTE pbDetour,
216 PBYTE *ppbRealTrampoline,
217 PBYTE *ppbRealTarget,
218 PBYTE *ppbRealDetour);
220 BOOL WINAPI DetourFunctionWithTrampoline(PBYTE pbTrampoline,
221 PBYTE pbDetour);
223 BOOL WINAPI DetourFunctionWithTrampolineEx(PBYTE pbTrampoline,
224 PBYTE pbDetour,
225 PBYTE *ppbRealTrampoline,
226 PBYTE *ppbRealTarget);
228 BOOL WINAPI DetourRemove(PBYTE pbTrampoline, PBYTE pbDetour);
230 ////////////////////////////////////////////////////////////// Code Functions.
232 PBYTE WINAPI DetourFindFunction(PCHAR pszModule, PCHAR pszFunction);
233 PBYTE WINAPI DetourGetFinalCode(PBYTE pbCode, BOOL fSkipJmp);
235 PBYTE WINAPI DetourCopyInstruction(PBYTE pbDst, PBYTE pbSrc, PBYTE *ppbTarget);
236 PBYTE WINAPI DetourCopyInstructionEx(PBYTE pbDst,
237 PBYTE pbSrc,
238 PBYTE *ppbTarget,
239 LONG *plExtra);
241 ///////////////////////////////////////////////////// Loaded Binary Functions.
243 HMODULE WINAPI DetourEnumerateModules(HMODULE hModuleLast);
244 PBYTE WINAPI DetourGetEntryPoint(HMODULE hModule);
245 BOOL WINAPI DetourEnumerateExports(HMODULE hModule,
246 PVOID pContext,
247 PF_DETOUR_BINARY_EXPORT_CALLBACK pfExport);
249 PBYTE WINAPI DetourFindPayload(HMODULE hModule, REFGUID rguid, DWORD *pcbData);
250 DWORD WINAPI DetourGetSizeOfPayloads(HMODULE hModule);
252 ///////////////////////////////////////////////// Persistent Binary Functions.
254 BOOL WINAPI DetourBinaryBindA(PCHAR pszFile, PCHAR pszDll, PCHAR pszPath);
255 BOOL WINAPI DetourBinaryBindW(PWCHAR pwzFile, PWCHAR pwzDll, PWCHAR pwzPath);
256 #ifdef UNICODE
257 #define DetourBinaryBind DetourBinaryBindW
258 #else
259 #define DetourBinaryBind DetourBinaryBindA
260 #endif // !UNICODE
262 PDETOUR_BINARY WINAPI DetourBinaryOpen(HANDLE hFile);
263 PBYTE WINAPI DetourBinaryEnumeratePayloads(PDETOUR_BINARY pBinary,
264 GUID *pGuid,
265 DWORD *pcbData,
266 DWORD *pnIterator);
267 PBYTE WINAPI DetourBinaryFindPayload(PDETOUR_BINARY pBinary,
268 REFGUID rguid,
269 DWORD *pcbData);
270 PBYTE WINAPI DetourBinarySetPayload(PDETOUR_BINARY pBinary,
271 REFGUID rguid,
272 PBYTE pbData,
273 DWORD cbData);
274 BOOL WINAPI DetourBinaryDeletePayload(PDETOUR_BINARY pBinary, REFGUID rguid);
275 BOOL WINAPI DetourBinaryPurgePayloads(PDETOUR_BINARY pBinary);
276 BOOL WINAPI DetourBinaryResetImports(PDETOUR_BINARY pBinary);
277 BOOL WINAPI DetourBinaryEditImports(PDETOUR_BINARY pBinary,
278 PVOID pContext,
279 PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway,
280 PF_DETOUR_BINARY_FILE_CALLBACK pfFile,
281 PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol,
282 PF_DETOUR_BINARY_FINAL_CALLBACK pfFinal);
283 BOOL WINAPI DetourBinaryWrite(PDETOUR_BINARY pBinary, HANDLE hFile);
284 BOOL WINAPI DetourBinaryClose(PDETOUR_BINARY pBinary);
286 /////////////////////////////////////////////// First Chance Exception Filter.
288 LPTOP_LEVEL_EXCEPTION_FILTER WINAPI
289 DetourFirstChanceExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelFilter);
291 ///////////////////////////////////////////////// Create Process & Inject Dll.
293 typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)
294 (LPCSTR lpApplicationName,
295 LPSTR lpCommandLine,
296 LPSECURITY_ATTRIBUTES lpProcessAttributes,
297 LPSECURITY_ATTRIBUTES lpThreadAttributes,
298 BOOL bInheritHandles,
299 DWORD dwCreationFlags,
300 LPVOID lpEnvironment,
301 LPCSTR lpCurrentDirectory,
302 LPSTARTUPINFOA lpStartupInfo,
303 LPPROCESS_INFORMATION lpProcessInformation);
305 typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)
306 (LPCWSTR lpApplicationName,
307 LPWSTR lpCommandLine,
308 LPSECURITY_ATTRIBUTES lpProcessAttributes,
309 LPSECURITY_ATTRIBUTES lpThreadAttributes,
310 BOOL bInheritHandles,
311 DWORD dwCreationFlags,
312 LPVOID lpEnvironment,
313 LPCWSTR lpCurrentDirectory,
314 LPSTARTUPINFOW lpStartupInfo,
315 LPPROCESS_INFORMATION lpProcessInformation);
317 BOOL WINAPI DetourCreateProcessWithDllA(LPCSTR lpApplicationName,
318 LPSTR lpCommandLine,
319 LPSECURITY_ATTRIBUTES lpProcessAttributes,
320 LPSECURITY_ATTRIBUTES lpThreadAttributes,
321 BOOL bInheritHandles,
322 DWORD dwCreationFlags,
323 LPVOID lpEnvironment,
324 LPCSTR lpCurrentDirectory,
325 LPSTARTUPINFOA lpStartupInfo,
326 LPPROCESS_INFORMATION lpProcessInformation,
327 LPCSTR lpDllName,
328 PDETOUR_CREATE_PROCESS_ROUTINEA
329 pfCreateProcessA);
331 BOOL WINAPI DetourCreateProcessWithDllW(LPCWSTR lpApplicationName,
332 LPWSTR lpCommandLine,
333 LPSECURITY_ATTRIBUTES lpProcessAttributes,
334 LPSECURITY_ATTRIBUTES lpThreadAttributes,
335 BOOL bInheritHandles,
336 DWORD dwCreationFlags,
337 LPVOID lpEnvironment,
338 LPCWSTR lpCurrentDirectory,
339 LPSTARTUPINFOW lpStartupInfo,
340 LPPROCESS_INFORMATION lpProcessInformation,
341 LPCWSTR lpDllName,
342 PDETOUR_CREATE_PROCESS_ROUTINEW
343 pfCreateProcessW);
345 #ifdef UNICODE
346 #define DetourCreateProcessWithDll DetourCreateProcessWithDllW
347 #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW
348 #else
349 #define DetourCreateProcessWithDll DetourCreateProcessWithDllA
350 #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA
351 #endif // !UNICODE
353 BOOL WINAPI DetourContinueProcessWithDllA(HANDLE hProcess, LPCSTR lpDllName);
354 BOOL WINAPI DetourContinueProcessWithDllW(HANDLE hProcess, LPCWSTR lpDllName);
356 #ifdef UNICODE
357 #define DetourContinueProcessWithDll DetourContinueProcessWithDllW
358 #else
359 #define DetourContinueProcessWithDll DetourContinueProcessWithDllA
360 #endif // !UNICODE
362 //////////////////////////////////////////////////////////////////////////////
363 #ifdef __cplusplus
365 #endif // __cplusplus
367 /////////////////////////////////////////////////////////////////// Old Names.
369 #define ContinueProcessWithDll DetourContinueProcessWithDll
370 #define ContinueProcessWithDllA DetourContinueProcessWithDllA
371 #define ContinueProcessWithDllW DetourContinueProcessWithDllW
372 #define CreateProcessWithDll DetourCreateProcessWithDll
373 #define CreateProcessWithDllA DetourCreateProcessWithDllA
374 #define CreateProcessWithDllW DetourCreateProcessWithDllW
375 #define DETOUR_TRAMPOLINE_WO_TARGET DETOUR_TRAMPOLINE_EMPTY
376 #define DetourBinaryPurgePayload DetourBinaryPurgePayloads
377 #define DetourEnumerateExportsForInstance DetourEnumerateExports
378 #define DetourEnumerateInstances DetourEnumerateModules
379 #define DetourFindEntryPointForInstance DetourGetEntryPoint
380 #define DetourFindFinalCode DetourGetFinalCode
381 #define DetourFindPayloadInBinary DetourFindPayload
382 #define DetourGetSizeOfBinary DetourGetSizeOfPayloads
383 #define DetourRemoveWithTrampoline DetourRemove
384 #define PCREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINE
385 #define PCREATE_PROCESS_ROUTINEA PDETOUR_CREATE_PROCESS_ROUTINEA
386 #define PCREATE_PROCESS_ROUTINEW PDETOUR_CREATE_PROCESS_ROUTINEW
389 //////////////////////////////////////////////// Detours Internal Definitions.
391 #ifdef __cplusplus
392 #ifdef DETOURS_INTERNAL
394 //////////////////////////////////////////////////////////////////////////////
396 #ifdef IMAGEAPI // defined by IMAGEHLP.H
397 typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(LPAPI_VERSION AppVersion);
399 typedef BOOL (NTAPI *PF_SymInitialize)(IN HANDLE hProcess,
400 IN LPSTR UserSearchPath,
401 IN BOOL fInvadeProcess);
402 typedef DWORD (NTAPI *PF_SymSetOptions)(IN DWORD SymOptions);
403 typedef DWORD (NTAPI *PF_SymGetOptions)(VOID);
404 typedef BOOL (NTAPI *PF_SymLoadModule)(IN HANDLE hProcess,
405 IN HANDLE hFile,
406 IN PSTR ImageName,
407 IN PSTR ModuleName,
408 IN DWORD BaseOfDll,
409 IN DWORD SizeOfDll);
410 typedef BOOL (NTAPI *PF_SymGetModuleInfo)(IN HANDLE hProcess,
411 IN DWORD dwAddr,
412 OUT PIMAGEHLP_MODULE ModuleInfo);
413 typedef BOOL (NTAPI *PF_SymGetSymFromName)(IN HANDLE hProcess,
414 IN LPSTR Name,
415 OUT PIMAGEHLP_SYMBOL Symbol);
416 typedef BOOL (NTAPI *PF_BindImage)(IN LPSTR pszImageName,
417 IN LPSTR pszDllPath,
418 IN LPSTR pszSymbolPath);
420 typedef struct _DETOUR_SYM_INFO
422 HANDLE hProcess;
423 HMODULE hImageHlp;
424 PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx;
425 PF_SymInitialize pfSymInitialize;
426 PF_SymSetOptions pfSymSetOptions;
427 PF_SymGetOptions pfSymGetOptions;
428 PF_SymLoadModule pfSymLoadModule;
429 PF_SymGetModuleInfo pfSymGetModuleInfo;
430 PF_SymGetSymFromName pfSymGetSymFromName;
431 PF_BindImage pfBindImage;
432 } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO;
434 PDETOUR_SYM_INFO DetourLoadImageHlp(VOID);
436 #endif // IMAGEAPI
438 //////////////////////////////////////////////////////////////////////////////
440 class CDetourEnableWriteOnCodePage
442 public:
443 CDetourEnableWriteOnCodePage(PBYTE pbCode, LONG cbCode = DETOUR_TRAMPOLINE_SIZE)
445 m_pbCode = pbCode;
446 m_cbCode = cbCode;
447 m_dwOldPerm = 0;
448 m_hProcess = GetCurrentProcess();
450 if (m_pbCode && m_cbCode) {
451 if (!FlushInstructionCache(m_hProcess, pbCode, cbCode)) {
452 return;
454 if (!VirtualProtect(pbCode,
455 cbCode,
456 PAGE_EXECUTE_READWRITE,
457 &m_dwOldPerm)) {
458 return;
463 ~CDetourEnableWriteOnCodePage()
465 if (m_dwOldPerm && m_pbCode && m_cbCode) {
466 DWORD dwTemp = 0;
467 if (!FlushInstructionCache(m_hProcess, m_pbCode, m_cbCode)) {
468 return;
470 if (!VirtualProtect(m_pbCode, m_cbCode, m_dwOldPerm, &dwTemp)) {
471 return;
476 BOOL SetPermission(DWORD dwPerms)
478 if (m_dwOldPerm && m_pbCode && m_cbCode) {
479 m_dwOldPerm = dwPerms;
480 return TRUE;
482 return FALSE;
485 BOOL IsValid(VOID)
487 return m_pbCode && m_cbCode && m_dwOldPerm;
490 private:
491 HANDLE m_hProcess;
492 PBYTE m_pbCode;
493 LONG m_cbCode;
494 DWORD m_dwOldPerm;
497 //////////////////////////////////////////////////////////////////////////////
499 inline PBYTE DetourGenMovEax(PBYTE pbCode, UINT32 nValue)
501 *pbCode++ = 0xB8;
502 *((UINT32*&)pbCode)++ = nValue;
503 return pbCode;
506 inline PBYTE DetourGenMovEbx(PBYTE pbCode, UINT32 nValue)
508 *pbCode++ = 0xBB;
509 *((UINT32*&)pbCode)++ = nValue;
510 return pbCode;
513 inline PBYTE DetourGenMovEcx(PBYTE pbCode, UINT32 nValue)
515 *pbCode++ = 0xB9;
516 *((UINT32*&)pbCode)++ = nValue;
517 return pbCode;
520 inline PBYTE DetourGenMovEdx(PBYTE pbCode, UINT32 nValue)
522 *pbCode++ = 0xBA;
523 *((UINT32*&)pbCode)++ = nValue;
524 return pbCode;
527 inline PBYTE DetourGenMovEsi(PBYTE pbCode, UINT32 nValue)
529 *pbCode++ = 0xBE;
530 *((UINT32*&)pbCode)++ = nValue;
531 return pbCode;
534 inline PBYTE DetourGenMovEdi(PBYTE pbCode, UINT32 nValue)
536 *pbCode++ = 0xBF;
537 *((UINT32*&)pbCode)++ = nValue;
538 return pbCode;
541 inline PBYTE DetourGenMovEbp(PBYTE pbCode, UINT32 nValue)
543 *pbCode++ = 0xBD;
544 *((UINT32*&)pbCode)++ = nValue;
545 return pbCode;
548 inline PBYTE DetourGenMovEsp(PBYTE pbCode, UINT32 nValue)
550 *pbCode++ = 0xBC;
551 *((UINT32*&)pbCode)++ = nValue;
552 return pbCode;
555 inline PBYTE DetourGenPush(PBYTE pbCode, UINT32 nValue)
557 *pbCode++ = 0x68;
558 *((UINT32*&)pbCode)++ = nValue;
559 return pbCode;
562 inline PBYTE DetourGenPushad(PBYTE pbCode)
564 *pbCode++ = 0x60;
565 return pbCode;
568 inline PBYTE DetourGenPopad(PBYTE pbCode)
570 *pbCode++ = 0x61;
571 return pbCode;
574 inline PBYTE DetourGenJmp(PBYTE pbCode, PBYTE pbJmpDst, PBYTE pbJmpSrc = 0)
576 if (pbJmpSrc == 0) {
577 pbJmpSrc = pbCode;
579 *pbCode++ = 0xE9;
580 *((INT32*&)pbCode)++ = pbJmpDst - (pbJmpSrc + 5);
581 return pbCode;
584 inline PBYTE DetourGenCall(PBYTE pbCode, PBYTE pbJmpDst, PBYTE pbJmpSrc = 0)
586 if (pbJmpSrc == 0) {
587 pbJmpSrc = pbCode;
589 *pbCode++ = 0xE8;
590 *((INT32*&)pbCode)++ = pbJmpDst - (pbJmpSrc + 5);
591 return pbCode;
594 inline PBYTE DetourGenBreak(PBYTE pbCode)
596 *pbCode++ = 0xcc;
597 return pbCode;
600 inline PBYTE DetourGenRet(PBYTE pbCode)
602 *pbCode++ = 0xc3;
603 return pbCode;
606 inline PBYTE DetourGenNop(PBYTE pbCode)
608 *pbCode++ = 0x90;
609 return pbCode;
611 #endif DETOURS_INTERAL
612 #endif // __cplusplus
614 #endif // _DETOURS_H_
616 //////////////////////////////////////////////////////////////// End of File.