disasm.cpp 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Detours Disassembler (disasm.cpp of detours.lib)
  4. //
  5. // Microsoft Research Detours Package, Version 2.1.
  6. //
  7. // Copyright (c) Microsoft Corporation. All rights reserved.
  8. //
  9. #include <windows.h>
  10. #include <limits.h>
  11. // #define DETOUR_DEBUG 1
  12. #define DETOURS_INTERNAL
  13. #include "detours.h"
  14. #define DETOURS_X86
  15. #if !defined(DETOURS_X86) && !defined(DETOURS_X64) && !defined(DETOURS_IA64)
  16. #error Must define one of DETOURS_X86, DETOURS_X64, or DETOURS_IA64
  17. #endif
  18. #undef ASSERT
  19. #define ASSERT(x)
  20. //////////////////////////////////////////////////////////////////////////////
  21. //
  22. // Function:
  23. // DetourCopyInstructionEx(PVOID pDst,
  24. // PVOID pSrc,
  25. // PVOID *ppTarget,
  26. // LONG *plExtra)
  27. // Purpose:
  28. // Copy a single instruction from pSrc to pDst.
  29. //
  30. // Arguments:
  31. // pDst:
  32. // Destination address for the instruction. May be NULL in which
  33. // case DetourCopyInstruction is used to measure an instruction.
  34. // If not NULL then the source instruction is copied to the
  35. // destination instruction and any relative arguments are adjusted.
  36. // pSrc:
  37. // Source address of the instruction.
  38. // ppTarget:
  39. // Out parameter for any target instruction address pointed to by
  40. // the instruction. For example, a branch or a jump insruction has
  41. // a target, but a load or store instruction doesn't. A target is
  42. // another instruction that may be executed as a result of this
  43. // instruction. ppTarget may be NULL.
  44. // plExtra:
  45. // Out parameter for the number of extra bytes needed by the
  46. // instruction to reach the target. For example, lExtra = 3 if the
  47. // instruction had an 8-bit relative offset, but needs a 32-bit
  48. // relative offset.
  49. //
  50. // Returns:
  51. // Returns the address of the next instruction (following in the source)
  52. // instruction. By subtracting pSrc from the return value, the caller
  53. // can determinte the size of the instruction copied.
  54. //
  55. // Comments:
  56. // By following the pTarget, the caller can follow alternate
  57. // instruction streams. However, it is not always possible to determine
  58. // the target based on static analysis. For example, the destination of
  59. // a jump relative to a register cannot be determined from just the
  60. // instruction stream. The output value, pTarget, can have any of the
  61. // following outputs:
  62. // DETOUR_INSTRUCTION_TARGET_NONE:
  63. // The instruction has no targets.
  64. // DETOUR_INSTRUCTION_TARGET_DYNAMIC:
  65. // The instruction has a non-deterministic (dynamic) target.
  66. // (i.e. the jump is to an address held in a register.)
  67. // Address: The instruction has the specified target.
  68. //
  69. // When copying instructions, DetourCopyInstruction insures that any
  70. // targets remain constant. It does so by adjusting any IP relative
  71. // offsets.
  72. //
  73. PVOID WINAPI DetourCopyInstruction( PVOID pDst , PVOID pSrc , PVOID * ppTarget )
  74. {
  75. return DetourCopyInstructionEx( pDst,pSrc,ppTarget,NULL );
  76. }
  77. //////////////////////////////////////////////////// X86 and X64 Disassembler.
  78. //
  79. // Includes full support for all x86 chips prior to the Pentium III.
  80. //
  81. #if defined(DETOURS_X64) || defined(DETOURS_X86)
  82. class CDetourDis
  83. {
  84. public:
  85. CDetourDis( PBYTE * ppbTarget , LONG * plExtra );
  86. PBYTE CopyInstruction( PBYTE pbDst , PBYTE pbSrc );
  87. static BOOL SanityCheckSystem();
  88. public:
  89. struct COPYENTRY;
  90. typedef const COPYENTRY * REFCOPYENTRY;
  91. typedef PBYTE ( CDetourDis::* COPYFUNC )( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  92. enum
  93. {
  94. DYNAMIC = 0x1u ,
  95. ADDRESS = 0x2u ,
  96. NOENLARGE = 0x4u ,
  97. RAX = 0x8u ,
  98. SIB = 0x10u ,
  99. RIP = 0x20u ,
  100. NOTSIB = 0x0fu,
  101. };
  102. struct COPYENTRY
  103. {
  104. ULONG nOpcode : 8; // Opcode
  105. ULONG nFixedSize : 4; // Fixed size of opcode
  106. ULONG nFixedSize16 : 4; // Fixed size when 16 bit operand
  107. ULONG nModOffset : 4; // Offset to mod/rm byte (0=none)
  108. LONG nRelOffset : 4; // Offset to relative target.
  109. LONG nTargetBack : 4; // Offset back to absolute or rip target
  110. ULONG nFlagBits : 4; // Flags for DYNAMIC, etc.
  111. COPYFUNC pfCopy; // Function pointer.
  112. };
  113. protected:
  114. // These macros define common uses of nFixedSize..pfCopy.
  115. #define ENTRY_CopyBytes1 1, 1, 0, 0, 0, 0, &CDetourDis::CopyBytes
  116. #define ENTRY_CopyBytes1Dynamic 1, 1, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
  117. #define ENTRY_CopyBytes2 2, 2, 0, 0, 0, 0, &CDetourDis::CopyBytes
  118. #define ENTRY_CopyBytes2Jump 2, 2, 0, 1, 0, 0, &CDetourDis::CopyBytes
  119. #define ENTRY_CopyBytes2CantJump 2, 2, 0, 1, 0, NOENLARGE, &CDetourDis::CopyBytes
  120. #define ENTRY_CopyBytes2Dynamic 2, 2, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
  121. #define ENTRY_CopyBytes3 3, 3, 0, 0, 0, 0, &CDetourDis::CopyBytes
  122. #define ENTRY_CopyBytes3Dynamic 3, 3, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
  123. #define ENTRY_CopyBytes3Or5 5, 3, 0, 0, 0, 0, &CDetourDis::CopyBytes
  124. #define ENTRY_CopyBytes3Or5Rax 5, 3, 0, 0, 0, RAX, &CDetourDis::CopyBytes
  125. #define ENTRY_CopyBytes3Or5Target 5, 3, 0, 1, 0, 0, &CDetourDis::CopyBytes
  126. #define ENTRY_CopyBytes5Or7Dynamic 7, 5, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
  127. #define ENTRY_CopyBytes3Or5Address 5, 3, 0, 0, 0, ADDRESS, &CDetourDis::CopyBytes
  128. #define ENTRY_CopyBytes4 4, 4, 0, 0, 0, 0, &CDetourDis::CopyBytes
  129. #define ENTRY_CopyBytes5 5, 5, 0, 0, 0, 0, &CDetourDis::CopyBytes
  130. #define ENTRY_CopyBytes7 7, 7, 0, 0, 0, 0, &CDetourDis::CopyBytes
  131. #define ENTRY_CopyBytes2Mod 2, 2, 1, 0, 0, 0, &CDetourDis::CopyBytes
  132. #define ENTRY_CopyBytes2Mod1 3, 3, 1, 0, 1, 0, &CDetourDis::CopyBytes
  133. #define ENTRY_CopyBytes2ModOperand 6, 4, 1, 0, 4, 0, &CDetourDis::CopyBytes
  134. #define ENTRY_CopyBytes3Mod 3, 3, 2, 0, 0, 0, &CDetourDis::CopyBytes
  135. #define ENTRY_CopyBytesPrefix 1, 1, 0, 0, 0, 0, &CDetourDis::CopyBytesPrefix
  136. #define ENTRY_CopyBytesRax 1, 1, 0, 0, 0, 0, &CDetourDis::CopyBytesRax
  137. #define ENTRY_Copy0F 1, 1, 0, 0, 0, 0, &CDetourDis::Copy0F
  138. #define ENTRY_Copy66 1, 1, 0, 0, 0, 0, &CDetourDis::Copy66
  139. #define ENTRY_Copy67 1, 1, 0, 0, 0, 0, &CDetourDis::Copy67
  140. #define ENTRY_CopyF6 0, 0, 0, 0, 0, 0, &CDetourDis::CopyF6
  141. #define ENTRY_CopyF7 0, 0, 0, 0, 0, 0, &CDetourDis::CopyF7
  142. #define ENTRY_CopyFF 0, 0, 0, 0, 0, 0, &CDetourDis::CopyFF
  143. #define ENTRY_Invalid 1, 1, 0, 0, 0, 0, &CDetourDis::Invalid
  144. #define ENTRY_End 0, 0, 0, 0, 0, 0, NULL
  145. PBYTE CopyBytes( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  146. PBYTE CopyBytesPrefix( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  147. PBYTE CopyBytesRax( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  148. PBYTE Invalid( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  149. PBYTE AdjustTarget( PBYTE pbDst , PBYTE pbSrc , LONG cbOp , LONG cbTargetOffset , LONG cbTargetSize );
  150. protected:
  151. PBYTE Copy0F( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  152. PBYTE Copy66( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  153. PBYTE Copy67( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  154. PBYTE CopyF6( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  155. PBYTE CopyF7( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  156. PBYTE CopyFF( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
  157. protected:
  158. static const COPYENTRY s_rceCopyTable[257];
  159. static const COPYENTRY s_rceCopyTable0F[257];
  160. static const BYTE s_rbModRm[256];
  161. protected:
  162. BOOL m_bOperandOverride;
  163. BOOL m_bAddressOverride;
  164. BOOL m_bRaxOverride;
  165. PBYTE * m_ppbTarget;
  166. LONG * m_plExtra;
  167. LONG m_lScratchExtra;
  168. PBYTE m_pbScratchTarget;
  169. BYTE m_rbScratchDst[64];
  170. };
  171. PVOID WINAPI DetourCopyInstructionEx( PVOID pDst , PVOID pSrc , PVOID * ppTarget , LONG * plExtra )
  172. {
  173. CDetourDis oDetourDisasm ( ( PBYTE * ) ppTarget,plExtra );
  174. return oDetourDisasm.CopyInstruction( ( PBYTE ) pDst,( PBYTE ) pSrc );
  175. }
  176. /////////////////////////////////////////////////////////// Disassembler Code.
  177. //
  178. CDetourDis::CDetourDis( PBYTE * ppbTarget , LONG * plExtra )
  179. {
  180. m_bOperandOverride = FALSE;
  181. m_bAddressOverride = FALSE;
  182. m_bRaxOverride = FALSE;
  183. m_ppbTarget = ppbTarget ? ppbTarget : &m_pbScratchTarget;
  184. m_plExtra = plExtra ? plExtra : &m_lScratchExtra;
  185. *m_ppbTarget = ( PBYTE ) DETOUR_INSTRUCTION_TARGET_NONE;
  186. *m_plExtra = 0;
  187. }
  188. PBYTE CDetourDis::CopyInstruction( PBYTE pbDst , PBYTE pbSrc )
  189. {
  190. // Configure scratch areas if real areas are not available.
  191. if ( NULL == pbDst )
  192. {
  193. pbDst = m_rbScratchDst;
  194. }
  195. if ( NULL == pbSrc )
  196. {
  197. // We can't copy a non-existent instruction.
  198. SetLastError( ERROR_INVALID_DATA );
  199. return NULL;
  200. }
  201. // Figure out how big the instruction is, do the appropriate copy,
  202. // and figure out what the target of the instruction is if any.
  203. //
  204. REFCOPYENTRY pEntry = &s_rceCopyTable[pbSrc[0]];
  205. return ( this->*pEntry->pfCopy ) ( pEntry,pbDst,pbSrc );
  206. }
  207. PBYTE CDetourDis::CopyBytes( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  208. {
  209. #ifdef DETOURS_X64
  210. #error Feature not supported in this release.
  211. #else
  212. LONG nBytesFixed = ( pEntry->nFlagBits & ADDRESS ) ? ( m_bAddressOverride ? pEntry->nFixedSize16 : pEntry->nFixedSize ) : ( m_bOperandOverride ? pEntry->nFixedSize16 : pEntry->nFixedSize );
  213. #endif
  214. LONG nBytes = nBytesFixed;
  215. LONG nRelOffset = pEntry->nRelOffset;
  216. LONG cbTarget = nBytes - nRelOffset;
  217. if ( pEntry->nModOffset > 0 )
  218. {
  219. BYTE bModRm = pbSrc[pEntry->nModOffset];
  220. BYTE bFlags = s_rbModRm[bModRm];
  221. nBytes += bFlags & NOTSIB;
  222. if ( bFlags & SIB )
  223. {
  224. BYTE bSib = pbSrc[pEntry->nModOffset + 1];
  225. if ( ( bSib & 0x07 ) == 0x05 )
  226. {
  227. if ( ( bModRm & 0xc0 ) == 0x00 )
  228. {
  229. nBytes += 4;
  230. }
  231. else if ( ( bModRm & 0xc0 ) == 0x40 )
  232. {
  233. nBytes += 1;
  234. }
  235. else if ( ( bModRm & 0xc0 ) == 0x80 )
  236. {
  237. nBytes += 4;
  238. }
  239. }
  240. cbTarget = nBytes - nRelOffset;
  241. }
  242. else if ( bFlags & RIP )
  243. {
  244. #ifdef DETOURS_X64
  245. #error Feature not supported in this release.
  246. #endif
  247. }
  248. }
  249. CopyMemory( pbDst,pbSrc,nBytes );
  250. if ( nRelOffset )
  251. {
  252. *m_ppbTarget = AdjustTarget( pbDst,pbSrc,nBytesFixed,nRelOffset,cbTarget );
  253. #ifdef DETOURS_X64
  254. #error Feature not supported in this release.
  255. #endif
  256. }
  257. if ( pEntry->nFlagBits & NOENLARGE )
  258. {
  259. *m_plExtra = -*m_plExtra;
  260. }
  261. if ( pEntry->nFlagBits & DYNAMIC )
  262. {
  263. *m_ppbTarget = ( PBYTE ) DETOUR_INSTRUCTION_TARGET_DYNAMIC;
  264. }
  265. return pbSrc + nBytes;
  266. }
  267. PBYTE CDetourDis::CopyBytesPrefix( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  268. {
  269. CopyBytes( pEntry,pbDst,pbSrc );
  270. pEntry = &s_rceCopyTable[pbSrc[1]];
  271. return ( this->*pEntry->pfCopy ) ( pEntry,pbDst + 1,pbSrc + 1 );
  272. }
  273. PBYTE CDetourDis::CopyBytesRax( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  274. {
  275. CopyBytes( pEntry,pbDst,pbSrc );
  276. if ( *pbSrc & 0x8 )
  277. {
  278. m_bRaxOverride = TRUE;
  279. }
  280. pEntry = &s_rceCopyTable[pbSrc[1]];
  281. return ( this->*pEntry->pfCopy ) ( pEntry,pbDst + 1,pbSrc + 1 );
  282. }
  283. PBYTE CDetourDis::AdjustTarget( PBYTE pbDst , PBYTE pbSrc , LONG cbOp , LONG cbTargetOffset , LONG cbTargetSize )
  284. {
  285. PBYTE pbTarget = NULL;
  286. PVOID pvTargetAddr = &pbDst[cbTargetOffset];
  287. LONG_PTR nOldOffset = 0;
  288. switch ( cbTargetSize )
  289. {
  290. case 1:
  291. nOldOffset = ( LONG_PTR ) * ( CHAR * & ) pvTargetAddr;
  292. break;
  293. case 2:
  294. nOldOffset = ( LONG_PTR ) * ( SHORT * & ) pvTargetAddr;
  295. break;
  296. case 4:
  297. nOldOffset = ( LONG_PTR ) * ( LONG * & ) pvTargetAddr;
  298. break;
  299. case 8:
  300. nOldOffset = ( LONG_PTR ) * ( LONG_PTR * & ) pvTargetAddr;
  301. break;
  302. default:
  303. ASSERT( !"cbTargetSize is invalid." );
  304. break;
  305. }
  306. pbTarget = pbSrc + cbOp + nOldOffset;
  307. LONG_PTR nNewOffset = nOldOffset - ( pbDst - pbSrc );
  308. switch ( cbTargetSize )
  309. {
  310. case 1:
  311. *( CHAR * & ) pvTargetAddr = ( CHAR ) nNewOffset;
  312. if ( nNewOffset < SCHAR_MIN || nNewOffset > SCHAR_MAX )
  313. {
  314. *m_plExtra = sizeof( ULONG_PTR ) - 1;
  315. }
  316. break;
  317. case 2:
  318. *( SHORT * & ) pvTargetAddr = ( SHORT ) nNewOffset;
  319. if ( nNewOffset < SHRT_MIN || nNewOffset > SHRT_MAX )
  320. {
  321. *m_plExtra = sizeof( ULONG_PTR ) - 2;
  322. }
  323. break;
  324. case 4:
  325. *( LONG * & ) pvTargetAddr = ( LONG ) nNewOffset;
  326. if ( nNewOffset < LONG_MIN || nNewOffset > LONG_MAX )
  327. {
  328. *m_plExtra = sizeof( ULONG_PTR ) - 4;
  329. }
  330. break;
  331. case 8:
  332. *( LONG_PTR * & ) pvTargetAddr = ( LONG_PTR ) nNewOffset;
  333. break;
  334. }
  335. ASSERT( pbDst + cbOp + nNewOffset == pbTarget );
  336. return pbTarget;
  337. }
  338. PBYTE CDetourDis::Invalid( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  339. {
  340. ( void ) pbDst;
  341. ( void ) pEntry;
  342. ASSERT( !"Invalid Instruction" );
  343. return pbSrc + 1;
  344. }
  345. ////////////////////////////////////////////////////// Individual Bytes Codes.
  346. //
  347. PBYTE CDetourDis::Copy0F( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  348. {
  349. CopyBytes( pEntry,pbDst,pbSrc );
  350. pEntry = &s_rceCopyTable0F[pbSrc[1]];
  351. return ( this->*pEntry->pfCopy ) ( pEntry,pbDst + 1,pbSrc + 1 );
  352. }
  353. PBYTE CDetourDis::Copy66( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  354. {
  355. // Operand-size override prefix
  356. m_bOperandOverride = TRUE;
  357. return CopyBytesPrefix( pEntry,pbDst,pbSrc );
  358. }
  359. PBYTE CDetourDis::Copy67( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  360. {
  361. // Address size override prefix
  362. m_bAddressOverride = TRUE;
  363. return CopyBytesPrefix( pEntry,pbDst,pbSrc );
  364. }
  365. PBYTE CDetourDis::CopyF6( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  366. {
  367. ( void ) pEntry;
  368. // TEST BYTE /0
  369. if ( 0x00 == ( 0x38 & pbSrc[1] ) )
  370. {
  371. // reg(bits 543) of ModR/M == 0
  372. const COPYENTRY ce ={0xf6, ENTRY_CopyBytes2Mod1};
  373. return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
  374. }
  375. // DIV /6
  376. // IDIV /7
  377. // IMUL /5
  378. // MUL /4
  379. // NEG /3
  380. // NOT /2
  381. const COPYENTRY ce ={0xf6, ENTRY_CopyBytes2Mod};
  382. return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
  383. }
  384. PBYTE CDetourDis::CopyF7( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  385. {
  386. ( void ) pEntry;
  387. // TEST WORD /0
  388. if ( 0x00 == ( 0x38 & pbSrc[1] ) )
  389. {
  390. // reg(bits 543) of ModR/M == 0
  391. const COPYENTRY ce ={0xf7, ENTRY_CopyBytes2ModOperand};
  392. return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
  393. }
  394. // DIV /6
  395. // IDIV /7
  396. // IMUL /5
  397. // MUL /4
  398. // NEG /3
  399. // NOT /2
  400. const COPYENTRY ce ={0xf7, ENTRY_CopyBytes2Mod};
  401. return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
  402. }
  403. PBYTE CDetourDis::CopyFF( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
  404. {
  405. // CALL /2
  406. // CALL /3
  407. // INC /0
  408. // JMP /4
  409. // JMP /5
  410. // PUSH /6
  411. ( void ) pEntry;
  412. if ( 0x15 == pbSrc[1] || 0x25 == pbSrc[1] )
  413. {
  414. // CALL [], JMP []
  415. #ifdef DETOURS_X64
  416. #error Feature not supported in this release.
  417. #else
  418. PBYTE * ppbTarget = *( PBYTE ** ) &pbSrc[2];
  419. *m_ppbTarget = *ppbTarget;
  420. #endif
  421. }
  422. else if ( 0x10 == ( 0x38 & pbSrc[1] ) || // CALL /2 --> reg(bits 543) of ModR/M == 010
  423. 0x18 == ( 0x38 & pbSrc[1] ) || // CALL /3 --> reg(bits 543) of ModR/M == 011
  424. 0x20 == ( 0x38 & pbSrc[1] ) || // JMP /4 --> reg(bits 543) of ModR/M == 100
  425. 0x28 == ( 0x38 & pbSrc[1] ) // JMP /5 --> reg(bits 543) of ModR/M == 101
  426. )
  427. {
  428. *m_ppbTarget = ( PBYTE ) DETOUR_INSTRUCTION_TARGET_DYNAMIC;
  429. }
  430. const COPYENTRY ce ={0xff, ENTRY_CopyBytes2Mod};
  431. return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
  432. }
  433. ///////////////////////////////////////////////////////// Disassembler Tables.
  434. //
  435. const BYTE CDetourDis::s_rbModRm[256] ={0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, // 0x
  436. 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, // 1x
  437. 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, // 2x
  438. 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, // 3x
  439. 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 4x
  440. 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 5x
  441. 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 6x
  442. 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 7x
  443. 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, // 8x
  444. 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, // 9x
  445. 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, // Ax
  446. 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, // Bx
  447. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
  448. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
  449. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
  450. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // Fx
  451. };
  452. const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable[257] ={{ 0x00, ENTRY_CopyBytes2Mod }, // ADD /r
  453. { 0x01, ENTRY_CopyBytes2Mod }, // ADD /r
  454. { 0x02, ENTRY_CopyBytes2Mod }, // ADD /r
  455. { 0x03, ENTRY_CopyBytes2Mod }, // ADD /r
  456. { 0x04, ENTRY_CopyBytes2 }, // ADD ib
  457. { 0x05, ENTRY_CopyBytes3Or5 }, // ADD iw
  458. { 0x06, ENTRY_CopyBytes1 }, // PUSH
  459. { 0x07, ENTRY_CopyBytes1 }, // POP
  460. { 0x08, ENTRY_CopyBytes2Mod }, // OR /r
  461. { 0x09, ENTRY_CopyBytes2Mod }, // OR /r
  462. { 0x0A, ENTRY_CopyBytes2Mod }, // OR /r
  463. { 0x0B, ENTRY_CopyBytes2Mod }, // OR /r
  464. { 0x0C, ENTRY_CopyBytes2 }, // OR ib
  465. { 0x0D, ENTRY_CopyBytes3Or5 }, // OR iw
  466. { 0x0E, ENTRY_CopyBytes1 }, // PUSH
  467. { 0x0F, ENTRY_Copy0F }, // Extension Ops
  468. { 0x10, ENTRY_CopyBytes2Mod }, // ADC /r
  469. { 0x11, ENTRY_CopyBytes2Mod }, // ADC /r
  470. { 0x12, ENTRY_CopyBytes2Mod }, // ADC /r
  471. { 0x13, ENTRY_CopyBytes2Mod }, // ADC /r
  472. { 0x14, ENTRY_CopyBytes2 }, // ADC ib
  473. { 0x15, ENTRY_CopyBytes3Or5 }, // ADC id
  474. { 0x16, ENTRY_CopyBytes1 }, // PUSH
  475. { 0x17, ENTRY_CopyBytes1 }, // POP
  476. { 0x18, ENTRY_CopyBytes2Mod }, // SBB /r
  477. { 0x19, ENTRY_CopyBytes2Mod }, // SBB /r
  478. { 0x1A, ENTRY_CopyBytes2Mod }, // SBB /r
  479. { 0x1B, ENTRY_CopyBytes2Mod }, // SBB /r
  480. { 0x1C, ENTRY_CopyBytes2 }, // SBB ib
  481. { 0x1D, ENTRY_CopyBytes3Or5 }, // SBB id
  482. { 0x1E, ENTRY_CopyBytes1 }, // PUSH
  483. { 0x1F, ENTRY_CopyBytes1 }, // POP
  484. { 0x20, ENTRY_CopyBytes2Mod }, // AND /r
  485. { 0x21, ENTRY_CopyBytes2Mod }, // AND /r
  486. { 0x22, ENTRY_CopyBytes2Mod }, // AND /r
  487. { 0x23, ENTRY_CopyBytes2Mod }, // AND /r
  488. { 0x24, ENTRY_CopyBytes2 }, // AND ib
  489. { 0x25, ENTRY_CopyBytes3Or5 }, // AND id
  490. { 0x26, ENTRY_CopyBytesPrefix }, // ES prefix
  491. { 0x27, ENTRY_CopyBytes1 }, // DAA
  492. { 0x28, ENTRY_CopyBytes2Mod }, // SUB /r
  493. { 0x29, ENTRY_CopyBytes2Mod }, // SUB /r
  494. { 0x2A, ENTRY_CopyBytes2Mod }, // SUB /r
  495. { 0x2B, ENTRY_CopyBytes2Mod }, // SUB /r
  496. { 0x2C, ENTRY_CopyBytes2 }, // SUB ib
  497. { 0x2D, ENTRY_CopyBytes3Or5 }, // SUB id
  498. { 0x2E, ENTRY_CopyBytesPrefix }, // CS prefix
  499. { 0x2F, ENTRY_CopyBytes1 }, // DAS
  500. { 0x30, ENTRY_CopyBytes2Mod }, // XOR /r
  501. { 0x31, ENTRY_CopyBytes2Mod }, // XOR /r
  502. { 0x32, ENTRY_CopyBytes2Mod }, // XOR /r
  503. { 0x33, ENTRY_CopyBytes2Mod }, // XOR /r
  504. { 0x34, ENTRY_CopyBytes2 }, // XOR ib
  505. { 0x35, ENTRY_CopyBytes3Or5 }, // XOR id
  506. { 0x36, ENTRY_CopyBytesPrefix }, // SS prefix
  507. { 0x37, ENTRY_CopyBytes1 }, // AAA
  508. { 0x38, ENTRY_CopyBytes2Mod }, // CMP /r
  509. { 0x39, ENTRY_CopyBytes2Mod }, // CMP /r
  510. { 0x3A, ENTRY_CopyBytes2Mod }, // CMP /r
  511. { 0x3B, ENTRY_CopyBytes2Mod }, // CMP /r
  512. { 0x3C, ENTRY_CopyBytes2 }, // CMP ib
  513. { 0x3D, ENTRY_CopyBytes3Or5 }, // CMP id
  514. { 0x3E, ENTRY_CopyBytesPrefix }, // DS prefix
  515. { 0x3F, ENTRY_CopyBytes1 }, // AAS
  516. #ifdef DETOURS_X64 // For Rax Prefix
  517. #error Feature not supported in this release.
  518. #else
  519. { 0x40, ENTRY_CopyBytes1 }, // INC
  520. { 0x41, ENTRY_CopyBytes1 }, // INC
  521. { 0x42, ENTRY_CopyBytes1 }, // INC
  522. { 0x43, ENTRY_CopyBytes1 }, // INC
  523. { 0x44, ENTRY_CopyBytes1 }, // INC
  524. { 0x45, ENTRY_CopyBytes1 }, // INC
  525. { 0x46, ENTRY_CopyBytes1 }, // INC
  526. { 0x47, ENTRY_CopyBytes1 }, // INC
  527. { 0x48, ENTRY_CopyBytes1 }, // DEC
  528. { 0x49, ENTRY_CopyBytes1 }, // DEC
  529. { 0x4A, ENTRY_CopyBytes1 }, // DEC
  530. { 0x4B, ENTRY_CopyBytes1 }, // DEC
  531. { 0x4C, ENTRY_CopyBytes1 }, // DEC
  532. { 0x4D, ENTRY_CopyBytes1 }, // DEC
  533. { 0x4E, ENTRY_CopyBytes1 }, // DEC
  534. { 0x4F, ENTRY_CopyBytes1 }, // DEC
  535. #endif
  536. { 0x50, ENTRY_CopyBytes1 }, // PUSH
  537. { 0x51, ENTRY_CopyBytes1 }, // PUSH
  538. { 0x52, ENTRY_CopyBytes1 }, // PUSH
  539. { 0x53, ENTRY_CopyBytes1 }, // PUSH
  540. { 0x54, ENTRY_CopyBytes1 }, // PUSH
  541. { 0x55, ENTRY_CopyBytes1 }, // PUSH
  542. { 0x56, ENTRY_CopyBytes1 }, // PUSH
  543. { 0x57, ENTRY_CopyBytes1 }, // PUSH
  544. { 0x58, ENTRY_CopyBytes1 }, // POP
  545. { 0x59, ENTRY_CopyBytes1 }, // POP
  546. { 0x5A, ENTRY_CopyBytes1 }, // POP
  547. { 0x5B, ENTRY_CopyBytes1 }, // POP
  548. { 0x5C, ENTRY_CopyBytes1 }, // POP
  549. { 0x5D, ENTRY_CopyBytes1 }, // POP
  550. { 0x5E, ENTRY_CopyBytes1 }, // POP
  551. { 0x5F, ENTRY_CopyBytes1 }, // POP
  552. { 0x60, ENTRY_CopyBytes1 }, // PUSHAD
  553. { 0x61, ENTRY_CopyBytes1 }, // POPAD
  554. { 0x62, ENTRY_CopyBytes2Mod }, // BOUND /r
  555. { 0x63, ENTRY_CopyBytes2Mod }, // ARPL /r
  556. { 0x64, ENTRY_CopyBytesPrefix }, // FS prefix
  557. { 0x65, ENTRY_CopyBytesPrefix }, // GS prefix
  558. { 0x66, ENTRY_Copy66 }, // Operand Prefix
  559. { 0x67, ENTRY_Copy67 }, // Address Prefix
  560. { 0x68, ENTRY_CopyBytes3Or5 }, // PUSH
  561. { 0x69, ENTRY_CopyBytes2ModOperand }, //
  562. { 0x6A, ENTRY_CopyBytes2 }, // PUSH
  563. { 0x6B, ENTRY_CopyBytes2Mod1 }, // IMUL /r ib
  564. { 0x6C, ENTRY_CopyBytes1 }, // INS
  565. { 0x6D, ENTRY_CopyBytes1 }, // INS
  566. { 0x6E, ENTRY_CopyBytes1 }, // OUTS/OUTSB
  567. { 0x6F, ENTRY_CopyBytes1 }, // OUTS/OUTSW
  568. { 0x70, ENTRY_CopyBytes2Jump }, // JO
  569. { 0x71, ENTRY_CopyBytes2Jump }, // JNO
  570. { 0x72, ENTRY_CopyBytes2Jump }, // JB/JC/JNAE
  571. { 0x73, ENTRY_CopyBytes2Jump }, // JAE/JNB/JNC
  572. { 0x74, ENTRY_CopyBytes2Jump }, // JE/JZ
  573. { 0x75, ENTRY_CopyBytes2Jump }, // JNE/JNZ
  574. { 0x76, ENTRY_CopyBytes2Jump }, // JBE/JNA
  575. { 0x77, ENTRY_CopyBytes2Jump }, // JA/JNBE
  576. { 0x78, ENTRY_CopyBytes2Jump }, // JS
  577. { 0x79, ENTRY_CopyBytes2Jump }, // JNS
  578. { 0x7A, ENTRY_CopyBytes2Jump }, // JP/JPE
  579. { 0x7B, ENTRY_CopyBytes2Jump }, // JNP/JPO
  580. { 0x7C, ENTRY_CopyBytes2Jump }, // JL/JNGE
  581. { 0x7D, ENTRY_CopyBytes2Jump }, // JGE/JNL
  582. { 0x7E, ENTRY_CopyBytes2Jump }, // JLE/JNG
  583. { 0x7F, ENTRY_CopyBytes2Jump }, // JG/JNLE
  584. { 0x80, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc.s
  585. { 0x81, ENTRY_CopyBytes2ModOperand }, //
  586. { 0x82, ENTRY_CopyBytes2 }, // MOV al,x
  587. { 0x83, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc.
  588. { 0x84, ENTRY_CopyBytes2Mod }, // TEST /r
  589. { 0x85, ENTRY_CopyBytes2Mod }, // TEST /r
  590. { 0x86, ENTRY_CopyBytes2Mod }, // XCHG /r @todo
  591. { 0x87, ENTRY_CopyBytes2Mod }, // XCHG /r @todo
  592. { 0x88, ENTRY_CopyBytes2Mod }, // MOV /r
  593. { 0x89, ENTRY_CopyBytes2Mod }, // MOV /r
  594. { 0x8A, ENTRY_CopyBytes2Mod }, // MOV /r
  595. { 0x8B, ENTRY_CopyBytes2Mod }, // MOV /r
  596. { 0x8C, ENTRY_CopyBytes2Mod }, // MOV /r
  597. { 0x8D, ENTRY_CopyBytes2Mod }, // LEA /r
  598. { 0x8E, ENTRY_CopyBytes2Mod }, // MOV /r
  599. { 0x8F, ENTRY_CopyBytes2Mod }, // POP /0
  600. { 0x90, ENTRY_CopyBytes1 }, // NOP
  601. { 0x91, ENTRY_CopyBytes1 }, // XCHG
  602. { 0x92, ENTRY_CopyBytes1 }, // XCHG
  603. { 0x93, ENTRY_CopyBytes1 }, // XCHG
  604. { 0x94, ENTRY_CopyBytes1 }, // XCHG
  605. { 0x95, ENTRY_CopyBytes1 }, // XCHG
  606. { 0x96, ENTRY_CopyBytes1 }, // XCHG
  607. { 0x97, ENTRY_CopyBytes1 }, // XCHG
  608. { 0x98, ENTRY_CopyBytes1 }, // CWDE
  609. { 0x99, ENTRY_CopyBytes1 }, // CDQ
  610. { 0x9A, ENTRY_CopyBytes5Or7Dynamic }, // CALL cp
  611. { 0x9B, ENTRY_CopyBytes1 }, // WAIT/FWAIT
  612. { 0x9C, ENTRY_CopyBytes1 }, // PUSHFD
  613. { 0x9D, ENTRY_CopyBytes1 }, // POPFD
  614. { 0x9E, ENTRY_CopyBytes1 }, // SAHF
  615. { 0x9F, ENTRY_CopyBytes1 }, // LAHF
  616. { 0xA0, ENTRY_CopyBytes3Or5Address }, // MOV
  617. { 0xA1, ENTRY_CopyBytes3Or5Address }, // MOV
  618. { 0xA2, ENTRY_CopyBytes3Or5Address }, // MOV
  619. { 0xA3, ENTRY_CopyBytes3Or5Address }, // MOV
  620. { 0xA4, ENTRY_CopyBytes1 }, // MOVS
  621. { 0xA5, ENTRY_CopyBytes1 }, // MOVS/MOVSD
  622. { 0xA6, ENTRY_CopyBytes1 }, // CMPS/CMPSB
  623. { 0xA7, ENTRY_CopyBytes1 }, // CMPS/CMPSW
  624. { 0xA8, ENTRY_CopyBytes2 }, // TEST
  625. { 0xA9, ENTRY_CopyBytes3Or5 }, // TEST
  626. { 0xAA, ENTRY_CopyBytes1 }, // STOS/STOSB
  627. { 0xAB, ENTRY_CopyBytes1 }, // STOS/STOSW
  628. { 0xAC, ENTRY_CopyBytes1 }, // LODS/LODSB
  629. { 0xAD, ENTRY_CopyBytes1 }, // LODS/LODSW
  630. { 0xAE, ENTRY_CopyBytes1 }, // SCAS/SCASB
  631. { 0xAF, ENTRY_CopyBytes1 }, // SCAS/SCASD
  632. { 0xB0, ENTRY_CopyBytes2 }, // MOV B0+rb
  633. { 0xB1, ENTRY_CopyBytes2 }, // MOV B0+rb
  634. { 0xB2, ENTRY_CopyBytes2 }, // MOV B0+rb
  635. { 0xB3, ENTRY_CopyBytes2 }, // MOV B0+rb
  636. { 0xB4, ENTRY_CopyBytes2 }, // MOV B0+rb
  637. { 0xB5, ENTRY_CopyBytes2 }, // MOV B0+rb
  638. { 0xB6, ENTRY_CopyBytes2 }, // MOV B0+rb
  639. { 0xB7, ENTRY_CopyBytes2 }, // MOV B0+rb
  640. { 0xB8, ENTRY_CopyBytes3Or5Rax }, // MOV B8+rb
  641. { 0xB9, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
  642. { 0xBA, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
  643. { 0xBB, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
  644. { 0xBC, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
  645. { 0xBD, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
  646. { 0xBE, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
  647. { 0xBF, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
  648. { 0xC0, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc.
  649. { 0xC1, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc.
  650. { 0xC2, ENTRY_CopyBytes3 }, // RET
  651. { 0xC3, ENTRY_CopyBytes1 }, // RET
  652. { 0xC4, ENTRY_CopyBytes2Mod }, // LES
  653. { 0xC5, ENTRY_CopyBytes2Mod }, // LDS
  654. { 0xC6, ENTRY_CopyBytes2Mod1 }, // MOV
  655. { 0xC7, ENTRY_CopyBytes2ModOperand }, // MOV
  656. { 0xC8, ENTRY_CopyBytes4 }, // ENTER
  657. { 0xC9, ENTRY_CopyBytes1 }, // LEAVE
  658. { 0xCA, ENTRY_CopyBytes3Dynamic }, // RET
  659. { 0xCB, ENTRY_CopyBytes1Dynamic }, // RET
  660. { 0xCC, ENTRY_CopyBytes1Dynamic }, // INT 3
  661. { 0xCD, ENTRY_CopyBytes2Dynamic }, // INT ib
  662. { 0xCE, ENTRY_CopyBytes1Dynamic }, // INTO
  663. { 0xCF, ENTRY_CopyBytes1Dynamic }, // IRET
  664. { 0xD0, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
  665. { 0xD1, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
  666. { 0xD2, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
  667. { 0xD3, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
  668. { 0xD4, ENTRY_CopyBytes2 }, // AAM
  669. { 0xD5, ENTRY_CopyBytes2 }, // AAD
  670. { 0xD6, ENTRY_Invalid }, //
  671. { 0xD7, ENTRY_CopyBytes1 }, // XLAT/XLATB
  672. { 0xD8, ENTRY_CopyBytes2Mod }, // FADD, etc.
  673. { 0xD9, ENTRY_CopyBytes2Mod }, // F2XM1, etc.
  674. { 0xDA, ENTRY_CopyBytes2Mod }, // FLADD, etc.
  675. { 0xDB, ENTRY_CopyBytes2Mod }, // FCLEX, etc.
  676. { 0xDC, ENTRY_CopyBytes2Mod }, // FADD/0, etc.
  677. { 0xDD, ENTRY_CopyBytes2Mod }, // FFREE, etc.
  678. { 0xDE, ENTRY_CopyBytes2Mod }, // FADDP, etc.
  679. { 0xDF, ENTRY_CopyBytes2Mod }, // FBLD/4, etc.
  680. { 0xE0, ENTRY_CopyBytes2CantJump }, // LOOPNE cb
  681. { 0xE1, ENTRY_CopyBytes2CantJump }, // LOOPE cb
  682. { 0xE2, ENTRY_CopyBytes2CantJump }, // LOOP cb
  683. { 0xE3, ENTRY_CopyBytes2Jump }, // JCXZ/JECXZ
  684. { 0xE4, ENTRY_CopyBytes2 }, // IN ib
  685. { 0xE5, ENTRY_CopyBytes2 }, // IN id
  686. { 0xE6, ENTRY_CopyBytes2 }, // OUT ib
  687. { 0xE7, ENTRY_CopyBytes2 }, // OUT ib
  688. { 0xE8, ENTRY_CopyBytes3Or5Target }, // CALL cd
  689. { 0xE9, ENTRY_CopyBytes3Or5Target }, // JMP cd
  690. { 0xEA, ENTRY_CopyBytes5Or7Dynamic }, // JMP cp
  691. { 0xEB, ENTRY_CopyBytes2Jump }, // JMP cb
  692. { 0xEC, ENTRY_CopyBytes1 }, // IN ib
  693. { 0xED, ENTRY_CopyBytes1 }, // IN id
  694. { 0xEE, ENTRY_CopyBytes1 }, // OUT
  695. { 0xEF, ENTRY_CopyBytes1 }, // OUT
  696. { 0xF0, ENTRY_CopyBytesPrefix }, // LOCK prefix
  697. { 0xF1, ENTRY_Invalid }, //
  698. { 0xF2, ENTRY_CopyBytesPrefix }, // REPNE prefix
  699. { 0xF3, ENTRY_CopyBytesPrefix }, // REPE prefix
  700. { 0xF4, ENTRY_CopyBytes1 }, // HLT
  701. { 0xF5, ENTRY_CopyBytes1 }, // CMC
  702. { 0xF6, ENTRY_CopyF6 }, // TEST/0, DIV/6
  703. { 0xF7, ENTRY_CopyF7 }, // TEST/0, DIV/6
  704. { 0xF8, ENTRY_CopyBytes1 }, // CLC
  705. { 0xF9, ENTRY_CopyBytes1 }, // STC
  706. { 0xFA, ENTRY_CopyBytes1 }, // CLI
  707. { 0xFB, ENTRY_CopyBytes1 }, // STI
  708. { 0xFC, ENTRY_CopyBytes1 }, // CLD
  709. { 0xFD, ENTRY_CopyBytes1 }, // STD
  710. { 0xFE, ENTRY_CopyBytes2Mod }, // DEC/1,INC/0
  711. { 0xFF, ENTRY_CopyFF }, // CALL/2
  712. { 0, ENTRY_End }, };
  713. const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable0F[257] ={{ 0x00, ENTRY_CopyBytes2Mod }, // LLDT/2, etc.
  714. { 0x01, ENTRY_CopyBytes2Mod }, // INVLPG/7, etc.
  715. { 0x02, ENTRY_CopyBytes2Mod }, // LAR/r
  716. { 0x03, ENTRY_CopyBytes2Mod }, // LSL/r
  717. { 0x04, ENTRY_Invalid }, // _04
  718. { 0x05, ENTRY_Invalid }, // _05
  719. { 0x06, ENTRY_CopyBytes2 }, // CLTS
  720. { 0x07, ENTRY_Invalid }, // _07
  721. { 0x08, ENTRY_CopyBytes2 }, // INVD
  722. { 0x09, ENTRY_CopyBytes2 }, // WBINVD
  723. { 0x0A, ENTRY_Invalid }, // _0A
  724. { 0x0B, ENTRY_CopyBytes2 }, // UD2
  725. { 0x0C, ENTRY_Invalid }, // _0C
  726. { 0x0D, ENTRY_CopyBytes2Mod }, // PREFETCH
  727. { 0x0E, ENTRY_CopyBytes2 }, // FEMMS
  728. { 0x0F, ENTRY_CopyBytes3Mod }, // 3DNow Opcodes
  729. { 0x10, ENTRY_CopyBytes2Mod }, // MOVSS MOVUPD MOVSD
  730. { 0x11, ENTRY_CopyBytes2Mod }, // MOVSS MOVUPD MOVSD
  731. { 0x12, ENTRY_CopyBytes2Mod }, // MOVLPD
  732. { 0x13, ENTRY_CopyBytes2Mod }, // MOVLPD
  733. { 0x14, ENTRY_CopyBytes2Mod }, // UNPCKLPD
  734. { 0x15, ENTRY_CopyBytes2Mod }, // UNPCKHPD
  735. { 0x16, ENTRY_CopyBytes2Mod }, // MOVHPD
  736. { 0x17, ENTRY_CopyBytes2Mod }, // MOVHPD
  737. { 0x18, ENTRY_CopyBytes2Mod }, // PREFETCHINTA...
  738. { 0x19, ENTRY_Invalid }, // _19
  739. { 0x1A, ENTRY_Invalid }, // _1A
  740. { 0x1B, ENTRY_Invalid }, // _1B
  741. { 0x1C, ENTRY_Invalid }, // _1C
  742. { 0x1D, ENTRY_Invalid }, // _1D
  743. { 0x1E, ENTRY_Invalid }, // _1E
  744. { 0x1F, ENTRY_Invalid }, // _1F
  745. { 0x20, ENTRY_CopyBytes2Mod }, // MOV/r
  746. { 0x21, ENTRY_CopyBytes2Mod }, // MOV/r
  747. { 0x22, ENTRY_CopyBytes2Mod }, // MOV/r
  748. { 0x23, ENTRY_CopyBytes2Mod }, // MOV/r
  749. { 0x24, ENTRY_Invalid }, // _24
  750. { 0x25, ENTRY_Invalid }, // _25
  751. { 0x26, ENTRY_Invalid }, // _26
  752. { 0x27, ENTRY_Invalid }, // _27
  753. { 0x28, ENTRY_CopyBytes2Mod }, // MOVAPS MOVAPD
  754. { 0x29, ENTRY_CopyBytes2Mod }, // MOVAPS MOVAPD
  755. { 0x2A, ENTRY_CopyBytes2Mod }, // CVPI2PS &
  756. { 0x2B, ENTRY_CopyBytes2Mod }, // MOVNTPS MOVNTPD
  757. { 0x2C, ENTRY_CopyBytes2Mod }, // CVTTPS2PI &
  758. { 0x2D, ENTRY_CopyBytes2Mod }, // CVTPS2PI &
  759. { 0x2E, ENTRY_CopyBytes2Mod }, // UCOMISS UCOMISD
  760. { 0x2F, ENTRY_CopyBytes2Mod }, // COMISS COMISD
  761. { 0x30, ENTRY_CopyBytes2 }, // WRMSR
  762. { 0x31, ENTRY_CopyBytes2 }, // RDTSC
  763. { 0x32, ENTRY_CopyBytes2 }, // RDMSR
  764. { 0x33, ENTRY_CopyBytes2 }, // RDPMC
  765. { 0x34, ENTRY_CopyBytes2 }, // SYSENTER
  766. { 0x35, ENTRY_CopyBytes2 }, // SYSEXIT
  767. { 0x36, ENTRY_Invalid }, // _36
  768. { 0x37, ENTRY_Invalid }, // _37
  769. { 0x38, ENTRY_Invalid }, // _38
  770. { 0x39, ENTRY_Invalid }, // _39
  771. { 0x3A, ENTRY_Invalid }, // _3A
  772. { 0x3B, ENTRY_Invalid }, // _3B
  773. { 0x3C, ENTRY_Invalid }, // _3C
  774. { 0x3D, ENTRY_Invalid }, // _3D
  775. { 0x3E, ENTRY_Invalid }, // _3E
  776. { 0x3F, ENTRY_Invalid }, // _3F
  777. { 0x40, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40)
  778. { 0x41, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41)
  779. { 0x42, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVNE (0F 42)
  780. { 0x43, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB (0F 43)
  781. { 0x44, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44)
  782. { 0x45, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45)
  783. { 0x46, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46)
  784. { 0x47, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47)
  785. { 0x48, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48)
  786. { 0x49, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49)
  787. { 0x4A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A)
  788. { 0x4B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B)
  789. { 0x4C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C)
  790. { 0x4D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D)
  791. { 0x4E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E)
  792. { 0x4F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F)
  793. { 0x50, ENTRY_CopyBytes2Mod }, // MOVMSKPD MOVMSKPD
  794. { 0x51, ENTRY_CopyBytes2Mod }, // SQRTPS &
  795. { 0x52, ENTRY_CopyBytes2Mod }, // RSQRTTS RSQRTPS
  796. { 0x53, ENTRY_CopyBytes2Mod }, // RCPPS RCPSS
  797. { 0x54, ENTRY_CopyBytes2Mod }, // ANDPS ANDPD
  798. { 0x55, ENTRY_CopyBytes2Mod }, // ANDNPS ANDNPD
  799. { 0x56, ENTRY_CopyBytes2Mod }, // ORPS ORPD
  800. { 0x57, ENTRY_CopyBytes2Mod }, // XORPS XORPD
  801. { 0x58, ENTRY_CopyBytes2Mod }, // ADDPS &
  802. { 0x59, ENTRY_CopyBytes2Mod }, // MULPS &
  803. { 0x5A, ENTRY_CopyBytes2Mod }, // CVTPS2PD &
  804. { 0x5B, ENTRY_CopyBytes2Mod }, // CVTDQ2PS &
  805. { 0x5C, ENTRY_CopyBytes2Mod }, // SUBPS &
  806. { 0x5D, ENTRY_CopyBytes2Mod }, // MINPS &
  807. { 0x5E, ENTRY_CopyBytes2Mod }, // DIVPS &
  808. { 0x5F, ENTRY_CopyBytes2Mod }, // MASPS &
  809. { 0x60, ENTRY_CopyBytes2Mod }, // PUNPCKLBW/r
  810. { 0x61, ENTRY_CopyBytes2Mod }, // PUNPCKLWD/r
  811. { 0x62, ENTRY_CopyBytes2Mod }, // PUNPCKLWD/r
  812. { 0x63, ENTRY_CopyBytes2Mod }, // PACKSSWB/r
  813. { 0x64, ENTRY_CopyBytes2Mod }, // PCMPGTB/r
  814. { 0x65, ENTRY_CopyBytes2Mod }, // PCMPGTW/r
  815. { 0x66, ENTRY_CopyBytes2Mod }, // PCMPGTD/r
  816. { 0x67, ENTRY_CopyBytes2Mod }, // PACKUSWB/r
  817. { 0x68, ENTRY_CopyBytes2Mod }, // PUNPCKHBW/r
  818. { 0x69, ENTRY_CopyBytes2Mod }, // PUNPCKHWD/r
  819. { 0x6A, ENTRY_CopyBytes2Mod }, // PUNPCKHDQ/r
  820. { 0x6B, ENTRY_CopyBytes2Mod }, // PACKSSDW/r
  821. { 0x6C, ENTRY_CopyBytes2Mod }, // PUNPCKLQDQ
  822. { 0x6D, ENTRY_CopyBytes2Mod }, // PUNPCKHQDQ
  823. { 0x6E, ENTRY_CopyBytes2Mod }, // MOVD/r
  824. { 0x6F, ENTRY_CopyBytes2Mod }, // MOV/r
  825. { 0x70, ENTRY_CopyBytes2Mod1 }, // PSHUFW/r ib
  826. { 0x71, ENTRY_CopyBytes2Mod1 }, // PSLLW/6 ib,PSRAW/4 ib,PSRLW/2 ib
  827. { 0x72, ENTRY_CopyBytes2Mod1 }, // PSLLD/6 ib,PSRAD/4 ib,PSRLD/2 ib
  828. { 0x73, ENTRY_CopyBytes2Mod1 }, // PSLLQ/6 ib,PSRLQ/2 ib
  829. { 0x74, ENTRY_CopyBytes2Mod }, // PCMPEQB/r
  830. { 0x75, ENTRY_CopyBytes2Mod }, // PCMPEQW/r
  831. { 0x76, ENTRY_CopyBytes2Mod }, // PCMPEQD/r
  832. { 0x77, ENTRY_CopyBytes2 }, // EMMS
  833. { 0x78, ENTRY_Invalid }, // _78
  834. { 0x79, ENTRY_Invalid }, // _79
  835. { 0x7A, ENTRY_Invalid }, // _7A
  836. { 0x7B, ENTRY_Invalid }, // _7B
  837. { 0x7C, ENTRY_Invalid }, // _7C
  838. { 0x7D, ENTRY_Invalid }, // _7D
  839. { 0x7E, ENTRY_CopyBytes2Mod }, // MOVD/r
  840. { 0x7F, ENTRY_CopyBytes2Mod }, // MOV/r
  841. { 0x80, ENTRY_CopyBytes3Or5Target }, // JO
  842. { 0x81, ENTRY_CopyBytes3Or5Target }, // JNO
  843. { 0x82, ENTRY_CopyBytes3Or5Target }, // JB,JC,JNAE
  844. { 0x83, ENTRY_CopyBytes3Or5Target }, // JAE,JNB,JNC
  845. { 0x84, ENTRY_CopyBytes3Or5Target }, // JE,JZ,JZ
  846. { 0x85, ENTRY_CopyBytes3Or5Target }, // JNE,JNZ
  847. { 0x86, ENTRY_CopyBytes3Or5Target }, // JBE,JNA
  848. { 0x87, ENTRY_CopyBytes3Or5Target }, // JA,JNBE
  849. { 0x88, ENTRY_CopyBytes3Or5Target }, // JS
  850. { 0x89, ENTRY_CopyBytes3Or5Target }, // JNS
  851. { 0x8A, ENTRY_CopyBytes3Or5Target }, // JP,JPE
  852. { 0x8B, ENTRY_CopyBytes3Or5Target }, // JNP,JPO
  853. { 0x8C, ENTRY_CopyBytes3Or5Target }, // JL,NGE
  854. { 0x8D, ENTRY_CopyBytes3Or5Target }, // JGE,JNL
  855. { 0x8E, ENTRY_CopyBytes3Or5Target }, // JLE,JNG
  856. { 0x8F, ENTRY_CopyBytes3Or5Target }, // JG,JNLE
  857. { 0x90, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40)
  858. { 0x91, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41)
  859. { 0x92, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVC & CMOVNAE (0F 42)
  860. { 0x93, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB & CMOVNC (0F 43)
  861. { 0x94, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44)
  862. { 0x95, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45)
  863. { 0x96, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46)
  864. { 0x97, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47)
  865. { 0x98, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48)
  866. { 0x99, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49)
  867. { 0x9A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A)
  868. { 0x9B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B)
  869. { 0x9C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C)
  870. { 0x9D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D)
  871. { 0x9E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E)
  872. { 0x9F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F)
  873. { 0xA0, ENTRY_CopyBytes2 }, // PUSH
  874. { 0xA1, ENTRY_CopyBytes2 }, // POP
  875. { 0xA2, ENTRY_CopyBytes2 }, // CPUID
  876. { 0xA3, ENTRY_CopyBytes2Mod }, // BT (0F A3)
  877. { 0xA4, ENTRY_CopyBytes2Mod1 }, // SHLD
  878. { 0xA5, ENTRY_CopyBytes2Mod }, // SHLD
  879. { 0xA6, ENTRY_Invalid }, // _A6
  880. { 0xA7, ENTRY_Invalid }, // _A7
  881. { 0xA8, ENTRY_CopyBytes2 }, // PUSH
  882. { 0xA9, ENTRY_CopyBytes2 }, // POP
  883. { 0xAA, ENTRY_CopyBytes2 }, // RSM
  884. { 0xAB, ENTRY_CopyBytes2Mod }, // BTS (0F AB)
  885. { 0xAC, ENTRY_CopyBytes2Mod1 }, // SHRD
  886. { 0xAD, ENTRY_CopyBytes2Mod }, // SHRD
  887. { 0xAE, ENTRY_CopyBytes2Mod }, // FXRSTOR/1,FXSAVE/0
  888. { 0xAF, ENTRY_CopyBytes2Mod }, // IMUL (0F AF)
  889. { 0xB0, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B0)
  890. { 0xB1, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B1)
  891. { 0xB2, ENTRY_CopyBytes2Mod }, // LSS/r
  892. { 0xB3, ENTRY_CopyBytes2Mod }, // BTR (0F B3)
  893. { 0xB4, ENTRY_CopyBytes2Mod }, // LFS/r
  894. { 0xB5, ENTRY_CopyBytes2Mod }, // LGS/r
  895. { 0xB6, ENTRY_CopyBytes2Mod }, // MOVZX/r
  896. { 0xB7, ENTRY_CopyBytes2Mod }, // MOVZX/r
  897. { 0xB8, ENTRY_Invalid }, // _B8
  898. { 0xB9, ENTRY_Invalid }, // _B9
  899. { 0xBA, ENTRY_CopyBytes2Mod1 }, // BT & BTC & BTR & BTS (0F BA)
  900. { 0xBB, ENTRY_CopyBytes2Mod }, // BTC (0F BB)
  901. { 0xBC, ENTRY_CopyBytes2Mod }, // BSF (0F BC)
  902. { 0xBD, ENTRY_CopyBytes2Mod }, // BSR (0F BD)
  903. { 0xBE, ENTRY_CopyBytes2Mod }, // MOVSX/r
  904. { 0xBF, ENTRY_CopyBytes2Mod }, // MOVSX/r
  905. { 0xC0, ENTRY_CopyBytes2Mod }, // XADD/r
  906. { 0xC1, ENTRY_CopyBytes2Mod }, // XADD/r
  907. { 0xC2, ENTRY_CopyBytes2Mod }, // CMPPS &
  908. { 0xC3, ENTRY_CopyBytes2Mod }, // MOVNTI
  909. { 0xC4, ENTRY_CopyBytes2Mod1 }, // PINSRW /r ib
  910. { 0xC5, ENTRY_CopyBytes2Mod1 }, // PEXTRW /r ib
  911. { 0xC6, ENTRY_CopyBytes2Mod1 }, // SHUFPS & SHUFPD
  912. { 0xC7, ENTRY_CopyBytes2Mod }, // CMPXCHG8B (0F C7)
  913. { 0xC8, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
  914. { 0xC9, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
  915. { 0xCA, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
  916. { 0xCB, ENTRY_CopyBytes2 }, //CVTPD2PI BSWAP 0F C8 + rd
  917. { 0xCC, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
  918. { 0xCD, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
  919. { 0xCE, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
  920. { 0xCF, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
  921. { 0xD0, ENTRY_Invalid }, // _D0
  922. { 0xD1, ENTRY_CopyBytes2Mod }, // PSRLW/r
  923. { 0xD2, ENTRY_CopyBytes2Mod }, // PSRLD/r
  924. { 0xD3, ENTRY_CopyBytes2Mod }, // PSRLQ/r
  925. { 0xD4, ENTRY_CopyBytes2Mod }, // PADDQ
  926. { 0xD5, ENTRY_CopyBytes2Mod }, // PMULLW/r
  927. { 0xD6, ENTRY_CopyBytes2Mod }, // MOVDQ2Q / MOVQ2DQ
  928. { 0xD7, ENTRY_CopyBytes2Mod }, // PMOVMSKB/r
  929. { 0xD8, ENTRY_CopyBytes2Mod }, // PSUBUSB/r
  930. { 0xD9, ENTRY_CopyBytes2Mod }, // PSUBUSW/r
  931. { 0xDA, ENTRY_CopyBytes2Mod }, // PMINUB/r
  932. { 0xDB, ENTRY_CopyBytes2Mod }, // PAND/r
  933. { 0xDC, ENTRY_CopyBytes2Mod }, // PADDUSB/r
  934. { 0xDD, ENTRY_CopyBytes2Mod }, // PADDUSW/r
  935. { 0xDE, ENTRY_CopyBytes2Mod }, // PMAXUB/r
  936. { 0xDF, ENTRY_CopyBytes2Mod }, // PANDN/r
  937. { 0xE0, ENTRY_CopyBytes2Mod }, // PAVGB
  938. { 0xE1, ENTRY_CopyBytes2Mod }, // PSRAW/r
  939. { 0xE2, ENTRY_CopyBytes2Mod }, // PSRAD/r
  940. { 0xE3, ENTRY_CopyBytes2Mod }, // PAVGW
  941. { 0xE4, ENTRY_CopyBytes2Mod }, // PMULHUW/r
  942. { 0xE5, ENTRY_CopyBytes2Mod }, // PMULHW/r
  943. { 0xE6, ENTRY_CopyBytes2Mod }, // CTDQ2PD &
  944. { 0xE7, ENTRY_CopyBytes2Mod }, // MOVNTQ
  945. { 0xE8, ENTRY_CopyBytes2Mod }, // PSUBB/r
  946. { 0xE9, ENTRY_CopyBytes2Mod }, // PSUBW/r
  947. { 0xEA, ENTRY_CopyBytes2Mod }, // PMINSW/r
  948. { 0xEB, ENTRY_CopyBytes2Mod }, // POR/r
  949. { 0xEC, ENTRY_CopyBytes2Mod }, // PADDSB/r
  950. { 0xED, ENTRY_CopyBytes2Mod }, // PADDSW/r
  951. { 0xEE, ENTRY_CopyBytes2Mod }, // PMAXSW /r
  952. { 0xEF, ENTRY_CopyBytes2Mod }, // PXOR/r
  953. { 0xF0, ENTRY_Invalid }, // _F0
  954. { 0xF1, ENTRY_CopyBytes2Mod }, // PSLLW/r
  955. { 0xF2, ENTRY_CopyBytes2Mod }, // PSLLD/r
  956. { 0xF3, ENTRY_CopyBytes2Mod }, // PSLLQ/r
  957. { 0xF4, ENTRY_CopyBytes2Mod }, // PMULUDQ/r
  958. { 0xF5, ENTRY_CopyBytes2Mod }, // PMADDWD/r
  959. { 0xF6, ENTRY_CopyBytes2Mod }, // PSADBW/r
  960. { 0xF7, ENTRY_CopyBytes2Mod }, // MASKMOVQ
  961. { 0xF8, ENTRY_CopyBytes2Mod }, // PSUBB/r
  962. { 0xF9, ENTRY_CopyBytes2Mod }, // PSUBW/r
  963. { 0xFA, ENTRY_CopyBytes2Mod }, // PSUBD/r
  964. { 0xFB, ENTRY_CopyBytes2Mod }, // FSUBQ/r
  965. { 0xFC, ENTRY_CopyBytes2Mod }, // PADDB/r
  966. { 0xFD, ENTRY_CopyBytes2Mod }, // PADDW/r
  967. { 0xFE, ENTRY_CopyBytes2Mod }, // PADDD/r
  968. { 0xFF, ENTRY_Invalid }, // _FF
  969. { 0, ENTRY_End }, };
  970. BOOL CDetourDis::SanityCheckSystem()
  971. {
  972. ULONG n = 0;
  973. for ( ; n < 256; n++ )
  974. {
  975. REFCOPYENTRY pEntry = &s_rceCopyTable[n];
  976. if ( n != pEntry->nOpcode )
  977. {
  978. ASSERT( n == pEntry->nOpcode );
  979. return FALSE;
  980. }
  981. }
  982. if ( s_rceCopyTable[256].pfCopy != NULL )
  983. {
  984. ASSERT( !"Missing end marker." );
  985. return FALSE;
  986. }
  987. for ( n = 0; n < 256; n++ )
  988. {
  989. REFCOPYENTRY pEntry = &s_rceCopyTable0F[n];
  990. if ( n != pEntry->nOpcode )
  991. {
  992. ASSERT( n == pEntry->nOpcode );
  993. return FALSE;
  994. }
  995. }
  996. if ( s_rceCopyTable0F[256].pfCopy != NULL )
  997. {
  998. ASSERT( !"Missing end marker." );
  999. return FALSE;
  1000. }
  1001. return TRUE;
  1002. }
  1003. #endif // defined(DETOURS_X64) || defined(DETOURS_X86)
  1004. /////////////////////////////////////////////////////////// IA64 Disassembler.
  1005. //
  1006. #ifdef DETOURS_IA64
  1007. #error Feature not supported in this release.
  1008. #endif // DETOURS_IA64
  1009. //
  1010. ///////////////////////////////////////////////////////////////// End of File.