1 //////////////////////////////////////////////////////////////////////////////
6 // Detours for binary functions. Version 1.5 (Build 46)
8 // Copyright 1995-2001, Microsoft Corporation
15 #pragma comment(lib, "detours")
17 //////////////////////////////////////////////////////////////////////////////
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
36 #ifndef _REFGUID_DEFINED
37 #define _REFGUID_DEFINED
38 #define REFGUID const GUID * const
39 #endif // !_REFGUID_DEFINED
40 #endif // !__cplusplus
42 //////////////////////////////////////////////////////////////////////////////
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) \
68 __declspec(naked) trampoline \
72 __asm { call _Detours_GetVA_##target };\
99 #define DETOUR_TRAMPOLINE_EMPTY(trampoline) \
100 __declspec(naked) trampoline \
104 __asm { xor eax, eax };\
105 __asm { mov eax, [eax] };\
134 /////////////////////////////////////////////////////////// Binary Structures.
136 #pragma pack(push, 8)
137 typedef struct _DETOUR_SECTION_HEADER
144 DWORD nOriginalImportVirtualAddress
;
145 DWORD nOriginalImportSize
;
146 DWORD nOriginalBoundImportVirtualAddress
;
147 DWORD nOriginalBoundImportSize
;
149 DWORD nOriginalIatVirtualAddress
;
150 DWORD nOriginalIatSize
;
151 DWORD nOriginalSizeOfImage
;
153 } DETOUR_SECTION_HEADER
, *PDETOUR_SECTION_HEADER
;
155 typedef struct _DETOUR_SECTION_RECORD
160 } DETOUR_SECTION_RECORD
, *PDETOUR_SECTION_RECORD
;
163 #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \
165 sizeof(DETOUR_SECTION_HEADER),\
166 DETOUR_SECTION_HEADER_SIGNATURE,\
167 sizeof(DETOUR_SECTION_HEADER),\
181 ///////////////////////////////////////////////////////////// Binary Typedefs.
183 typedef BOOL (CALLBACK
*PF_DETOUR_BINARY_BYWAY_CALLBACK
)(PVOID pContext
,
186 typedef BOOL (CALLBACK
*PF_DETOUR_BINARY_FILE_CALLBACK
)(PVOID pContext
,
190 typedef BOOL (CALLBACK
*PF_DETOUR_BINARY_SYMBOL_CALLBACK
)(PVOID pContext
,
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
,
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
,
213 BOOL WINAPI
DetourFunctionWithEmptyTrampolineEx(PBYTE pbTrampoline
,
216 PBYTE
*ppbRealTrampoline
,
217 PBYTE
*ppbRealTarget
,
218 PBYTE
*ppbRealDetour
);
220 BOOL WINAPI
DetourFunctionWithTrampoline(PBYTE pbTrampoline
,
223 BOOL WINAPI
DetourFunctionWithTrampolineEx(PBYTE pbTrampoline
,
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
,
241 ///////////////////////////////////////////////////// Loaded Binary Functions.
243 HMODULE WINAPI
DetourEnumerateModules(HMODULE hModuleLast
);
244 PBYTE WINAPI
DetourGetEntryPoint(HMODULE hModule
);
245 BOOL WINAPI
DetourEnumerateExports(HMODULE hModule
,
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
);
257 #define DetourBinaryBind DetourBinaryBindW
259 #define DetourBinaryBind DetourBinaryBindA
262 PDETOUR_BINARY WINAPI
DetourBinaryOpen(HANDLE hFile
);
263 PBYTE WINAPI
DetourBinaryEnumeratePayloads(PDETOUR_BINARY pBinary
,
267 PBYTE WINAPI
DetourBinaryFindPayload(PDETOUR_BINARY pBinary
,
270 PBYTE WINAPI
DetourBinarySetPayload(PDETOUR_BINARY pBinary
,
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
,
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
,
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
,
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
,
328 PDETOUR_CREATE_PROCESS_ROUTINEA
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
,
342 PDETOUR_CREATE_PROCESS_ROUTINEW
346 #define DetourCreateProcessWithDll DetourCreateProcessWithDllW
347 #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW
349 #define DetourCreateProcessWithDll DetourCreateProcessWithDllA
350 #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA
353 BOOL WINAPI
DetourContinueProcessWithDllA(HANDLE hProcess
, LPCSTR lpDllName
);
354 BOOL WINAPI
DetourContinueProcessWithDllW(HANDLE hProcess
, LPCWSTR lpDllName
);
357 #define DetourContinueProcessWithDll DetourContinueProcessWithDllW
359 #define DetourContinueProcessWithDll DetourContinueProcessWithDllA
362 //////////////////////////////////////////////////////////////////////////////
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.
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
,
410 typedef BOOL (NTAPI
*PF_SymGetModuleInfo
)(IN HANDLE hProcess
,
412 OUT PIMAGEHLP_MODULE ModuleInfo
);
413 typedef BOOL (NTAPI
*PF_SymGetSymFromName
)(IN HANDLE hProcess
,
415 OUT PIMAGEHLP_SYMBOL Symbol
);
416 typedef BOOL (NTAPI
*PF_BindImage
)(IN LPSTR pszImageName
,
418 IN LPSTR pszSymbolPath
);
420 typedef struct _DETOUR_SYM_INFO
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
);
438 //////////////////////////////////////////////////////////////////////////////
440 class CDetourEnableWriteOnCodePage
443 CDetourEnableWriteOnCodePage(PBYTE pbCode
, LONG cbCode
= DETOUR_TRAMPOLINE_SIZE
)
448 m_hProcess
= GetCurrentProcess();
450 if (m_pbCode
&& m_cbCode
) {
451 if (!FlushInstructionCache(m_hProcess
, pbCode
, cbCode
)) {
454 if (!VirtualProtect(pbCode
,
456 PAGE_EXECUTE_READWRITE
,
463 ~CDetourEnableWriteOnCodePage()
465 if (m_dwOldPerm
&& m_pbCode
&& m_cbCode
) {
467 if (!FlushInstructionCache(m_hProcess
, m_pbCode
, m_cbCode
)) {
470 if (!VirtualProtect(m_pbCode
, m_cbCode
, m_dwOldPerm
, &dwTemp
)) {
476 BOOL
SetPermission(DWORD dwPerms
)
478 if (m_dwOldPerm
&& m_pbCode
&& m_cbCode
) {
479 m_dwOldPerm
= dwPerms
;
487 return m_pbCode
&& m_cbCode
&& m_dwOldPerm
;
497 //////////////////////////////////////////////////////////////////////////////
499 inline PBYTE
DetourGenMovEax(PBYTE pbCode
, UINT32 nValue
)
502 *((UINT32
*&)pbCode
)++ = nValue
;
506 inline PBYTE
DetourGenMovEbx(PBYTE pbCode
, UINT32 nValue
)
509 *((UINT32
*&)pbCode
)++ = nValue
;
513 inline PBYTE
DetourGenMovEcx(PBYTE pbCode
, UINT32 nValue
)
516 *((UINT32
*&)pbCode
)++ = nValue
;
520 inline PBYTE
DetourGenMovEdx(PBYTE pbCode
, UINT32 nValue
)
523 *((UINT32
*&)pbCode
)++ = nValue
;
527 inline PBYTE
DetourGenMovEsi(PBYTE pbCode
, UINT32 nValue
)
530 *((UINT32
*&)pbCode
)++ = nValue
;
534 inline PBYTE
DetourGenMovEdi(PBYTE pbCode
, UINT32 nValue
)
537 *((UINT32
*&)pbCode
)++ = nValue
;
541 inline PBYTE
DetourGenMovEbp(PBYTE pbCode
, UINT32 nValue
)
544 *((UINT32
*&)pbCode
)++ = nValue
;
548 inline PBYTE
DetourGenMovEsp(PBYTE pbCode
, UINT32 nValue
)
551 *((UINT32
*&)pbCode
)++ = nValue
;
555 inline PBYTE
DetourGenPush(PBYTE pbCode
, UINT32 nValue
)
558 *((UINT32
*&)pbCode
)++ = nValue
;
562 inline PBYTE
DetourGenPushad(PBYTE pbCode
)
568 inline PBYTE
DetourGenPopad(PBYTE pbCode
)
574 inline PBYTE
DetourGenJmp(PBYTE pbCode
, PBYTE pbJmpDst
, PBYTE pbJmpSrc
= 0)
580 *((INT32
*&)pbCode
)++ = pbJmpDst
- (pbJmpSrc
+ 5);
584 inline PBYTE
DetourGenCall(PBYTE pbCode
, PBYTE pbJmpDst
, PBYTE pbJmpSrc
= 0)
590 *((INT32
*&)pbCode
)++ = pbJmpDst
- (pbJmpSrc
+ 5);
594 inline PBYTE
DetourGenBreak(PBYTE pbCode
)
600 inline PBYTE
DetourGenRet(PBYTE pbCode
)
606 inline PBYTE
DetourGenNop(PBYTE pbCode
)
611 #endif DETOURS_INTERAL
612 #endif // __cplusplus
614 #endif // _DETOURS_H_
616 //////////////////////////////////////////////////////////////// End of File.