detours.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #pragma once
  2. #ifndef _DETOURS_H_
  3. #define _DETOURS_H_
  4. #define DETOURS_VERSION 20100
  5. #if (_MSC_VER < 1299)
  6. typedef LONG LONG_PTR;
  7. typedef ULONG ULONG_PTR;
  8. #endif
  9. #ifndef __in_z
  10. #define __in_z
  11. #endif
  12. #ifndef GUID_DEFINED
  13. #define GUID_DEFINED
  14. typedef struct _GUID
  15. {
  16. DWORD Data1;
  17. WORD Data2;
  18. WORD Data3;
  19. BYTE Data4[8];
  20. } GUID;
  21. #ifdef INITGUID
  22. #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 } }
  23. #else
  24. #define DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID name
  25. #endif
  26. #endif
  27. #if defined(__cplusplus)
  28. #ifndef _REFGUID_DEFINED
  29. #define _REFGUID_DEFINED
  30. #define REFGUID const GUID &
  31. #endif
  32. #else
  33. #ifndef _REFGUID_DEFINED
  34. #define _REFGUID_DEFINED
  35. #define REFGUID const GUID * const
  36. #endif
  37. #endif
  38. #ifdef __cplusplus
  39. extern "C"
  40. {
  41. #endif
  42. //Instruction Target Macros.
  43. #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0)
  44. #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1)
  45. #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0"
  46. extern const GUID DETOUR_EXE_RESTORE_GUID;
  47. #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr!
  48. typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, * PDETOUR_TRAMPOLINE;
  49. #pragma pack(push,8)
  50. typedef struct _DETOUR_SECTION_HEADER
  51. {
  52. DWORD cbHeaderSize;
  53. DWORD nSignature;
  54. DWORD nDataOffset;
  55. DWORD cbDataSize;
  56. DWORD nOriginalImportVirtualAddress;
  57. DWORD nOriginalImportSize;
  58. DWORD nOriginalBoundImportVirtualAddress;
  59. DWORD nOriginalBoundImportSize;
  60. DWORD nOriginalIatVirtualAddress;
  61. DWORD nOriginalIatSize;
  62. DWORD nOriginalSizeOfImage;
  63. DWORD cbPrePE;
  64. DWORD nOriginalClrFlags;
  65. DWORD reserved1;
  66. DWORD reserved2;
  67. DWORD reserved3;
  68. // Followed by cbPrePE bytes of data.
  69. } DETOUR_SECTION_HEADER, * PDETOUR_SECTION_HEADER;
  70. typedef struct _DETOUR_SECTION_RECORD
  71. {
  72. DWORD cbBytes;
  73. DWORD nReserved;
  74. GUID guid;
  75. } DETOUR_SECTION_RECORD, * PDETOUR_SECTION_RECORD;
  76. typedef struct _DETOUR_CLR_HEADER
  77. {
  78. // Header versioning
  79. ULONG cb;
  80. USHORT MajorRuntimeVersion;
  81. USHORT MinorRuntimeVersion;
  82. // Symbol table and startup information
  83. IMAGE_DATA_DIRECTORY MetaData;
  84. ULONG Flags;
  85. // Followed by the rest of the header.
  86. } DETOUR_CLR_HEADER, * PDETOUR_CLR_HEADER;
  87. typedef struct _DETOUR_EXE_RESTORE
  88. {
  89. ULONG cb;
  90. PIMAGE_DOS_HEADER pidh;
  91. PIMAGE_NT_HEADERS pinh;
  92. PULONG pclrFlags;
  93. DWORD impDirProt;
  94. IMAGE_DOS_HEADER idh;
  95. IMAGE_NT_HEADERS inh;
  96. ULONG clrFlags;
  97. } DETOUR_EXE_RESTORE, * PDETOUR_EXE_RESTORE;
  98. #pragma pack(pop)
  99. #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,}
  100. // Binary Typedefs.
  101. typedef BOOL ( CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK )( PVOID pContext , PCHAR pszFile , PCHAR * ppszOutFile );
  102. typedef BOOL ( CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK )( PVOID pContext , PCHAR pszOrigFile , PCHAR pszFile , PCHAR * ppszOutFile );
  103. typedef BOOL ( CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK )( PVOID pContext , ULONG nOrigOrdinal , ULONG nOrdinal , ULONG * pnOutOrdinal , PCHAR pszOrigSymbol , PCHAR pszSymbol , PCHAR * ppszOutSymbol );
  104. typedef BOOL ( CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK )( PVOID pContext );
  105. typedef BOOL ( CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK )( PVOID pContext , ULONG nOrdinal , PCHAR pszName , PVOID pCode );
  106. typedef VOID * PDETOUR_BINARY;
  107. typedef VOID * PDETOUR_LOADED_BINARY;
  108. // Detours 2.1 APIs.
  109. LONG WINAPI DetourTransactionBegin();
  110. LONG WINAPI DetourTransactionAbort();
  111. LONG WINAPI DetourTransactionCommit();
  112. LONG WINAPI DetourTransactionCommitEx( PVOID ** pppFailedPointer );
  113. LONG WINAPI DetourUpdateThread( HANDLE hThread );
  114. LONG WINAPI DetourAttach( PVOID * ppPointer , PVOID pDetour );
  115. LONG WINAPI DetourAttachEx( PVOID * ppPointer , PVOID pDetour , PDETOUR_TRAMPOLINE * ppRealTrampoline , PVOID * ppRealTarget , PVOID * ppRealDetour );
  116. LONG WINAPI DetourDetach( PVOID * ppPointer , PVOID pDetour );
  117. VOID WINAPI DetourSetIgnoreTooSmall( BOOL fIgnore );
  118. // Code Functions.
  119. PVOID WINAPI DetourFindFunction( PCSTR pszModule , PCSTR pszFunction );
  120. PVOID WINAPI DetourCodeFromPointer( PVOID pPointer , PVOID * ppGlobals );
  121. PVOID WINAPI DetourCopyInstruction( PVOID pDst , PVOID pSrc , PVOID * ppTarget );
  122. PVOID WINAPI DetourCopyInstructionEx( PVOID pDst , PVOID pSrc , PVOID * ppTarget , LONG * plExtra );
  123. // Loaded Binary Functions.
  124. HMODULE WINAPI DetourEnumerateModules( HMODULE hModuleLast );
  125. PVOID WINAPI DetourGetEntryPoint( HMODULE hModule );
  126. ULONG WINAPI DetourGetModuleSize( HMODULE hModule );
  127. BOOL WINAPI DetourEnumerateExports( HMODULE hModule , PVOID pContext , PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport );
  128. PVOID WINAPI DetourFindPayload( HMODULE hModule , REFGUID rguid , DWORD * pcbData );
  129. DWORD WINAPI DetourGetSizeOfPayloads( HMODULE hModule );
  130. // Persistent Binary Functions.
  131. PDETOUR_BINARY WINAPI DetourBinaryOpen( HANDLE hFile );
  132. PVOID WINAPI DetourBinaryEnumeratePayloads( PDETOUR_BINARY pBinary , GUID * pGuid , DWORD * pcbData , DWORD * pnIterator );
  133. PVOID WINAPI DetourBinaryFindPayload( PDETOUR_BINARY pBinary , REFGUID rguid , DWORD * pcbData );
  134. PVOID WINAPI DetourBinarySetPayload( PDETOUR_BINARY pBinary , REFGUID rguid , PVOID pData , DWORD cbData );
  135. BOOL WINAPI DetourBinaryDeletePayload( PDETOUR_BINARY pBinary , REFGUID rguid );
  136. BOOL WINAPI DetourBinaryPurgePayloads( PDETOUR_BINARY pBinary );
  137. BOOL WINAPI DetourBinaryResetImports( PDETOUR_BINARY pBinary );
  138. 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 );
  139. BOOL WINAPI DetourBinaryWrite( PDETOUR_BINARY pBinary , HANDLE hFile );
  140. BOOL WINAPI DetourBinaryClose( PDETOUR_BINARY pBinary );
  141. // Create Process & Load Dll.
  142. 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 );
  143. 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 );
  144. 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 );
  145. 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 );
  146. #ifdef UNICODE
  147. #define DetourCreateProcessWithDll DetourCreateProcessWithDllW
  148. #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW
  149. #else
  150. #define DetourCreateProcessWithDll DetourCreateProcessWithDllA
  151. #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA
  152. #endif
  153. BOOL WINAPI DetourCopyPayloadToProcess( HANDLE hProcess , REFGUID rguid , PVOID pvData , DWORD cbData );
  154. BOOL WINAPI DetourRestoreAfterWith();
  155. BOOL WINAPI DetourRestoreAfterWithEx( PVOID pvData , DWORD cbData );
  156. HMODULE WINAPI DetourGetDetouredMarker();
  157. #ifdef __cplusplus
  158. }
  159. #endif
  160. #ifdef __cplusplus
  161. #ifdef DETOURS_INTERNAL
  162. #ifndef __deref_out
  163. #define __deref_out
  164. #endif
  165. #ifndef __deref
  166. #define __deref
  167. #endif
  168. #if (_MSC_VER < 1299)
  169. #include <imagehlp.h>
  170. typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
  171. typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
  172. typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
  173. typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
  174. static inline LONG InterlockedCompareExchange( LONG * ptr , LONG nval , LONG oval )
  175. {
  176. return ( LONG ) ::InterlockedCompareExchange( ( PVOID * ) ptr,( PVOID ) nval,( PVOID ) oval );
  177. }
  178. #else
  179. #include <dbghelp.h>
  180. #endif
  181. #ifdef IMAGEAPI // defined by DBGHELP.H
  182. typedef LPAPI_VERSION ( NTAPI *PF_ImagehlpApiVersionEx )( LPAPI_VERSION AppVersion );
  183. typedef BOOL ( NTAPI *PF_SymInitialize )( IN HANDLE hProcess , IN LPCSTR UserSearchPath , IN BOOL fInvadeProcess );
  184. typedef DWORD ( NTAPI *PF_SymSetOptions )( IN DWORD SymOptions );
  185. typedef DWORD ( NTAPI *PF_SymGetOptions )( VOID );
  186. typedef DWORD64 ( NTAPI *PF_SymLoadModule64 )( IN HANDLE hProcess , IN HANDLE hFile , IN PSTR ImageName , IN PSTR ModuleName , IN DWORD64 BaseOfDll , IN DWORD SizeOfDll );
  187. typedef BOOL ( NTAPI *PF_SymGetModuleInfo64 )( IN HANDLE hProcess , IN DWORD64 qwAddr , OUT PIMAGEHLP_MODULE64 ModuleInfo );
  188. typedef BOOL ( NTAPI *PF_SymFromName )( IN HANDLE hProcess , IN LPSTR Name , OUT PSYMBOL_INFO Symbol );
  189. typedef struct _DETOUR_SYM_INFO
  190. {
  191. HANDLE hProcess;
  192. HMODULE hDbgHelp;
  193. PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx;
  194. PF_SymInitialize pfSymInitialize;
  195. PF_SymSetOptions pfSymSetOptions;
  196. PF_SymGetOptions pfSymGetOptions;
  197. PF_SymLoadModule64 pfSymLoadModule64;
  198. PF_SymGetModuleInfo64 pfSymGetModuleInfo64;
  199. PF_SymFromName pfSymFromName;
  200. } DETOUR_SYM_INFO, * PDETOUR_SYM_INFO;
  201. PDETOUR_SYM_INFO DetourLoadDbgHelp( VOID );
  202. #endif // IMAGEAPI
  203. #ifndef DETOUR_TRACE
  204. #if DETOUR_DEBUG
  205. #define DETOUR_TRACE(x) printf x
  206. #define DETOUR_BREAK() DebugBreak()
  207. #include <stdio.h>
  208. #include <limits.h>
  209. #else
  210. #define DETOUR_TRACE(x)
  211. #define DETOUR_BREAK()
  212. #endif
  213. #endif
  214. #ifdef DETOURS_IA64
  215. __declspec(align(16)) struct DETOUR_IA64_BUNDLE
  216. {
  217. public:
  218. union
  219. {
  220. BYTE data[16];
  221. UINT64 wide[2];
  222. };
  223. public:
  224. struct DETOUR_IA64_METADATA;
  225. typedef BOOL ( DETOUR_IA64_BUNDLE::* DETOUR_IA64_METACOPY )
  226. ( const DETOUR_IA64_METADATA * pMeta , DETOUR_IA64_BUNDLE * pDst ) const;
  227. enum
  228. {
  229. A_UNIT = 1u ,
  230. I_UNIT = 2u ,
  231. M_UNIT = 3u ,
  232. B_UNIT = 4u ,
  233. F_UNIT = 5u ,
  234. L_UNIT = 6u ,
  235. X_UNIT = 7u ,
  236. UNIT_MASK = 7u ,
  237. STOP = 8u
  238. };
  239. struct DETOUR_IA64_METADATA
  240. {
  241. ULONG nTemplate : 8; // Instruction template.
  242. ULONG nUnit0 : 4; // Unit for slot 0
  243. ULONG nUnit1 : 4; // Unit for slot 1
  244. ULONG nUnit2 : 4; // Unit for slot 2
  245. DETOUR_IA64_METACOPY pfCopy; // Function pointer.
  246. };
  247. protected:
  248. BOOL CopyBytes( const DETOUR_IA64_METADATA * pMeta , DETOUR_IA64_BUNDLE * pDst ) const;
  249. BOOL CopyBytesMMB( const DETOUR_IA64_METADATA * pMeta , DETOUR_IA64_BUNDLE * pDst ) const;
  250. BOOL CopyBytesMBB( const DETOUR_IA64_METADATA * pMeta , DETOUR_IA64_BUNDLE * pDst ) const;
  251. BOOL CopyBytesBBB( const DETOUR_IA64_METADATA * pMeta , DETOUR_IA64_BUNDLE * pDst ) const;
  252. BOOL CopyBytesMLX( const DETOUR_IA64_METADATA * pMeta , DETOUR_IA64_BUNDLE * pDst ) const;
  253. static const DETOUR_IA64_METADATA s_rceCopyTable[33];
  254. public:
  255. // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0
  256. // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0.
  257. // 00
  258. // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0.
  259. // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0]
  260. // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5]
  261. // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42]
  262. // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46]
  263. // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83]
  264. // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87]
  265. // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124]
  266. BYTE GetTemplate() const;
  267. BYTE GetInst0() const;
  268. BYTE GetInst1() const;
  269. BYTE GetInst2() const;
  270. BYTE GetUnit0() const;
  271. BYTE GetUnit1() const;
  272. BYTE GetUnit2() const;
  273. UINT64 GetData0() const;
  274. UINT64 GetData1() const;
  275. UINT64 GetData2() const;
  276. public:
  277. BOOL IsBrl() const;
  278. VOID SetBrl();
  279. VOID SetBrl( UINT64 target );
  280. UINT64 GetBrlTarget() const;
  281. VOID SetBrlTarget( UINT64 target );
  282. VOID SetBrlImm( UINT64 imm );
  283. UINT64 GetBrlImm() const;
  284. BOOL IsMovlGp() const;
  285. UINT64 GetMovlGp() const;
  286. VOID SetMovlGp( UINT64 gp );
  287. VOID SetInst0( BYTE nInst );
  288. VOID SetInst1( BYTE nInst );
  289. VOID SetInst2( BYTE nInst );
  290. VOID SetData0( UINT64 nData );
  291. VOID SetData1( UINT64 nData );
  292. VOID SetData2( UINT64 nData );
  293. BOOL SetNop0();
  294. BOOL SetNop1();
  295. BOOL SetNop2();
  296. BOOL SetStop();
  297. BOOL Copy( DETOUR_IA64_BUNDLE * pDst ) const;
  298. };
  299. #endif
  300. #endif
  301. #endif
  302. #endif