detours.h 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237
  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. #pragma once
  10. #ifndef _DETOURS_H_
  11. #define _DETOURS_H_
  12. #define DETOURS_VERSION 0x4c0c1 // 0xMAJORcMINORcPATCH
  13. //////////////////////////////////////////////////////////////////////////////
  14. //
  15. #ifdef DETOURS_INTERNAL
  16. #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1
  17. #define _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE 1
  18. #pragma warning(disable:4068) // unknown pragma (suppress)
  19. #if _MSC_VER >= 1900
  20. #pragma warning(push)
  21. #pragma warning(disable:4091) // empty typedef
  22. #endif
  23. // Suppress declspec(dllimport) for the sake of Detours
  24. // users that provide kernel32 functionality themselves.
  25. // This is ok in the mainstream case, it will just cost
  26. // an extra instruction calling some functions, which
  27. // LTCG optimizes away.
  28. //
  29. #define _KERNEL32_ 1
  30. #define _USER32_ 1
  31. #include <windows.h>
  32. #if (_MSC_VER < 1310)
  33. #else
  34. #pragma warning(push)
  35. #if _MSC_VER > 1400
  36. #pragma warning(disable:6102 6103) // /analyze warnings
  37. #endif
  38. #include <strsafe.h>
  39. #include <intsafe.h>
  40. #pragma warning(pop)
  41. #endif
  42. #include <crtdbg.h>
  43. // Allow Detours to cleanly compile with the MingW toolchain.
  44. //
  45. #ifdef __GNUC__
  46. #define __try
  47. #define __except(x) if (0)
  48. #include <strsafe.h>
  49. #include <intsafe.h>
  50. #endif
  51. // From winerror.h, as this error isn't found in some SDKs:
  52. //
  53. // MessageId: ERROR_DYNAMIC_CODE_BLOCKED
  54. //
  55. // MessageText:
  56. //
  57. // The operation was blocked as the process prohibits dynamic code generation.
  58. //
  59. #define ERROR_DYNAMIC_CODE_BLOCKED 1655L
  60. #endif // DETOURS_INTERNAL
  61. //////////////////////////////////////////////////////////////////////////////
  62. //
  63. #undef DETOURS_X64
  64. #undef DETOURS_X86
  65. #undef DETOURS_IA64
  66. #undef DETOURS_ARM
  67. #undef DETOURS_ARM64
  68. #undef DETOURS_BITS
  69. #undef DETOURS_32BIT
  70. #undef DETOURS_64BIT
  71. #ifndef DECLSPEC_HYBRID_PATCHABLE
  72. #define DECLSPEC_HYBRID_PATCHABLE DECLSPEC_CHPE_PATCHABLE
  73. #endif
  74. #if defined(_X86_)
  75. #define DETOURS_X86
  76. #define DETOURS_OPTION_BITS 64
  77. #elif defined(_AMD64_) || defined(_ARM64EC_)
  78. #define DETOURS_X64
  79. #define DETOURS_OPTION_BITS 32
  80. #elif defined(_IA64_)
  81. #define DETOURS_IA64
  82. #define DETOURS_OPTION_BITS 32
  83. #elif defined(_ARM_)
  84. #define DETOURS_ARM
  85. #elif defined(_ARM64_)
  86. #define DETOURS_ARM64
  87. #else
  88. #error Unknown architecture (x86, amd64, ia64, arm, arm64, arm64ec)
  89. #endif
  90. #ifdef _WIN64
  91. #undef DETOURS_32BIT
  92. #define DETOURS_64BIT 1
  93. #define DETOURS_BITS 64
  94. // If all 64bit kernels can run one and only one 32bit architecture.
  95. //#define DETOURS_OPTION_BITS 32
  96. #else
  97. #define DETOURS_32BIT 1
  98. #undef DETOURS_64BIT
  99. #define DETOURS_BITS 32
  100. // If all 64bit kernels can run one and only one 32bit architecture.
  101. //#define DETOURS_OPTION_BITS 32
  102. #endif
  103. /////////////////////////////////////////////////////////////// Helper Macros.
  104. //
  105. #define DETOURS_STRINGIFY_(x) #x
  106. #define DETOURS_STRINGIFY(x) DETOURS_STRINGIFY_(x)
  107. #define VER_DETOURS_BITS DETOURS_STRINGIFY(DETOURS_BITS)
  108. //////////////////////////////////////////////////////////////////////////////
  109. //
  110. #if (_MSC_VER < 1299) && !defined(__MINGW32__)
  111. typedef LONG LONG_PTR;
  112. typedef ULONG ULONG_PTR;
  113. #endif
  114. ///////////////////////////////////////////////// SAL 2.0 Annotations w/o SAL.
  115. //
  116. // These definitions are include so that Detours will build even if the
  117. // compiler doesn't have full SAL 2.0 support.
  118. //
  119. #ifndef DETOURS_DONT_REMOVE_SAL_20
  120. #ifdef DETOURS_TEST_REMOVE_SAL_20
  121. #undef _Analysis_assume_
  122. #undef _Benign_race_begin_
  123. #undef _Benign_race_end_
  124. #undef _Field_range_
  125. #undef _Field_size_
  126. #undef _In_
  127. #undef _In_bytecount_
  128. #undef _In_count_
  129. #undef __in_ecount
  130. #undef _In_opt_
  131. #undef _In_opt_bytecount_
  132. #undef _In_opt_count_
  133. #undef _In_opt_z_
  134. #undef _In_range_
  135. #undef _In_reads_
  136. #undef _In_reads_bytes_
  137. #undef _In_reads_opt_
  138. #undef _In_reads_opt_bytes_
  139. #undef _In_reads_or_z_
  140. #undef _In_z_
  141. #undef _Inout_
  142. #undef _Inout_opt_
  143. #undef _Inout_z_count_
  144. #undef _Out_
  145. #undef _Out_opt_
  146. #undef _Out_writes_
  147. #undef _Outptr_result_maybenull_
  148. #undef _Readable_bytes_
  149. #undef _Success_
  150. #undef _Writable_bytes_
  151. #undef _Pre_notnull_
  152. #endif
  153. #if defined(_Deref_out_opt_z_) && !defined(_Outptr_result_maybenull_)
  154. #define _Outptr_result_maybenull_ _Deref_out_opt_z_
  155. #endif
  156. #if defined(_In_count_) && !defined(_In_reads_)
  157. #define _In_reads_(x) _In_count_(x)
  158. #endif
  159. #if defined(_In_opt_count_) && !defined(_In_reads_opt_)
  160. #define _In_reads_opt_(x) _In_opt_count_(x)
  161. #endif
  162. #if defined(_In_opt_bytecount_) && !defined(_In_reads_opt_bytes_)
  163. #define _In_reads_opt_bytes_(x) _In_opt_bytecount_(x)
  164. #endif
  165. #if defined(_In_bytecount_) && !defined(_In_reads_bytes_)
  166. #define _In_reads_bytes_(x) _In_bytecount_(x)
  167. #endif
  168. #ifndef _In_
  169. #define _In_
  170. #endif
  171. #ifndef _In_bytecount_
  172. #define _In_bytecount_(x)
  173. #endif
  174. #ifndef _In_count_
  175. #define _In_count_(x)
  176. #endif
  177. #ifndef __in_ecount
  178. #define __in_ecount(x)
  179. #endif
  180. #ifndef _In_opt_
  181. #define _In_opt_
  182. #endif
  183. #ifndef _In_opt_bytecount_
  184. #define _In_opt_bytecount_(x)
  185. #endif
  186. #ifndef _In_opt_count_
  187. #define _In_opt_count_(x)
  188. #endif
  189. #ifndef _In_opt_z_
  190. #define _In_opt_z_
  191. #endif
  192. #ifndef _In_range_
  193. #define _In_range_(x,y)
  194. #endif
  195. #ifndef _In_reads_
  196. #define _In_reads_(x)
  197. #endif
  198. #ifndef _In_reads_bytes_
  199. #define _In_reads_bytes_(x)
  200. #endif
  201. #ifndef _In_reads_opt_
  202. #define _In_reads_opt_(x)
  203. #endif
  204. #ifndef _In_reads_opt_bytes_
  205. #define _In_reads_opt_bytes_(x)
  206. #endif
  207. #ifndef _In_reads_or_z_
  208. #define _In_reads_or_z_
  209. #endif
  210. #ifndef _In_z_
  211. #define _In_z_
  212. #endif
  213. #ifndef _Inout_
  214. #define _Inout_
  215. #endif
  216. #ifndef _Inout_opt_
  217. #define _Inout_opt_
  218. #endif
  219. #ifndef _Inout_z_count_
  220. #define _Inout_z_count_(x)
  221. #endif
  222. #ifndef _Out_
  223. #define _Out_
  224. #endif
  225. #ifndef _Out_opt_
  226. #define _Out_opt_
  227. #endif
  228. #ifndef _Out_writes_
  229. #define _Out_writes_(x)
  230. #endif
  231. #ifndef _Outptr_result_maybenull_
  232. #define _Outptr_result_maybenull_
  233. #endif
  234. #ifndef _Writable_bytes_
  235. #define _Writable_bytes_(x)
  236. #endif
  237. #ifndef _Readable_bytes_
  238. #define _Readable_bytes_(x)
  239. #endif
  240. #ifndef _Success_
  241. #define _Success_(x)
  242. #endif
  243. #ifndef _Pre_notnull_
  244. #define _Pre_notnull_
  245. #endif
  246. #ifdef DETOURS_INTERNAL
  247. #pragma warning(disable:4615) // unknown warning type (suppress with older compilers)
  248. #ifndef _Benign_race_begin_
  249. #define _Benign_race_begin_
  250. #endif
  251. #ifndef _Benign_race_end_
  252. #define _Benign_race_end_
  253. #endif
  254. #ifndef _Field_size_
  255. #define _Field_size_(x)
  256. #endif
  257. #ifndef _Field_range_
  258. #define _Field_range_(x,y)
  259. #endif
  260. #ifndef _Analysis_assume_
  261. #define _Analysis_assume_(x)
  262. #endif
  263. #endif // DETOURS_INTERNAL
  264. #endif // DETOURS_DONT_REMOVE_SAL_20
  265. //////////////////////////////////////////////////////////////////////////////
  266. //
  267. #ifndef GUID_DEFINED
  268. #define GUID_DEFINED
  269. typedef struct _GUID
  270. {
  271. DWORD Data1;
  272. WORD Data2;
  273. WORD Data3;
  274. BYTE Data4[ 8 ];
  275. } GUID;
  276. #ifdef INITGUID
  277. #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
  278. const GUID name \
  279. = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
  280. #else
  281. #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
  282. const GUID name
  283. #endif // INITGUID
  284. #endif // !GUID_DEFINED
  285. #if defined(__cplusplus)
  286. #ifndef _REFGUID_DEFINED
  287. #define _REFGUID_DEFINED
  288. #define REFGUID const GUID &
  289. #endif // !_REFGUID_DEFINED
  290. #else // !__cplusplus
  291. #ifndef _REFGUID_DEFINED
  292. #define _REFGUID_DEFINED
  293. #define REFGUID const GUID * const
  294. #endif // !_REFGUID_DEFINED
  295. #endif // !__cplusplus
  296. #ifndef ARRAYSIZE
  297. #define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
  298. #endif
  299. //
  300. //////////////////////////////////////////////////////////////////////////////
  301. #ifdef __cplusplus
  302. extern "C" {
  303. #endif // __cplusplus
  304. /////////////////////////////////////////////////// Instruction Target Macros.
  305. //
  306. #define DETOUR_INSTRUCTION_TARGET_NONE ((PVOID)0)
  307. #define DETOUR_INSTRUCTION_TARGET_DYNAMIC ((PVOID)(LONG_PTR)-1)
  308. #define DETOUR_SECTION_HEADER_SIGNATURE 0x00727444 // "Dtr\0"
  309. extern const GUID DETOUR_EXE_RESTORE_GUID;
  310. extern const GUID DETOUR_EXE_HELPER_GUID;
  311. #define DETOUR_TRAMPOLINE_SIGNATURE 0x21727444 // Dtr!
  312. typedef struct _DETOUR_TRAMPOLINE DETOUR_TRAMPOLINE, *PDETOUR_TRAMPOLINE;
  313. #ifndef DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS
  314. #define DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS 32
  315. #endif // !DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS
  316. /////////////////////////////////////////////////////////// Binary Structures.
  317. //
  318. #pragma pack(push, 8)
  319. typedef struct _DETOUR_SECTION_HEADER
  320. {
  321. DWORD cbHeaderSize;
  322. DWORD nSignature;
  323. DWORD nDataOffset;
  324. DWORD cbDataSize;
  325. DWORD nOriginalImportVirtualAddress;
  326. DWORD nOriginalImportSize;
  327. DWORD nOriginalBoundImportVirtualAddress;
  328. DWORD nOriginalBoundImportSize;
  329. DWORD nOriginalIatVirtualAddress;
  330. DWORD nOriginalIatSize;
  331. DWORD nOriginalSizeOfImage;
  332. DWORD cbPrePE;
  333. DWORD nOriginalClrFlags;
  334. DWORD reserved1;
  335. DWORD reserved2;
  336. DWORD reserved3;
  337. // Followed by cbPrePE bytes of data.
  338. } DETOUR_SECTION_HEADER, *PDETOUR_SECTION_HEADER;
  339. typedef struct _DETOUR_SECTION_RECORD
  340. {
  341. DWORD cbBytes;
  342. DWORD nReserved;
  343. GUID guid;
  344. } DETOUR_SECTION_RECORD, *PDETOUR_SECTION_RECORD;
  345. typedef struct _DETOUR_CLR_HEADER
  346. {
  347. // Header versioning
  348. ULONG cb;
  349. USHORT MajorRuntimeVersion;
  350. USHORT MinorRuntimeVersion;
  351. // Symbol table and startup information
  352. IMAGE_DATA_DIRECTORY MetaData;
  353. ULONG Flags;
  354. // Followed by the rest of the IMAGE_COR20_HEADER
  355. } DETOUR_CLR_HEADER, *PDETOUR_CLR_HEADER;
  356. typedef struct _DETOUR_EXE_RESTORE
  357. {
  358. DWORD cb;
  359. DWORD cbidh;
  360. DWORD cbinh;
  361. DWORD cbclr;
  362. PBYTE pidh;
  363. PBYTE pinh;
  364. PBYTE pclr;
  365. IMAGE_DOS_HEADER idh;
  366. union {
  367. IMAGE_NT_HEADERS inh; // all environments have this
  368. #ifdef IMAGE_NT_OPTIONAL_HDR32_MAGIC // some environments do not have this
  369. IMAGE_NT_HEADERS32 inh32;
  370. #endif
  371. #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this
  372. IMAGE_NT_HEADERS64 inh64;
  373. #endif
  374. #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC // some environments do not have this
  375. BYTE raw[sizeof(IMAGE_NT_HEADERS64) +
  376. sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS];
  377. #else
  378. BYTE raw[0x108 + sizeof(IMAGE_SECTION_HEADER) * DETOUR_MAX_SUPPORTED_IMAGE_SECTION_HEADERS];
  379. #endif
  380. };
  381. DETOUR_CLR_HEADER clr;
  382. } DETOUR_EXE_RESTORE, *PDETOUR_EXE_RESTORE;
  383. #ifdef IMAGE_NT_OPTIONAL_HDR64_MAGIC
  384. C_ASSERT(sizeof(IMAGE_NT_HEADERS64) == 0x108);
  385. #endif
  386. // The size can change, but assert for clarity due to the muddying #ifdefs.
  387. #ifdef _WIN64
  388. C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x688);
  389. #else
  390. C_ASSERT(sizeof(DETOUR_EXE_RESTORE) == 0x678);
  391. #endif
  392. typedef struct _DETOUR_EXE_HELPER
  393. {
  394. DWORD cb;
  395. DWORD pid;
  396. DWORD nDlls;
  397. CHAR rDlls[4];
  398. } DETOUR_EXE_HELPER, *PDETOUR_EXE_HELPER;
  399. #pragma pack(pop)
  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. ///////////////////////////////////////////////////////////// Binary Typedefs.
  418. //
  419. typedef BOOL (CALLBACK *PF_DETOUR_BINARY_BYWAY_CALLBACK)(
  420. _In_opt_ PVOID pContext,
  421. _In_opt_ LPCSTR pszFile,
  422. _Outptr_result_maybenull_ LPCSTR *ppszOutFile);
  423. typedef BOOL (CALLBACK *PF_DETOUR_BINARY_FILE_CALLBACK)(
  424. _In_opt_ PVOID pContext,
  425. _In_ LPCSTR pszOrigFile,
  426. _In_ LPCSTR pszFile,
  427. _Outptr_result_maybenull_ LPCSTR *ppszOutFile);
  428. typedef BOOL (CALLBACK *PF_DETOUR_BINARY_SYMBOL_CALLBACK)(
  429. _In_opt_ PVOID pContext,
  430. _In_ ULONG nOrigOrdinal,
  431. _In_ ULONG nOrdinal,
  432. _Out_ ULONG *pnOutOrdinal,
  433. _In_opt_ LPCSTR pszOrigSymbol,
  434. _In_opt_ LPCSTR pszSymbol,
  435. _Outptr_result_maybenull_ LPCSTR *ppszOutSymbol);
  436. typedef BOOL (CALLBACK *PF_DETOUR_BINARY_COMMIT_CALLBACK)(
  437. _In_opt_ PVOID pContext);
  438. typedef BOOL (CALLBACK *PF_DETOUR_ENUMERATE_EXPORT_CALLBACK)(_In_opt_ PVOID pContext,
  439. _In_ ULONG nOrdinal,
  440. _In_opt_ LPCSTR pszName,
  441. _In_opt_ PVOID pCode);
  442. typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FILE_CALLBACK)(_In_opt_ PVOID pContext,
  443. _In_opt_ HMODULE hModule,
  444. _In_opt_ LPCSTR pszFile);
  445. typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK)(_In_opt_ PVOID pContext,
  446. _In_ DWORD nOrdinal,
  447. _In_opt_ LPCSTR pszFunc,
  448. _In_opt_ PVOID pvFunc);
  449. // Same as PF_DETOUR_IMPORT_FUNC_CALLBACK but extra indirection on last parameter.
  450. typedef BOOL (CALLBACK *PF_DETOUR_IMPORT_FUNC_CALLBACK_EX)(_In_opt_ PVOID pContext,
  451. _In_ DWORD nOrdinal,
  452. _In_opt_ LPCSTR pszFunc,
  453. _In_opt_ PVOID* ppvFunc);
  454. typedef VOID * PDETOUR_BINARY;
  455. typedef VOID * PDETOUR_LOADED_BINARY;
  456. //////////////////////////////////////////////////////////// Transaction APIs.
  457. //
  458. LONG WINAPI DetourTransactionBegin(VOID);
  459. LONG WINAPI DetourTransactionAbort(VOID);
  460. LONG WINAPI DetourTransactionCommit(VOID);
  461. LONG WINAPI DetourTransactionCommitEx(_Out_opt_ PVOID **pppFailedPointer);
  462. LONG WINAPI DetourUpdateThread(_In_ HANDLE hThread);
  463. LONG WINAPI DetourAttach(_Inout_ PVOID *ppPointer,
  464. _In_ PVOID pDetour);
  465. LONG WINAPI DetourAttachEx(_Inout_ PVOID *ppPointer,
  466. _In_ PVOID pDetour,
  467. _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline,
  468. _Out_opt_ PVOID *ppRealTarget,
  469. _Out_opt_ PVOID *ppRealDetour);
  470. LONG WINAPI DetourDetach(_Inout_ PVOID *ppPointer,
  471. _In_ PVOID pDetour);
  472. BOOL WINAPI DetourSetIgnoreTooSmall(_In_ BOOL fIgnore);
  473. BOOL WINAPI DetourSetRetainRegions(_In_ BOOL fRetain);
  474. PVOID WINAPI DetourSetSystemRegionLowerBound(_In_ PVOID pSystemRegionLowerBound);
  475. PVOID WINAPI DetourSetSystemRegionUpperBound(_In_ PVOID pSystemRegionUpperBound);
  476. ////////////////////////////////////////////////////////////// Code Functions.
  477. //
  478. PVOID WINAPI DetourFindFunction(_In_ LPCSTR pszModule,
  479. _In_ LPCSTR pszFunction);
  480. PVOID WINAPI DetourCodeFromPointer(_In_ PVOID pPointer,
  481. _Out_opt_ PVOID *ppGlobals);
  482. PVOID WINAPI DetourCopyInstruction(_In_opt_ PVOID pDst,
  483. _Inout_opt_ PVOID *ppDstPool,
  484. _In_ PVOID pSrc,
  485. _Out_opt_ PVOID *ppTarget,
  486. _Out_opt_ LONG *plExtra);
  487. BOOL WINAPI DetourSetCodeModule(_In_ HMODULE hModule,
  488. _In_ BOOL fLimitReferencesToModule);
  489. PVOID WINAPI DetourAllocateRegionWithinJumpBounds(_In_ LPCVOID pbTarget,
  490. _Out_ PDWORD pcbAllocatedSize);
  491. BOOL WINAPI DetourIsFunctionImported(_In_ PBYTE pbCode,
  492. _In_ PBYTE pbAddress);
  493. ///////////////////////////////////////////////////// Loaded Binary Functions.
  494. //
  495. HMODULE WINAPI DetourGetContainingModule(_In_ PVOID pvAddr);
  496. HMODULE WINAPI DetourEnumerateModules(_In_opt_ HMODULE hModuleLast);
  497. PVOID WINAPI DetourGetEntryPoint(_In_opt_ HMODULE hModule);
  498. ULONG WINAPI DetourGetModuleSize(_In_opt_ HMODULE hModule);
  499. BOOL WINAPI DetourEnumerateExports(_In_ HMODULE hModule,
  500. _In_opt_ PVOID pContext,
  501. _In_ PF_DETOUR_ENUMERATE_EXPORT_CALLBACK pfExport);
  502. BOOL WINAPI DetourEnumerateImports(_In_opt_ HMODULE hModule,
  503. _In_opt_ PVOID pContext,
  504. _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
  505. _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK pfImportFunc);
  506. BOOL WINAPI DetourEnumerateImportsEx(_In_opt_ HMODULE hModule,
  507. _In_opt_ PVOID pContext,
  508. _In_opt_ PF_DETOUR_IMPORT_FILE_CALLBACK pfImportFile,
  509. _In_opt_ PF_DETOUR_IMPORT_FUNC_CALLBACK_EX pfImportFuncEx);
  510. _Writable_bytes_(*pcbData)
  511. _Readable_bytes_(*pcbData)
  512. _Success_(return != NULL)
  513. PVOID WINAPI DetourFindPayload(_In_opt_ HMODULE hModule,
  514. _In_ REFGUID rguid,
  515. _Out_opt_ DWORD *pcbData);
  516. _Writable_bytes_(*pcbData)
  517. _Readable_bytes_(*pcbData)
  518. _Success_(return != NULL)
  519. PVOID WINAPI DetourFindPayloadEx(_In_ REFGUID rguid,
  520. _Out_opt_ DWORD *pcbData);
  521. DWORD WINAPI DetourGetSizeOfPayloads(_In_opt_ HMODULE hModule);
  522. BOOL WINAPI DetourFreePayload(_In_ PVOID pvData);
  523. ///////////////////////////////////////////////// Persistent Binary Functions.
  524. //
  525. PDETOUR_BINARY WINAPI DetourBinaryOpen(_In_ HANDLE hFile);
  526. _Writable_bytes_(*pcbData)
  527. _Readable_bytes_(*pcbData)
  528. _Success_(return != NULL)
  529. PVOID WINAPI DetourBinaryEnumeratePayloads(_In_ PDETOUR_BINARY pBinary,
  530. _Out_opt_ GUID *pGuid,
  531. _Out_ DWORD *pcbData,
  532. _Inout_ DWORD *pnIterator);
  533. _Writable_bytes_(*pcbData)
  534. _Readable_bytes_(*pcbData)
  535. _Success_(return != NULL)
  536. PVOID WINAPI DetourBinaryFindPayload(_In_ PDETOUR_BINARY pBinary,
  537. _In_ REFGUID rguid,
  538. _Out_ DWORD *pcbData);
  539. PVOID WINAPI DetourBinarySetPayload(_In_ PDETOUR_BINARY pBinary,
  540. _In_ REFGUID rguid,
  541. _In_reads_opt_(cbData) PVOID pData,
  542. _In_ DWORD cbData);
  543. BOOL WINAPI DetourBinaryDeletePayload(_In_ PDETOUR_BINARY pBinary, _In_ REFGUID rguid);
  544. BOOL WINAPI DetourBinaryPurgePayloads(_In_ PDETOUR_BINARY pBinary);
  545. BOOL WINAPI DetourBinaryResetImports(_In_ PDETOUR_BINARY pBinary);
  546. BOOL WINAPI DetourBinaryEditImports(_In_ PDETOUR_BINARY pBinary,
  547. _In_opt_ PVOID pContext,
  548. _In_opt_ PF_DETOUR_BINARY_BYWAY_CALLBACK pfByway,
  549. _In_opt_ PF_DETOUR_BINARY_FILE_CALLBACK pfFile,
  550. _In_opt_ PF_DETOUR_BINARY_SYMBOL_CALLBACK pfSymbol,
  551. _In_opt_ PF_DETOUR_BINARY_COMMIT_CALLBACK pfCommit);
  552. BOOL WINAPI DetourBinaryWrite(_In_ PDETOUR_BINARY pBinary, _In_ HANDLE hFile);
  553. BOOL WINAPI DetourBinaryClose(_In_ PDETOUR_BINARY pBinary);
  554. /////////////////////////////////////////////////// Create Process & Load Dll.
  555. //
  556. _Success_(return != NULL)
  557. PVOID WINAPI DetourFindRemotePayload(_In_ HANDLE hProcess,
  558. _In_ REFGUID rguid,
  559. _Out_opt_ DWORD *pcbData);
  560. typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEA)(
  561. _In_opt_ LPCSTR lpApplicationName,
  562. _Inout_opt_ LPSTR lpCommandLine,
  563. _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
  564. _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  565. _In_ BOOL bInheritHandles,
  566. _In_ DWORD dwCreationFlags,
  567. _In_opt_ LPVOID lpEnvironment,
  568. _In_opt_ LPCSTR lpCurrentDirectory,
  569. _In_ LPSTARTUPINFOA lpStartupInfo,
  570. _Out_ LPPROCESS_INFORMATION lpProcessInformation);
  571. typedef BOOL (WINAPI *PDETOUR_CREATE_PROCESS_ROUTINEW)(
  572. _In_opt_ LPCWSTR lpApplicationName,
  573. _Inout_opt_ LPWSTR lpCommandLine,
  574. _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
  575. _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  576. _In_ BOOL bInheritHandles,
  577. _In_ DWORD dwCreationFlags,
  578. _In_opt_ LPVOID lpEnvironment,
  579. _In_opt_ LPCWSTR lpCurrentDirectory,
  580. _In_ LPSTARTUPINFOW lpStartupInfo,
  581. _Out_ LPPROCESS_INFORMATION lpProcessInformation);
  582. BOOL WINAPI DetourCreateProcessWithDllA(_In_opt_ LPCSTR lpApplicationName,
  583. _Inout_opt_ LPSTR lpCommandLine,
  584. _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
  585. _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  586. _In_ BOOL bInheritHandles,
  587. _In_ DWORD dwCreationFlags,
  588. _In_opt_ LPVOID lpEnvironment,
  589. _In_opt_ LPCSTR lpCurrentDirectory,
  590. _In_ LPSTARTUPINFOA lpStartupInfo,
  591. _Out_ LPPROCESS_INFORMATION lpProcessInformation,
  592. _In_ LPCSTR lpDllName,
  593. _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
  594. BOOL WINAPI DetourCreateProcessWithDllW(_In_opt_ LPCWSTR lpApplicationName,
  595. _Inout_opt_ LPWSTR lpCommandLine,
  596. _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
  597. _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  598. _In_ BOOL bInheritHandles,
  599. _In_ DWORD dwCreationFlags,
  600. _In_opt_ LPVOID lpEnvironment,
  601. _In_opt_ LPCWSTR lpCurrentDirectory,
  602. _In_ LPSTARTUPINFOW lpStartupInfo,
  603. _Out_ LPPROCESS_INFORMATION lpProcessInformation,
  604. _In_ LPCSTR lpDllName,
  605. _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
  606. #ifdef UNICODE
  607. #define DetourCreateProcessWithDll DetourCreateProcessWithDllW
  608. #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEW
  609. #else
  610. #define DetourCreateProcessWithDll DetourCreateProcessWithDllA
  611. #define PDETOUR_CREATE_PROCESS_ROUTINE PDETOUR_CREATE_PROCESS_ROUTINEA
  612. #endif // !UNICODE
  613. BOOL WINAPI DetourCreateProcessWithDllExA(_In_opt_ LPCSTR lpApplicationName,
  614. _Inout_opt_ LPSTR lpCommandLine,
  615. _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
  616. _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  617. _In_ BOOL bInheritHandles,
  618. _In_ DWORD dwCreationFlags,
  619. _In_opt_ LPVOID lpEnvironment,
  620. _In_opt_ LPCSTR lpCurrentDirectory,
  621. _In_ LPSTARTUPINFOA lpStartupInfo,
  622. _Out_ LPPROCESS_INFORMATION lpProcessInformation,
  623. _In_ LPCSTR lpDllName,
  624. _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
  625. BOOL WINAPI DetourCreateProcessWithDllExW(_In_opt_ LPCWSTR lpApplicationName,
  626. _Inout_opt_ LPWSTR lpCommandLine,
  627. _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
  628. _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  629. _In_ BOOL bInheritHandles,
  630. _In_ DWORD dwCreationFlags,
  631. _In_opt_ LPVOID lpEnvironment,
  632. _In_opt_ LPCWSTR lpCurrentDirectory,
  633. _In_ LPSTARTUPINFOW lpStartupInfo,
  634. _Out_ LPPROCESS_INFORMATION lpProcessInformation,
  635. _In_ LPCSTR lpDllName,
  636. _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
  637. #ifdef UNICODE
  638. #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExW
  639. #else
  640. #define DetourCreateProcessWithDllEx DetourCreateProcessWithDllExA
  641. #endif // !UNICODE
  642. BOOL WINAPI DetourCreateProcessWithDllsA(_In_opt_ LPCSTR lpApplicationName,
  643. _Inout_opt_ LPSTR lpCommandLine,
  644. _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
  645. _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  646. _In_ BOOL bInheritHandles,
  647. _In_ DWORD dwCreationFlags,
  648. _In_opt_ LPVOID lpEnvironment,
  649. _In_opt_ LPCSTR lpCurrentDirectory,
  650. _In_ LPSTARTUPINFOA lpStartupInfo,
  651. _Out_ LPPROCESS_INFORMATION lpProcessInformation,
  652. _In_ DWORD nDlls,
  653. _In_reads_(nDlls) LPCSTR *rlpDlls,
  654. _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
  655. BOOL WINAPI DetourCreateProcessWithDllsW(_In_opt_ LPCWSTR lpApplicationName,
  656. _Inout_opt_ LPWSTR lpCommandLine,
  657. _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
  658. _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
  659. _In_ BOOL bInheritHandles,
  660. _In_ DWORD dwCreationFlags,
  661. _In_opt_ LPVOID lpEnvironment,
  662. _In_opt_ LPCWSTR lpCurrentDirectory,
  663. _In_ LPSTARTUPINFOW lpStartupInfo,
  664. _Out_ LPPROCESS_INFORMATION lpProcessInformation,
  665. _In_ DWORD nDlls,
  666. _In_reads_(nDlls) LPCSTR *rlpDlls,
  667. _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
  668. #ifdef UNICODE
  669. #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsW
  670. #else
  671. #define DetourCreateProcessWithDlls DetourCreateProcessWithDllsA
  672. #endif // !UNICODE
  673. BOOL WINAPI DetourProcessViaHelperA(_In_ DWORD dwTargetPid,
  674. _In_ LPCSTR lpDllName,
  675. _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
  676. BOOL WINAPI DetourProcessViaHelperW(_In_ DWORD dwTargetPid,
  677. _In_ LPCSTR lpDllName,
  678. _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
  679. #ifdef UNICODE
  680. #define DetourProcessViaHelper DetourProcessViaHelperW
  681. #else
  682. #define DetourProcessViaHelper DetourProcessViaHelperA
  683. #endif // !UNICODE
  684. BOOL WINAPI DetourProcessViaHelperDllsA(_In_ DWORD dwTargetPid,
  685. _In_ DWORD nDlls,
  686. _In_reads_(nDlls) LPCSTR *rlpDlls,
  687. _In_ PDETOUR_CREATE_PROCESS_ROUTINEA pfCreateProcessA);
  688. BOOL WINAPI DetourProcessViaHelperDllsW(_In_ DWORD dwTargetPid,
  689. _In_ DWORD nDlls,
  690. _In_reads_(nDlls) LPCSTR *rlpDlls,
  691. _In_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW);
  692. #ifdef UNICODE
  693. #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsW
  694. #else
  695. #define DetourProcessViaHelperDlls DetourProcessViaHelperDllsA
  696. #endif // !UNICODE
  697. BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess,
  698. _In_reads_(nDlls) LPCSTR *rlpDlls,
  699. _In_ DWORD nDlls);
  700. BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess,
  701. _In_ HMODULE hImage,
  702. _In_ BOOL bIs32Bit,
  703. _In_reads_(nDlls) LPCSTR *rlpDlls,
  704. _In_ DWORD nDlls);
  705. BOOL WINAPI DetourCopyPayloadToProcess(_In_ HANDLE hProcess,
  706. _In_ REFGUID rguid,
  707. _In_reads_bytes_(cbData) LPCVOID pvData,
  708. _In_ DWORD cbData);
  709. _Success_(return != NULL)
  710. PVOID WINAPI DetourCopyPayloadToProcessEx(_In_ HANDLE hProcess,
  711. _In_ REFGUID rguid,
  712. _In_reads_bytes_(cbData) LPCVOID pvData,
  713. _In_ DWORD cbData);
  714. BOOL WINAPI DetourRestoreAfterWith(VOID);
  715. BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData,
  716. _In_ DWORD cbData);
  717. BOOL WINAPI DetourIsHelperProcess(VOID);
  718. VOID CALLBACK DetourFinishHelperProcess(_In_ HWND,
  719. _In_ HINSTANCE,
  720. _In_ LPSTR,
  721. _In_ INT);
  722. //
  723. //////////////////////////////////////////////////////////////////////////////
  724. #ifdef __cplusplus
  725. }
  726. #endif // __cplusplus
  727. /////////////////////////////////////////////////// Type-safe overloads for C++
  728. //
  729. #if __cplusplus >= 201103L || _MSVC_LANG >= 201103L
  730. #include <type_traits>
  731. template<typename T>
  732. struct DetoursIsFunctionPointer : std::false_type {};
  733. template<typename T>
  734. struct DetoursIsFunctionPointer<T*> : std::is_function<typename std::remove_pointer<T>::type> {};
  735. template<
  736. typename T,
  737. typename std::enable_if<DetoursIsFunctionPointer<T>::value, int>::type = 0>
  738. LONG DetourAttach(_Inout_ T *ppPointer,
  739. _In_ T pDetour) noexcept
  740. {
  741. return DetourAttach(
  742. reinterpret_cast<void**>(ppPointer),
  743. reinterpret_cast<void*>(pDetour));
  744. }
  745. template<
  746. typename T,
  747. typename std::enable_if<DetoursIsFunctionPointer<T>::value, int>::type = 0>
  748. LONG DetourAttachEx(_Inout_ T *ppPointer,
  749. _In_ T pDetour,
  750. _Out_opt_ PDETOUR_TRAMPOLINE *ppRealTrampoline,
  751. _Out_opt_ T *ppRealTarget,
  752. _Out_opt_ T *ppRealDetour) noexcept
  753. {
  754. return DetourAttachEx(
  755. reinterpret_cast<void**>(ppPointer),
  756. reinterpret_cast<void*>(pDetour),
  757. ppRealTrampoline,
  758. reinterpret_cast<void**>(ppRealTarget),
  759. reinterpret_cast<void**>(ppRealDetour));
  760. }
  761. template<
  762. typename T,
  763. typename std::enable_if<DetoursIsFunctionPointer<T>::value, int>::type = 0>
  764. LONG DetourDetach(_Inout_ T *ppPointer,
  765. _In_ T pDetour) noexcept
  766. {
  767. return DetourDetach(
  768. reinterpret_cast<void**>(ppPointer),
  769. reinterpret_cast<void*>(pDetour));
  770. }
  771. #endif // __cplusplus >= 201103L || _MSVC_LANG >= 201103L
  772. //
  773. //////////////////////////////////////////////////////////////////////////////
  774. //////////////////////////////////////////////// Detours Internal Definitions.
  775. //
  776. #ifdef __cplusplus
  777. #ifdef DETOURS_INTERNAL
  778. #define NOTHROW
  779. // #define NOTHROW (nothrow)
  780. //////////////////////////////////////////////////////////////////////////////
  781. //
  782. #if (_MSC_VER < 1299) && !defined(__GNUC__)
  783. #include <imagehlp.h>
  784. typedef IMAGEHLP_MODULE IMAGEHLP_MODULE64;
  785. typedef PIMAGEHLP_MODULE PIMAGEHLP_MODULE64;
  786. typedef IMAGEHLP_SYMBOL SYMBOL_INFO;
  787. typedef PIMAGEHLP_SYMBOL PSYMBOL_INFO;
  788. static inline
  789. LONG InterlockedCompareExchange(_Inout_ LONG *ptr, _In_ LONG nval, _In_ LONG oval)
  790. {
  791. return (LONG)::InterlockedCompareExchange((PVOID*)ptr, (PVOID)nval, (PVOID)oval);
  792. }
  793. #else
  794. #pragma warning(push)
  795. #pragma warning(disable:4091) // empty typedef
  796. #include <dbghelp.h>
  797. #pragma warning(pop)
  798. #endif
  799. #ifdef IMAGEAPI // defined by DBGHELP.H
  800. typedef LPAPI_VERSION (NTAPI *PF_ImagehlpApiVersionEx)(_In_ LPAPI_VERSION AppVersion);
  801. typedef BOOL (NTAPI *PF_SymInitialize)(_In_ HANDLE hProcess,
  802. _In_opt_ LPCSTR UserSearchPath,
  803. _In_ BOOL fInvadeProcess);
  804. typedef DWORD (NTAPI *PF_SymSetOptions)(_In_ DWORD SymOptions);
  805. typedef DWORD (NTAPI *PF_SymGetOptions)(VOID);
  806. typedef DWORD64 (NTAPI *PF_SymLoadModule64)(_In_ HANDLE hProcess,
  807. _In_opt_ HANDLE hFile,
  808. _In_opt_ LPSTR ImageName,
  809. _In_opt_ LPSTR ModuleName,
  810. _In_ DWORD64 BaseOfDll,
  811. _In_ DWORD SizeOfDll);
  812. typedef BOOL (NTAPI *PF_SymGetModuleInfo64)(_In_ HANDLE hProcess,
  813. _In_ DWORD64 qwAddr,
  814. _Out_ PIMAGEHLP_MODULE64 ModuleInfo);
  815. typedef BOOL (NTAPI *PF_SymFromName)(_In_ HANDLE hProcess,
  816. _In_ LPSTR Name,
  817. _Out_ PSYMBOL_INFO Symbol);
  818. typedef struct _DETOUR_SYM_INFO
  819. {
  820. HANDLE hProcess;
  821. HMODULE hDbgHelp;
  822. PF_ImagehlpApiVersionEx pfImagehlpApiVersionEx;
  823. PF_SymInitialize pfSymInitialize;
  824. PF_SymSetOptions pfSymSetOptions;
  825. PF_SymGetOptions pfSymGetOptions;
  826. PF_SymLoadModule64 pfSymLoadModule64;
  827. PF_SymGetModuleInfo64 pfSymGetModuleInfo64;
  828. PF_SymFromName pfSymFromName;
  829. } DETOUR_SYM_INFO, *PDETOUR_SYM_INFO;
  830. PDETOUR_SYM_INFO DetourLoadImageHlp(VOID);
  831. #endif // IMAGEAPI
  832. #if defined(_INC_STDIO) && !defined(_CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS)
  833. #error detours.h must be included before stdio.h (or at least define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS earlier)
  834. #endif
  835. #define _CRT_STDIO_ARBITRARY_WIDE_SPECIFIERS 1
  836. #ifdef _DEBUG
  837. int Detour_AssertExprWithFunctionName(int reportType, const char* filename, int linenumber, const char* FunctionName, const char* msg);
  838. #define DETOUR_ASSERT_EXPR_WITH_FUNCTION(expr, msg) \
  839. (void) ((expr) || \
  840. (1 != Detour_AssertExprWithFunctionName(_CRT_ASSERT, __FILE__, __LINE__,__FUNCTION__, msg)) || \
  841. (_CrtDbgBreak(), 0))
  842. #define DETOUR_ASSERT(expr) DETOUR_ASSERT_EXPR_WITH_FUNCTION((expr), #expr)
  843. #else// _DEBUG
  844. #define DETOUR_ASSERT(expr)
  845. #endif// _DEBUG
  846. #ifndef DETOUR_TRACE
  847. #if DETOUR_DEBUG
  848. #define DETOUR_TRACE(x) printf x
  849. #define DETOUR_BREAK() __debugbreak()
  850. #include <stdio.h>
  851. #include <limits.h>
  852. #else
  853. #define DETOUR_TRACE(x)
  854. #define DETOUR_BREAK()
  855. #endif
  856. #endif
  857. #if 1 || defined(DETOURS_IA64)
  858. //
  859. // IA64 instructions are 41 bits, 3 per bundle, plus 5 bit bundle template => 128 bits per bundle.
  860. //
  861. #define DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE (3)
  862. #define DETOUR_IA64_TEMPLATE_OFFSET (0)
  863. #define DETOUR_IA64_TEMPLATE_SIZE (5)
  864. #define DETOUR_IA64_INSTRUCTION_SIZE (41)
  865. #define DETOUR_IA64_INSTRUCTION0_OFFSET (DETOUR_IA64_TEMPLATE_SIZE)
  866. #define DETOUR_IA64_INSTRUCTION1_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE)
  867. #define DETOUR_IA64_INSTRUCTION2_OFFSET (DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTION_SIZE + DETOUR_IA64_INSTRUCTION_SIZE)
  868. C_ASSERT(DETOUR_IA64_TEMPLATE_SIZE + DETOUR_IA64_INSTRUCTIONS_PER_BUNDLE * DETOUR_IA64_INSTRUCTION_SIZE == 128);
  869. __declspec(align(16)) struct DETOUR_IA64_BUNDLE
  870. {
  871. public:
  872. union
  873. {
  874. BYTE data[16];
  875. UINT64 wide[2];
  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. protected:
  894. static const DETOUR_IA64_METADATA s_rceCopyTable[33];
  895. UINT RelocateBundle(_Inout_ DETOUR_IA64_BUNDLE* pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const;
  896. bool RelocateInstruction(_Inout_ DETOUR_IA64_BUNDLE* pDst,
  897. _In_ BYTE slot,
  898. _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra) const;
  899. // 120 112 104 96 88 80 72 64 56 48 40 32 24 16 8 0
  900. // f. e. d. c. b. a. 9. 8. 7. 6. 5. 4. 3. 2. 1. 0.
  901. // 00
  902. // f.e. d.c. b.a. 9.8. 7.6. 5.4. 3.2. 1.0.
  903. // 0000 0000 0000 0000 0000 0000 0000 001f : Template [4..0]
  904. // 0000 0000 0000 0000 0000 03ff ffff ffe0 : Zero [ 41.. 5]
  905. // 0000 0000 0000 0000 0000 3c00 0000 0000 : Zero [ 45.. 42]
  906. // 0000 0000 0007 ffff ffff c000 0000 0000 : One [ 82.. 46]
  907. // 0000 0000 0078 0000 0000 0000 0000 0000 : One [ 86.. 83]
  908. // 0fff ffff ff80 0000 0000 0000 0000 0000 : Two [123.. 87]
  909. // f000 0000 0000 0000 0000 0000 0000 0000 : Two [127..124]
  910. BYTE GetTemplate() const;
  911. // Get 4 bit opcodes.
  912. BYTE GetInst0() const;
  913. BYTE GetInst1() const;
  914. BYTE GetInst2() const;
  915. BYTE GetUnit(BYTE slot) const;
  916. BYTE GetUnit0() const;
  917. BYTE GetUnit1() const;
  918. BYTE GetUnit2() const;
  919. // Get 37 bit data.
  920. UINT64 GetData0() const;
  921. UINT64 GetData1() const;
  922. UINT64 GetData2() const;
  923. // Get/set the full 41 bit instructions.
  924. UINT64 GetInstruction(BYTE slot) const;
  925. UINT64 GetInstruction0() const;
  926. UINT64 GetInstruction1() const;
  927. UINT64 GetInstruction2() const;
  928. void SetInstruction(BYTE slot, UINT64 instruction);
  929. void SetInstruction0(UINT64 instruction);
  930. void SetInstruction1(UINT64 instruction);
  931. void SetInstruction2(UINT64 instruction);
  932. // Get/set bitfields.
  933. static UINT64 GetBits(UINT64 Value, UINT64 Offset, UINT64 Count);
  934. static UINT64 SetBits(UINT64 Value, UINT64 Offset, UINT64 Count, UINT64 Field);
  935. // Get specific read-only fields.
  936. static UINT64 GetOpcode(UINT64 instruction); // 4bit opcode
  937. static UINT64 GetX(UINT64 instruction); // 1bit opcode extension
  938. static UINT64 GetX3(UINT64 instruction); // 3bit opcode extension
  939. static UINT64 GetX6(UINT64 instruction); // 6bit opcode extension
  940. // Get/set specific fields.
  941. static UINT64 GetImm7a(UINT64 instruction);
  942. static UINT64 SetImm7a(UINT64 instruction, UINT64 imm7a);
  943. static UINT64 GetImm13c(UINT64 instruction);
  944. static UINT64 SetImm13c(UINT64 instruction, UINT64 imm13c);
  945. static UINT64 GetSignBit(UINT64 instruction);
  946. static UINT64 SetSignBit(UINT64 instruction, UINT64 signBit);
  947. static UINT64 GetImm20a(UINT64 instruction);
  948. static UINT64 SetImm20a(UINT64 instruction, UINT64 imm20a);
  949. static UINT64 GetImm20b(UINT64 instruction);
  950. static UINT64 SetImm20b(UINT64 instruction, UINT64 imm20b);
  951. static UINT64 SignExtend(UINT64 Value, UINT64 Offset);
  952. BOOL IsMovlGp() const;
  953. VOID SetInst(BYTE Slot, BYTE nInst);
  954. VOID SetInst0(BYTE nInst);
  955. VOID SetInst1(BYTE nInst);
  956. VOID SetInst2(BYTE nInst);
  957. VOID SetData(BYTE Slot, UINT64 nData);
  958. VOID SetData0(UINT64 nData);
  959. VOID SetData1(UINT64 nData);
  960. VOID SetData2(UINT64 nData);
  961. BOOL SetNop(BYTE Slot);
  962. BOOL SetNop0();
  963. BOOL SetNop1();
  964. BOOL SetNop2();
  965. public:
  966. BOOL IsBrl() const;
  967. VOID SetBrl();
  968. VOID SetBrl(UINT64 target);
  969. UINT64 GetBrlTarget() const;
  970. VOID SetBrlTarget(UINT64 target);
  971. VOID SetBrlImm(UINT64 imm);
  972. UINT64 GetBrlImm() const;
  973. UINT64 GetMovlGp() const;
  974. VOID SetMovlGp(UINT64 gp);
  975. VOID SetStop();
  976. UINT Copy(_Out_ DETOUR_IA64_BUNDLE *pDst, _Inout_opt_ DETOUR_IA64_BUNDLE* pBundleExtra = NULL) const;
  977. };
  978. #endif // DETOURS_IA64
  979. #ifdef DETOURS_ARM
  980. #define DETOURS_PFUNC_TO_PBYTE(p) ((PBYTE)(((ULONG_PTR)(p)) & ~(ULONG_PTR)1))
  981. #define DETOURS_PBYTE_TO_PFUNC(p) ((PBYTE)(((ULONG_PTR)(p)) | (ULONG_PTR)1))
  982. #endif // DETOURS_ARM
  983. //////////////////////////////////////////////////////////////////////////////
  984. #ifdef __cplusplus
  985. extern "C" {
  986. #endif // __cplusplus
  987. #define DETOUR_OFFLINE_LIBRARY(x) \
  988. PVOID WINAPI DetourCopyInstruction##x(_In_opt_ PVOID pDst, \
  989. _Inout_opt_ PVOID *ppDstPool, \
  990. _In_ PVOID pSrc, \
  991. _Out_opt_ PVOID *ppTarget, \
  992. _Out_opt_ LONG *plExtra); \
  993. \
  994. BOOL WINAPI DetourSetCodeModule##x(_In_ HMODULE hModule, \
  995. _In_ BOOL fLimitReferencesToModule); \
  996. DETOUR_OFFLINE_LIBRARY(X86)
  997. DETOUR_OFFLINE_LIBRARY(X64)
  998. DETOUR_OFFLINE_LIBRARY(ARM)
  999. DETOUR_OFFLINE_LIBRARY(ARM64)
  1000. DETOUR_OFFLINE_LIBRARY(IA64)
  1001. #undef DETOUR_OFFLINE_LIBRARY
  1002. //////////////////////////////////////////////////////////////////////////////
  1003. //
  1004. // Helpers for manipulating page protection.
  1005. //
  1006. _Success_(return != FALSE)
  1007. BOOL WINAPI DetourVirtualProtectSameExecuteEx(_In_ HANDLE hProcess,
  1008. _In_ PVOID pAddress,
  1009. _In_ SIZE_T nSize,
  1010. _In_ DWORD dwNewProtect,
  1011. _Out_ PDWORD pdwOldProtect);
  1012. _Success_(return != FALSE)
  1013. BOOL WINAPI DetourVirtualProtectSameExecute(_In_ PVOID pAddress,
  1014. _In_ SIZE_T nSize,
  1015. _In_ DWORD dwNewProtect,
  1016. _Out_ PDWORD pdwOldProtect);
  1017. // Detours must depend only on kernel32.lib, so we cannot use IsEqualGUID
  1018. BOOL WINAPI DetourAreSameGuid(_In_ REFGUID left, _In_ REFGUID right);
  1019. #ifdef __cplusplus
  1020. }
  1021. #endif // __cplusplus
  1022. //////////////////////////////////////////////////////////////////////////////
  1023. #define MM_ALLOCATION_GRANULARITY 0x10000
  1024. //////////////////////////////////////////////////////////////////////////////
  1025. #endif // DETOURS_INTERNAL
  1026. #endif // __cplusplus
  1027. #endif // _DETOURS_H_
  1028. //
  1029. //////////////////////////////////////////////////////////////// End of File.