////////////////////////////////////////////////////////////////////////////// // // Core Detours Functionality (detours.h of detours.lib) // // Microsoft Research Detours Package, Version 2.1. // // Copyright (c) Microsoft Corporation. All rights reserved. // #pragma once #ifndef _DETOURS_H_ #define _DETOURS_H_ #define DETOURS_VERSION 20100 // 2.1.0 ////////////////////////////////////////////////////////////////////////////// // #if (_MSC_VER < 1299) typedef LONG LONG_PTR; typedef ULONG ULONG_PTR; #endif #ifndef __in_z #define __in_z #endif ////////////////////////////////////////////////////////////////////////////// // #ifndef GUID_DEFINED #define GUID_DEFINED typedef struct _GUID { DWORD Data1; WORD Data2; WORD Data3; BYTE Data4[ 8 ]; } GUID; #ifdef INITGUID #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ const GUID name \ = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } #else #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ const GUID name #endif // INITGUID #endif // !GUID_DEFINED #if defined(__cplusplus) #ifndef _REFGUID_DEFINED #define _REFGUID_DEFINED #define REFGUID const GUID & #endif // !_REFGUID_DEFINED #else // !__cplusplus #ifndef _REFGUID_DEFINED #define _REFGUID_DEFINED #define REFGUID const GUID * const #endif // !_REFGUID_DEFINED #endif // !__cplusplus // ////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus extern "C" { #endif // __cplusplus /////////////////////////////////////////////////// Instruction Target Macros. // #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0) #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1) #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0" extern const GUID DETOUR_EXE_RESTORE_GUID; #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr! typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE; /////////////////////////////////////////////////////////// Binary Structures. // #pragma pack(push, 8) typedef struct _DETOUR_SECTION_HEADER { DWORD cbHeaderSize; DWORD nSignature; DWORD nDataOffset; DWORD cbDataSize; DWORD nOriginalImportVirtualAddress; DWORD nOriginalImportSize; DWORD nOriginalBoundImportVirtualAddress; DWORD nOriginalBoundImportSize; DWORD nOriginalIatVirtualAddress; DWORD nOriginalIatSize; DWORD nOriginalSizeOfImage; DWORD cbPrePE; DWORD nOriginalClrFlags; DWORD reserved1; DWORD reserved2; DWORD reserved3; // Followed by cbPrePE bytes of data. } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER; typedef struct _DETOUR_SECTION_RECORD { DWORD cbBytes; DWORD nReserved; GUID guid; } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD; typedef struct _DETOUR_CLR_HEADER { // Header versioning ULONG cb; USHORT MajorRuntimeVersion; USHORT MinorRuntimeVersion; // Symbol table and startup information IMAGE_DATA_DIRECTORY MetaData; ULONG Flags; // Followed by the rest of the header. } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER; typedef struct _DETOUR_EXE_RESTORE { ULONG cb; PIMAGE_DOS_HEADER pidh; PIMAGE_NT_HEADERS pinh; PULONG pclrFlags; DWORD impDirProt; IMAGE_DOS_HEADER idh; IMAGE_NT_HEADERS inh; ULONG clrFlags; } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE; #pragma pack(pop) #define DETOUR_SECTION_HEADER_DECLARE(cbSectionSize) \ { \ sizeof(DETOUR_SECTION_HEADER),\ DETOUR_SECTION_HEADER_SIGNATURE,\ sizeof(DETOUR_SECTION_HEADER),\ (cbSectionSize),\ \ 0,\ 0,\ 0,\ 0,\ \ 0,\ 0,\ 0,\ 0,\ } ///////////////////////////////////////////////////////////// Binary Typedefs. // typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)(PVOID pContext, PCHAR pszFile, PCHAR *ppszOutFile); typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)(PVOID pContext, PCHAR pszOrigFile, PCHAR pszFile, PCHAR *ppszOutFile); typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)(PVOID pContext, ULONG nOrigOrdinal, ULONG nOrdinal, ULONG *pnOutOrdinal, PCHAR pszOrigSymbol, PCHAR pszSymbol, PCHAR *ppszOutSymbol); typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)(PVOID pContext); typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(PVOID pContext, ULONG nOrdinal, PCHAR pszName, PVOID pCode); typedef VOID * PDETOUR_BINARY; typedef VOID * PDETOUR_LOADED_BINARY; //////////////////////////////////////////////////////////// Detours 2.1 APIs. // LONG WINAPI DetourTransactionBegin(); LONG WINAPI DetourTransactionAbort(); LONG WINAPI DetourTransactionCommit(); LONG WINAPI DetourTransactionCommitEx(PVOID **pppFailedPointer); LONG WINAPI DetourUpdateThread(HANDLE hThread); LONG WINAPI DetourAttach(PVOID *ppPointer, PVOID pDetour); LONG WINAPI DetourAttachEx(PVOID *ppPointer, PVOID pDetour, PDETOUR_TRAMPOLINE *ppRealTrampoline, PVOID *ppRealTarget, PVOID *ppRealDetour); LONG WINAPI DetourDetach(PVOID *ppPointer, PVOID pDetour); VOID WINAPI DetourSetIgnoreTooSmall(BOOL fIgnore); ////////////////////////////////////////////////////////////// Code Functions. // PVOID WINAPI DetourFindFunction(PCSTR pszModule, PCSTR pszFunction); PVOID WINAPI DetourCodeFromPointer(PVOID pPointer, PVOID *ppGlobals); PVOID WINAPI DetourCopyInstruction(PVOID pDst, PVOID pSrc, PVOID *ppTarget); PVOID WINAPI DetourCopyInstructionEx(PVOID pDst, PVOID pSrc, PVOID *ppTarget, LONG *plExtra); ///////////////////////////////////////////////////// Loaded Binary Functions. // HMODULE WINAPI DetourEnumerateModules(HMODULE hModuleLast); PVOID WINAPI DetourGetEntryPoint(HMODULE hModule); ULONG WINAPI DetourGetModuleSize(HMODULE hModule); BOOL WINAPI DetourEnumerateExports(HMODULE hModule, PVOID pContext, PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport); PVOID WINAPI DetourFindPayload(HMODULE hModule, REFGUID rguid, DWORD *pcbData); DWORD WINAPI DetourGetSizeOfPayloads(HMODULE hModule); ///////////////////////////////////////////////// Persistent Binary Functions. // PDETOUR_BINARY WINAPI DetourBinaryOpen(HANDLE hFile); PVOID WINAPI DetourBinaryEnumeratePayloads(PDETOUR_BINARY pBinary, GUID *pGuid, DWORD *pcbData, DWORD *pnIterator); PVOID WINAPI DetourBinaryFindPayload(PDETOUR_BINARY pBinary, REFGUID rguid, DWORD *pcbData); PVOID WINAPI DetourBinarySetPayload(PDETOUR_BINARY pBinary, REFGUID rguid, PVOID pData, DWORD cbData); BOOL WINAPI DetourBinaryDeletePayload(PDETOUR_BINARY pBinary, REFGUID rguid); BOOL WINAPI DetourBinaryPurgePayloads(PDETOUR_BINARY pBinary); BOOL WINAPI DetourBinaryResetImports(PDETOUR_BINARY pBinary); BOOL WINAPI DetourBinaryEditImports(PDETOUR_BINARY pBinary, PVOID pContext, PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway, PF_DETOUR_BINARY_FILE_CALLBACK pfFile, PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol, PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit); BOOL WINAPI DetourBinaryWrite(PDETOUR_BINARY pBinary, HANDLE hFile); BOOL WINAPI DetourBinaryClose(PDETOUR_BINARY pBinary); /////////////////////////////////////////////////// Create Process & Load Dll. // typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA) (LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW) (LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation); BOOL WINAPI DetourCreateProcessWithDllA(LPCSTR lpApplicationName, __in_z LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation, LPCSTR lpDetouredDllFullName, LPCSTR lpDllName, PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA); BOOL WINAPI DetourCreateProcessWithDllW(LPCWSTR lpApplicationName, __in_z LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation, LPCSTR lpDetouredDllFullName, LPCSTR lpDllName, PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); #ifdef UNICODE #define DetourCreateProcessWithDll DetourCreateProcessWithDllW #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW #else #define DetourCreateProcessWithDll DetourCreateProcessWithDllA #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA #endif // !UNICODE BOOL WINAPI DetourCopyPayloadToProcess(HANDLE hProcess, REFGUID rguid, PVOID pvData, DWORD cbData); BOOL WINAPI DetourRestoreAfterWith(); BOOL WINAPI DetourRestoreAfterWithEx(PVOID pvData, DWORD cbData); HMODULE WINAPI DetourGetDetouredMarker(); // ////////////////////////////////////////////////////////////////////////////// #ifdef __cplusplus } #endif // __cplusplus //////////////////////////////////////////////// Detours Internal Definitions. // #ifdef __cplusplus #ifdef DETOURS_INTERNAL #ifndef __deref_out #define __deref_out #endif #ifndef __deref #define __deref #endif ////////////////////////////////////////////////////////////////////////////// // #if (_MSC_VER < 1299) #include typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64; typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64; typedef IMAGEHLP_SYMBOL SYMBOL_INFO; typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO; static inline LONG InterlockedCompareExchange(LONG *ptr, LONG nval, LONG oval) { return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval); } #else #include #endif #ifdef IMAGEAPI // defined by DBGHELP.H typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(LPAPI_VERSION AppVersion); typedef BOOL (NTAPI *PF_SymInitialize)(IN HANDLE hProcess, IN LPCSTR UserSearchPath, IN BOOL fInvadeProcess); typedef DWORD (NTAPI *PF_SymSetOptions)(IN DWORD SymOptions); typedef DWORD (NTAPI *PF_SymGetOptions)(VOID); typedef DWORD64 (NTAPI *PF_SymLoadModule64)(IN HANDLE hProcess, IN HANDLE hFile, IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll); typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(IN HANDLE hProcess, IN DWORD64 qwAddr, OUT PIMAGEHLP_MODULE64 ModuleInfo); typedef BOOL (NTAPI *PF_SymFromName)(IN HANDLE hProcess, IN LPSTR Name, OUT PSYMBOL_INFO Symbol); typedef struct _DETOUR_SYM_INFO { HANDLE hProcess; HMODULE hDbgHelp; PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx; PF_SymInitialize pfSymInitialize; PF_SymSetOptions pfSymSetOptions; PF_SymGetOptions pfSymGetOptions; PF_SymLoadModule64 pfSymLoadModule64; PF_SymGetModuleInfo64 pfSymGetModuleInfo64; PF_SymFromName pfSymFromName; } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO; PDETOUR_SYM_INFO DetourLoadDbgHelp(VOID); #endif // IMAGEAPI #ifndef DETOUR_TRACE #if DETOUR_DEBUG #define DETOUR_TRACE(x) printf x #define DETOUR_BREAK() DebugBreak() #include #include #else #define DETOUR_TRACE(x) #define DETOUR_BREAK() #endif #endif #ifdef DETOURS_IA64 __declspec(align(16)) struct DETOUR_IA64_BUNDLE { public: union { BYTE data[16]; UINT64 wide[2]; }; public: struct DETOUR_IA64_METADATA; typedef BOOL (DETOUR_IA64_BUNDLE::* DETOUR_IA64_METACOPY) (const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; enum { A_UNIT = 1u, I_UNIT = 2u, M_UNIT = 3u, B_UNIT = 4u, F_UNIT = 5u, L_UNIT = 6u, X_UNIT = 7u, UNIT_MASK = 7u, STOP = 8u }; struct DETOUR_IA64_METADATA { ULONG nTemplate : 8; // Instruction template. ULONG nUnit0 : 4; // Unit for slot 0 ULONG nUnit1 : 4; // Unit for slot 1 ULONG nUnit2 : 4; // Unit for slot 2 DETOUR_IA64_METACOPY pfCopy; // Function pointer. }; protected: BOOL CopyBytes(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; BOOL CopyBytesMMB(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; BOOL CopyBytesMBB(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; BOOL CopyBytesBBB(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; BOOL CopyBytesMLX(const DETOUR_IA64_METADATA *pMeta, DETOUR_IA64_BUNDLE *pDst) const; static const DETOUR_IA64_METADATA s_rceCopyTable[33]; public: // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0 // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0. // 00 // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0. // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0] // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5] // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42] // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46] // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83] // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87] // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124] BYTE GetTemplate() const; BYTE GetInst0() const; BYTE GetInst1() const; BYTE GetInst2() const; BYTE GetUnit0() const; BYTE GetUnit1() const; BYTE GetUnit2() const; UINT64 GetData0() const; UINT64 GetData1() const; UINT64 GetData2() const; public: BOOL IsBrl() const; VOID SetBrl(); VOID SetBrl(UINT64 target); UINT64 GetBrlTarget() const; VOID SetBrlTarget(UINT64 target); VOID SetBrlImm(UINT64 imm); UINT64 GetBrlImm() const; BOOL IsMovlGp() const; UINT64 GetMovlGp() const; VOID SetMovlGp(UINT64 gp); VOID SetInst0(BYTE nInst); VOID SetInst1(BYTE nInst); VOID SetInst2(BYTE nInst); VOID SetData0(UINT64 nData); VOID SetData1(UINT64 nData); VOID SetData2(UINT64 nData); BOOL SetNop0(); BOOL SetNop1(); BOOL SetNop2(); BOOL SetStop(); BOOL Copy(DETOUR_IA64_BUNDLE *pDst) const; }; #endif // DETOURS_IA64 ////////////////////////////////////////////////////////////////////////////// #endif // DETOURS_INTERNAL #endif // __cplusplus #endif // _DETOURS_H_ // //////////////////////////////////////////////////////////////// End of File.