| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620 |
- //////////////////////////////////////////////////////////////////////////////
- //
- // Detours Disassembler (disasm.cpp of detours.lib)
- //
- // Microsoft Research Detours Package, Version 2.1.
- //
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //
- #include <windows.h>
- #include <limits.h>
- // #define DETOUR_DEBUG 1
- #define DETOURS_INTERNAL
- #include "detours.h"
- #define DETOURS_X86
- #if !defined(DETOURS_X86) && !defined(DETOURS_X64) && !defined(DETOURS_IA64)
- #error Must define one of DETOURS_X86, DETOURS_X64, or DETOURS_IA64
- #endif
- #undef ASSERT
- #define ASSERT(x)
- //////////////////////////////////////////////////////////////////////////////
- //
- // Function:
- // DetourCopyInstructionEx(PVOID pDst,
- // PVOID pSrc,
- // PVOID *ppTarget,
- // LONG *plExtra)
- // Purpose:
- // Copy a single instruction from pSrc to pDst.
- //
- // Arguments:
- // pDst:
- // Destination address for the instruction. May be NULL in which
- // case DetourCopyInstruction is used to measure an instruction.
- // If not NULL then the source instruction is copied to the
- // destination instruction and any relative arguments are adjusted.
- // pSrc:
- // Source address of the instruction.
- // ppTarget:
- // Out parameter for any target instruction address pointed to by
- // the instruction. For example, a branch or a jump insruction has
- // a target, but a load or store instruction doesn't. A target is
- // another instruction that may be executed as a result of this
- // instruction. ppTarget may be NULL.
- // plExtra:
- // Out parameter for the number of extra bytes needed by the
- // instruction to reach the target. For example, lExtra = 3 if the
- // instruction had an 8-bit relative offset, but needs a 32-bit
- // relative offset.
- //
- // Returns:
- // Returns the address of the next instruction (following in the source)
- // instruction. By subtracting pSrc from the return value, the caller
- // can determinte the size of the instruction copied.
- //
- // Comments:
- // By following the pTarget, the caller can follow alternate
- // instruction streams. However, it is not always possible to determine
- // the target based on static analysis. For example, the destination of
- // a jump relative to a register cannot be determined from just the
- // instruction stream. The output value, pTarget, can have any of the
- // following outputs:
- // DETOUR_INSTRUCTION_TARGET_NONE:
- // The instruction has no targets.
- // DETOUR_INSTRUCTION_TARGET_DYNAMIC:
- // The instruction has a non-deterministic (dynamic) target.
- // (i.e. the jump is to an address held in a register.)
- // Address: The instruction has the specified target.
- //
- // When copying instructions, DetourCopyInstruction insures that any
- // targets remain constant. It does so by adjusting any IP relative
- // offsets.
- //
- PVOID WINAPI DetourCopyInstruction( PVOID pDst , PVOID pSrc , PVOID * ppTarget )
- {
- return DetourCopyInstructionEx( pDst,pSrc,ppTarget,NULL );
- }
- //////////////////////////////////////////////////// X86 and X64 Disassembler.
- //
- // Includes full support for all x86 chips prior to the Pentium III.
- //
- #if defined(DETOURS_X64) || defined(DETOURS_X86)
- class CDetourDis
- {
- public:
- CDetourDis( PBYTE * ppbTarget , LONG * plExtra );
- PBYTE CopyInstruction( PBYTE pbDst , PBYTE pbSrc );
- static BOOL SanityCheckSystem();
- public:
- struct COPYENTRY;
- typedef const COPYENTRY * REFCOPYENTRY;
- typedef PBYTE ( CDetourDis::* COPYFUNC )( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- enum
- {
- DYNAMIC = 0x1u ,
- ADDRESS = 0x2u ,
- NOENLARGE = 0x4u ,
- RAX = 0x8u ,
- SIB = 0x10u ,
- RIP = 0x20u ,
- NOTSIB = 0x0fu,
- };
- struct COPYENTRY
- {
- ULONG nOpcode : 8; // Opcode
- ULONG nFixedSize : 4; // Fixed size of opcode
- ULONG nFixedSize16 : 4; // Fixed size when 16 bit operand
- ULONG nModOffset : 4; // Offset to mod/rm byte (0=none)
- LONG nRelOffset : 4; // Offset to relative target.
- LONG nTargetBack : 4; // Offset back to absolute or rip target
- ULONG nFlagBits : 4; // Flags for DYNAMIC, etc.
- COPYFUNC pfCopy; // Function pointer.
- };
- protected:
- // These macros define common uses of nFixedSize..pfCopy.
- #define ENTRY_CopyBytes1 1, 1, 0, 0, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes1Dynamic 1, 1, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes2 2, 2, 0, 0, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes2Jump 2, 2, 0, 1, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes2CantJump 2, 2, 0, 1, 0, NOENLARGE, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes2Dynamic 2, 2, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes3 3, 3, 0, 0, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes3Dynamic 3, 3, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes3Or5 5, 3, 0, 0, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes3Or5Rax 5, 3, 0, 0, 0, RAX, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes3Or5Target 5, 3, 0, 1, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes5Or7Dynamic 7, 5, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes3Or5Address 5, 3, 0, 0, 0, ADDRESS, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes4 4, 4, 0, 0, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes5 5, 5, 0, 0, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes7 7, 7, 0, 0, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes2Mod 2, 2, 1, 0, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes2Mod1 3, 3, 1, 0, 1, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes2ModOperand 6, 4, 1, 0, 4, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytes3Mod 3, 3, 2, 0, 0, 0, &CDetourDis::CopyBytes
- #define ENTRY_CopyBytesPrefix 1, 1, 0, 0, 0, 0, &CDetourDis::CopyBytesPrefix
- #define ENTRY_CopyBytesRax 1, 1, 0, 0, 0, 0, &CDetourDis::CopyBytesRax
- #define ENTRY_Copy0F 1, 1, 0, 0, 0, 0, &CDetourDis::Copy0F
- #define ENTRY_Copy66 1, 1, 0, 0, 0, 0, &CDetourDis::Copy66
- #define ENTRY_Copy67 1, 1, 0, 0, 0, 0, &CDetourDis::Copy67
- #define ENTRY_CopyF6 0, 0, 0, 0, 0, 0, &CDetourDis::CopyF6
- #define ENTRY_CopyF7 0, 0, 0, 0, 0, 0, &CDetourDis::CopyF7
- #define ENTRY_CopyFF 0, 0, 0, 0, 0, 0, &CDetourDis::CopyFF
- #define ENTRY_Invalid 1, 1, 0, 0, 0, 0, &CDetourDis::Invalid
- #define ENTRY_End 0, 0, 0, 0, 0, 0, NULL
- PBYTE CopyBytes( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- PBYTE CopyBytesPrefix( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- PBYTE CopyBytesRax( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- PBYTE Invalid( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- PBYTE AdjustTarget( PBYTE pbDst , PBYTE pbSrc , LONG cbOp , LONG cbTargetOffset , LONG cbTargetSize );
- protected:
- PBYTE Copy0F( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- PBYTE Copy66( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- PBYTE Copy67( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- PBYTE CopyF6( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- PBYTE CopyF7( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- PBYTE CopyFF( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc );
- protected:
- static const COPYENTRY s_rceCopyTable[257];
- static const COPYENTRY s_rceCopyTable0F[257];
- static const BYTE s_rbModRm[256];
- protected:
- BOOL m_bOperandOverride;
- BOOL m_bAddressOverride;
- BOOL m_bRaxOverride;
- PBYTE * m_ppbTarget;
- LONG * m_plExtra;
- LONG m_lScratchExtra;
- PBYTE m_pbScratchTarget;
- BYTE m_rbScratchDst[64];
- };
- PVOID WINAPI DetourCopyInstructionEx( PVOID pDst , PVOID pSrc , PVOID * ppTarget , LONG * plExtra )
- {
- CDetourDis oDetourDisasm ( ( PBYTE * ) ppTarget,plExtra );
- return oDetourDisasm.CopyInstruction( ( PBYTE ) pDst,( PBYTE ) pSrc );
- }
- /////////////////////////////////////////////////////////// Disassembler Code.
- //
- CDetourDis::CDetourDis( PBYTE * ppbTarget , LONG * plExtra )
- {
- m_bOperandOverride = FALSE;
- m_bAddressOverride = FALSE;
- m_bRaxOverride = FALSE;
- m_ppbTarget = ppbTarget ? ppbTarget : &m_pbScratchTarget;
- m_plExtra = plExtra ? plExtra : &m_lScratchExtra;
- *m_ppbTarget = ( PBYTE ) DETOUR_INSTRUCTION_TARGET_NONE;
- *m_plExtra = 0;
- }
- PBYTE CDetourDis::CopyInstruction( PBYTE pbDst , PBYTE pbSrc )
- {
- // Configure scratch areas if real areas are not available.
- if ( NULL == pbDst )
- {
- pbDst = m_rbScratchDst;
- }
- if ( NULL == pbSrc )
- {
- // We can't copy a non-existent instruction.
- SetLastError( ERROR_INVALID_DATA );
- return NULL;
- }
- // Figure out how big the instruction is, do the appropriate copy,
- // and figure out what the target of the instruction is if any.
- //
- REFCOPYENTRY pEntry = &s_rceCopyTable[pbSrc[0]];
- return ( this->*pEntry->pfCopy ) ( pEntry,pbDst,pbSrc );
- }
- PBYTE CDetourDis::CopyBytes( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- #ifdef DETOURS_X64
- #error Feature not supported in this release.
- #else
- LONG nBytesFixed = ( pEntry->nFlagBits & ADDRESS ) ? ( m_bAddressOverride ? pEntry->nFixedSize16 : pEntry->nFixedSize ) : ( m_bOperandOverride ? pEntry->nFixedSize16 : pEntry->nFixedSize );
- #endif
- LONG nBytes = nBytesFixed;
- LONG nRelOffset = pEntry->nRelOffset;
- LONG cbTarget = nBytes - nRelOffset;
- if ( pEntry->nModOffset > 0 )
- {
- BYTE bModRm = pbSrc[pEntry->nModOffset];
- BYTE bFlags = s_rbModRm[bModRm];
- nBytes += bFlags & NOTSIB;
- if ( bFlags & SIB )
- {
- BYTE bSib = pbSrc[pEntry->nModOffset + 1];
- if ( ( bSib & 0x07 ) == 0x05 )
- {
- if ( ( bModRm & 0xc0 ) == 0x00 )
- {
- nBytes += 4;
- }
- else if ( ( bModRm & 0xc0 ) == 0x40 )
- {
- nBytes += 1;
- }
- else if ( ( bModRm & 0xc0 ) == 0x80 )
- {
- nBytes += 4;
- }
- }
- cbTarget = nBytes - nRelOffset;
- }
- else if ( bFlags & RIP )
- {
- #ifdef DETOURS_X64
- #error Feature not supported in this release.
- #endif
- }
- }
- CopyMemory( pbDst,pbSrc,nBytes );
- if ( nRelOffset )
- {
- *m_ppbTarget = AdjustTarget( pbDst,pbSrc,nBytesFixed,nRelOffset,cbTarget );
- #ifdef DETOURS_X64
- #error Feature not supported in this release.
- #endif
- }
- if ( pEntry->nFlagBits & NOENLARGE )
- {
- *m_plExtra = -*m_plExtra;
- }
- if ( pEntry->nFlagBits & DYNAMIC )
- {
- *m_ppbTarget = ( PBYTE ) DETOUR_INSTRUCTION_TARGET_DYNAMIC;
- }
- return pbSrc + nBytes;
- }
- PBYTE CDetourDis::CopyBytesPrefix( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- CopyBytes( pEntry,pbDst,pbSrc );
- pEntry = &s_rceCopyTable[pbSrc[1]];
- return ( this->*pEntry->pfCopy ) ( pEntry,pbDst + 1,pbSrc + 1 );
- }
- PBYTE CDetourDis::CopyBytesRax( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- CopyBytes( pEntry,pbDst,pbSrc );
- if ( *pbSrc & 0x8 )
- {
- m_bRaxOverride = TRUE;
- }
- pEntry = &s_rceCopyTable[pbSrc[1]];
- return ( this->*pEntry->pfCopy ) ( pEntry,pbDst + 1,pbSrc + 1 );
- }
- PBYTE CDetourDis::AdjustTarget( PBYTE pbDst , PBYTE pbSrc , LONG cbOp , LONG cbTargetOffset , LONG cbTargetSize )
- {
- PBYTE pbTarget = NULL;
- PVOID pvTargetAddr = &pbDst[cbTargetOffset];
- LONG_PTR nOldOffset = 0;
- switch ( cbTargetSize )
- {
- case 1:
- nOldOffset = ( LONG_PTR ) * ( CHAR * & ) pvTargetAddr;
- break;
- case 2:
- nOldOffset = ( LONG_PTR ) * ( SHORT * & ) pvTargetAddr;
- break;
- case 4:
- nOldOffset = ( LONG_PTR ) * ( LONG * & ) pvTargetAddr;
- break;
- case 8:
- nOldOffset = ( LONG_PTR ) * ( LONG_PTR * & ) pvTargetAddr;
- break;
- default:
- ASSERT( !"cbTargetSize is invalid." );
- break;
- }
- pbTarget = pbSrc + cbOp + nOldOffset;
- LONG_PTR nNewOffset = nOldOffset - ( pbDst - pbSrc );
- switch ( cbTargetSize )
- {
- case 1:
- *( CHAR * & ) pvTargetAddr = ( CHAR ) nNewOffset;
- if ( nNewOffset < SCHAR_MIN || nNewOffset > SCHAR_MAX )
- {
- *m_plExtra = sizeof( ULONG_PTR ) - 1;
- }
- break;
- case 2:
- *( SHORT * & ) pvTargetAddr = ( SHORT ) nNewOffset;
- if ( nNewOffset < SHRT_MIN || nNewOffset > SHRT_MAX )
- {
- *m_plExtra = sizeof( ULONG_PTR ) - 2;
- }
- break;
- case 4:
- *( LONG * & ) pvTargetAddr = ( LONG ) nNewOffset;
- if ( nNewOffset < LONG_MIN || nNewOffset > LONG_MAX )
- {
- *m_plExtra = sizeof( ULONG_PTR ) - 4;
- }
- break;
- case 8:
- *( LONG_PTR * & ) pvTargetAddr = ( LONG_PTR ) nNewOffset;
- break;
- }
- ASSERT( pbDst + cbOp + nNewOffset == pbTarget );
- return pbTarget;
- }
- PBYTE CDetourDis::Invalid( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- ( void ) pbDst;
- ( void ) pEntry;
- ASSERT( !"Invalid Instruction" );
- return pbSrc + 1;
- }
- ////////////////////////////////////////////////////// Individual Bytes Codes.
- //
- PBYTE CDetourDis::Copy0F( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- CopyBytes( pEntry,pbDst,pbSrc );
- pEntry = &s_rceCopyTable0F[pbSrc[1]];
- return ( this->*pEntry->pfCopy ) ( pEntry,pbDst + 1,pbSrc + 1 );
- }
- PBYTE CDetourDis::Copy66( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- // Operand-size override prefix
- m_bOperandOverride = TRUE;
- return CopyBytesPrefix( pEntry,pbDst,pbSrc );
- }
- PBYTE CDetourDis::Copy67( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- // Address size override prefix
- m_bAddressOverride = TRUE;
- return CopyBytesPrefix( pEntry,pbDst,pbSrc );
- }
- PBYTE CDetourDis::CopyF6( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- ( void ) pEntry;
- // TEST BYTE /0
- if ( 0x00 == ( 0x38 & pbSrc[1] ) )
- {
- // reg(bits 543) of ModR/M == 0
- const COPYENTRY ce ={0xf6, ENTRY_CopyBytes2Mod1};
- return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
- }
- // DIV /6
- // IDIV /7
- // IMUL /5
- // MUL /4
- // NEG /3
- // NOT /2
- const COPYENTRY ce ={0xf6, ENTRY_CopyBytes2Mod};
- return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
- }
- PBYTE CDetourDis::CopyF7( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- ( void ) pEntry;
- // TEST WORD /0
- if ( 0x00 == ( 0x38 & pbSrc[1] ) )
- {
- // reg(bits 543) of ModR/M == 0
- const COPYENTRY ce ={0xf7, ENTRY_CopyBytes2ModOperand};
- return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
- }
- // DIV /6
- // IDIV /7
- // IMUL /5
- // MUL /4
- // NEG /3
- // NOT /2
- const COPYENTRY ce ={0xf7, ENTRY_CopyBytes2Mod};
- return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
- }
- PBYTE CDetourDis::CopyFF( REFCOPYENTRY pEntry , PBYTE pbDst , PBYTE pbSrc )
- {
- // CALL /2
- // CALL /3
- // INC /0
- // JMP /4
- // JMP /5
- // PUSH /6
- ( void ) pEntry;
- if ( 0x15 == pbSrc[1] || 0x25 == pbSrc[1] )
- {
- // CALL [], JMP []
- #ifdef DETOURS_X64
- #error Feature not supported in this release.
- #else
- PBYTE * ppbTarget = *( PBYTE ** ) &pbSrc[2];
- *m_ppbTarget = *ppbTarget;
- #endif
- }
- else if ( 0x10 == ( 0x38 & pbSrc[1] ) || // CALL /2 --> reg(bits 543) of ModR/M == 010
- 0x18 == ( 0x38 & pbSrc[1] ) || // CALL /3 --> reg(bits 543) of ModR/M == 011
- 0x20 == ( 0x38 & pbSrc[1] ) || // JMP /4 --> reg(bits 543) of ModR/M == 100
- 0x28 == ( 0x38 & pbSrc[1] ) // JMP /5 --> reg(bits 543) of ModR/M == 101
- )
- {
- *m_ppbTarget = ( PBYTE ) DETOUR_INSTRUCTION_TARGET_DYNAMIC;
- }
- const COPYENTRY ce ={0xff, ENTRY_CopyBytes2Mod};
- return ( this->*ce.pfCopy ) ( &ce,pbDst,pbSrc );
- }
- ///////////////////////////////////////////////////////// Disassembler Tables.
- //
- 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
- 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, // 1x
- 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, // 2x
- 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, 0, 0, 0, 0, SIB | 1, RIP | 4, 0, 0, // 3x
- 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 4x
- 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 5x
- 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 6x
- 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, // 7x
- 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, // 8x
- 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, // 9x
- 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, // Ax
- 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, // Bx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // Fx
- };
- const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable[257] ={{ 0x00, ENTRY_CopyBytes2Mod }, // ADD /r
- { 0x01, ENTRY_CopyBytes2Mod }, // ADD /r
- { 0x02, ENTRY_CopyBytes2Mod }, // ADD /r
- { 0x03, ENTRY_CopyBytes2Mod }, // ADD /r
- { 0x04, ENTRY_CopyBytes2 }, // ADD ib
- { 0x05, ENTRY_CopyBytes3Or5 }, // ADD iw
- { 0x06, ENTRY_CopyBytes1 }, // PUSH
- { 0x07, ENTRY_CopyBytes1 }, // POP
- { 0x08, ENTRY_CopyBytes2Mod }, // OR /r
- { 0x09, ENTRY_CopyBytes2Mod }, // OR /r
- { 0x0A, ENTRY_CopyBytes2Mod }, // OR /r
- { 0x0B, ENTRY_CopyBytes2Mod }, // OR /r
- { 0x0C, ENTRY_CopyBytes2 }, // OR ib
- { 0x0D, ENTRY_CopyBytes3Or5 }, // OR iw
- { 0x0E, ENTRY_CopyBytes1 }, // PUSH
- { 0x0F, ENTRY_Copy0F }, // Extension Ops
- { 0x10, ENTRY_CopyBytes2Mod }, // ADC /r
- { 0x11, ENTRY_CopyBytes2Mod }, // ADC /r
- { 0x12, ENTRY_CopyBytes2Mod }, // ADC /r
- { 0x13, ENTRY_CopyBytes2Mod }, // ADC /r
- { 0x14, ENTRY_CopyBytes2 }, // ADC ib
- { 0x15, ENTRY_CopyBytes3Or5 }, // ADC id
- { 0x16, ENTRY_CopyBytes1 }, // PUSH
- { 0x17, ENTRY_CopyBytes1 }, // POP
- { 0x18, ENTRY_CopyBytes2Mod }, // SBB /r
- { 0x19, ENTRY_CopyBytes2Mod }, // SBB /r
- { 0x1A, ENTRY_CopyBytes2Mod }, // SBB /r
- { 0x1B, ENTRY_CopyBytes2Mod }, // SBB /r
- { 0x1C, ENTRY_CopyBytes2 }, // SBB ib
- { 0x1D, ENTRY_CopyBytes3Or5 }, // SBB id
- { 0x1E, ENTRY_CopyBytes1 }, // PUSH
- { 0x1F, ENTRY_CopyBytes1 }, // POP
- { 0x20, ENTRY_CopyBytes2Mod }, // AND /r
- { 0x21, ENTRY_CopyBytes2Mod }, // AND /r
- { 0x22, ENTRY_CopyBytes2Mod }, // AND /r
- { 0x23, ENTRY_CopyBytes2Mod }, // AND /r
- { 0x24, ENTRY_CopyBytes2 }, // AND ib
- { 0x25, ENTRY_CopyBytes3Or5 }, // AND id
- { 0x26, ENTRY_CopyBytesPrefix }, // ES prefix
- { 0x27, ENTRY_CopyBytes1 }, // DAA
- { 0x28, ENTRY_CopyBytes2Mod }, // SUB /r
- { 0x29, ENTRY_CopyBytes2Mod }, // SUB /r
- { 0x2A, ENTRY_CopyBytes2Mod }, // SUB /r
- { 0x2B, ENTRY_CopyBytes2Mod }, // SUB /r
- { 0x2C, ENTRY_CopyBytes2 }, // SUB ib
- { 0x2D, ENTRY_CopyBytes3Or5 }, // SUB id
- { 0x2E, ENTRY_CopyBytesPrefix }, // CS prefix
- { 0x2F, ENTRY_CopyBytes1 }, // DAS
- { 0x30, ENTRY_CopyBytes2Mod }, // XOR /r
- { 0x31, ENTRY_CopyBytes2Mod }, // XOR /r
- { 0x32, ENTRY_CopyBytes2Mod }, // XOR /r
- { 0x33, ENTRY_CopyBytes2Mod }, // XOR /r
- { 0x34, ENTRY_CopyBytes2 }, // XOR ib
- { 0x35, ENTRY_CopyBytes3Or5 }, // XOR id
- { 0x36, ENTRY_CopyBytesPrefix }, // SS prefix
- { 0x37, ENTRY_CopyBytes1 }, // AAA
- { 0x38, ENTRY_CopyBytes2Mod }, // CMP /r
- { 0x39, ENTRY_CopyBytes2Mod }, // CMP /r
- { 0x3A, ENTRY_CopyBytes2Mod }, // CMP /r
- { 0x3B, ENTRY_CopyBytes2Mod }, // CMP /r
- { 0x3C, ENTRY_CopyBytes2 }, // CMP ib
- { 0x3D, ENTRY_CopyBytes3Or5 }, // CMP id
- { 0x3E, ENTRY_CopyBytesPrefix }, // DS prefix
- { 0x3F, ENTRY_CopyBytes1 }, // AAS
- #ifdef DETOURS_X64 // For Rax Prefix
- #error Feature not supported in this release.
- #else
- { 0x40, ENTRY_CopyBytes1 }, // INC
- { 0x41, ENTRY_CopyBytes1 }, // INC
- { 0x42, ENTRY_CopyBytes1 }, // INC
- { 0x43, ENTRY_CopyBytes1 }, // INC
- { 0x44, ENTRY_CopyBytes1 }, // INC
- { 0x45, ENTRY_CopyBytes1 }, // INC
- { 0x46, ENTRY_CopyBytes1 }, // INC
- { 0x47, ENTRY_CopyBytes1 }, // INC
- { 0x48, ENTRY_CopyBytes1 }, // DEC
- { 0x49, ENTRY_CopyBytes1 }, // DEC
- { 0x4A, ENTRY_CopyBytes1 }, // DEC
- { 0x4B, ENTRY_CopyBytes1 }, // DEC
- { 0x4C, ENTRY_CopyBytes1 }, // DEC
- { 0x4D, ENTRY_CopyBytes1 }, // DEC
- { 0x4E, ENTRY_CopyBytes1 }, // DEC
- { 0x4F, ENTRY_CopyBytes1 }, // DEC
- #endif
- { 0x50, ENTRY_CopyBytes1 }, // PUSH
- { 0x51, ENTRY_CopyBytes1 }, // PUSH
- { 0x52, ENTRY_CopyBytes1 }, // PUSH
- { 0x53, ENTRY_CopyBytes1 }, // PUSH
- { 0x54, ENTRY_CopyBytes1 }, // PUSH
- { 0x55, ENTRY_CopyBytes1 }, // PUSH
- { 0x56, ENTRY_CopyBytes1 }, // PUSH
- { 0x57, ENTRY_CopyBytes1 }, // PUSH
- { 0x58, ENTRY_CopyBytes1 }, // POP
- { 0x59, ENTRY_CopyBytes1 }, // POP
- { 0x5A, ENTRY_CopyBytes1 }, // POP
- { 0x5B, ENTRY_CopyBytes1 }, // POP
- { 0x5C, ENTRY_CopyBytes1 }, // POP
- { 0x5D, ENTRY_CopyBytes1 }, // POP
- { 0x5E, ENTRY_CopyBytes1 }, // POP
- { 0x5F, ENTRY_CopyBytes1 }, // POP
- { 0x60, ENTRY_CopyBytes1 }, // PUSHAD
- { 0x61, ENTRY_CopyBytes1 }, // POPAD
- { 0x62, ENTRY_CopyBytes2Mod }, // BOUND /r
- { 0x63, ENTRY_CopyBytes2Mod }, // ARPL /r
- { 0x64, ENTRY_CopyBytesPrefix }, // FS prefix
- { 0x65, ENTRY_CopyBytesPrefix }, // GS prefix
- { 0x66, ENTRY_Copy66 }, // Operand Prefix
- { 0x67, ENTRY_Copy67 }, // Address Prefix
- { 0x68, ENTRY_CopyBytes3Or5 }, // PUSH
- { 0x69, ENTRY_CopyBytes2ModOperand }, //
- { 0x6A, ENTRY_CopyBytes2 }, // PUSH
- { 0x6B, ENTRY_CopyBytes2Mod1 }, // IMUL /r ib
- { 0x6C, ENTRY_CopyBytes1 }, // INS
- { 0x6D, ENTRY_CopyBytes1 }, // INS
- { 0x6E, ENTRY_CopyBytes1 }, // OUTS/OUTSB
- { 0x6F, ENTRY_CopyBytes1 }, // OUTS/OUTSW
- { 0x70, ENTRY_CopyBytes2Jump }, // JO
- { 0x71, ENTRY_CopyBytes2Jump }, // JNO
- { 0x72, ENTRY_CopyBytes2Jump }, // JB/JC/JNAE
- { 0x73, ENTRY_CopyBytes2Jump }, // JAE/JNB/JNC
- { 0x74, ENTRY_CopyBytes2Jump }, // JE/JZ
- { 0x75, ENTRY_CopyBytes2Jump }, // JNE/JNZ
- { 0x76, ENTRY_CopyBytes2Jump }, // JBE/JNA
- { 0x77, ENTRY_CopyBytes2Jump }, // JA/JNBE
- { 0x78, ENTRY_CopyBytes2Jump }, // JS
- { 0x79, ENTRY_CopyBytes2Jump }, // JNS
- { 0x7A, ENTRY_CopyBytes2Jump }, // JP/JPE
- { 0x7B, ENTRY_CopyBytes2Jump }, // JNP/JPO
- { 0x7C, ENTRY_CopyBytes2Jump }, // JL/JNGE
- { 0x7D, ENTRY_CopyBytes2Jump }, // JGE/JNL
- { 0x7E, ENTRY_CopyBytes2Jump }, // JLE/JNG
- { 0x7F, ENTRY_CopyBytes2Jump }, // JG/JNLE
- { 0x80, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc.s
- { 0x81, ENTRY_CopyBytes2ModOperand }, //
- { 0x82, ENTRY_CopyBytes2 }, // MOV al,x
- { 0x83, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc.
- { 0x84, ENTRY_CopyBytes2Mod }, // TEST /r
- { 0x85, ENTRY_CopyBytes2Mod }, // TEST /r
- { 0x86, ENTRY_CopyBytes2Mod }, // XCHG /r @todo
- { 0x87, ENTRY_CopyBytes2Mod }, // XCHG /r @todo
- { 0x88, ENTRY_CopyBytes2Mod }, // MOV /r
- { 0x89, ENTRY_CopyBytes2Mod }, // MOV /r
- { 0x8A, ENTRY_CopyBytes2Mod }, // MOV /r
- { 0x8B, ENTRY_CopyBytes2Mod }, // MOV /r
- { 0x8C, ENTRY_CopyBytes2Mod }, // MOV /r
- { 0x8D, ENTRY_CopyBytes2Mod }, // LEA /r
- { 0x8E, ENTRY_CopyBytes2Mod }, // MOV /r
- { 0x8F, ENTRY_CopyBytes2Mod }, // POP /0
- { 0x90, ENTRY_CopyBytes1 }, // NOP
- { 0x91, ENTRY_CopyBytes1 }, // XCHG
- { 0x92, ENTRY_CopyBytes1 }, // XCHG
- { 0x93, ENTRY_CopyBytes1 }, // XCHG
- { 0x94, ENTRY_CopyBytes1 }, // XCHG
- { 0x95, ENTRY_CopyBytes1 }, // XCHG
- { 0x96, ENTRY_CopyBytes1 }, // XCHG
- { 0x97, ENTRY_CopyBytes1 }, // XCHG
- { 0x98, ENTRY_CopyBytes1 }, // CWDE
- { 0x99, ENTRY_CopyBytes1 }, // CDQ
- { 0x9A, ENTRY_CopyBytes5Or7Dynamic }, // CALL cp
- { 0x9B, ENTRY_CopyBytes1 }, // WAIT/FWAIT
- { 0x9C, ENTRY_CopyBytes1 }, // PUSHFD
- { 0x9D, ENTRY_CopyBytes1 }, // POPFD
- { 0x9E, ENTRY_CopyBytes1 }, // SAHF
- { 0x9F, ENTRY_CopyBytes1 }, // LAHF
- { 0xA0, ENTRY_CopyBytes3Or5Address }, // MOV
- { 0xA1, ENTRY_CopyBytes3Or5Address }, // MOV
- { 0xA2, ENTRY_CopyBytes3Or5Address }, // MOV
- { 0xA3, ENTRY_CopyBytes3Or5Address }, // MOV
- { 0xA4, ENTRY_CopyBytes1 }, // MOVS
- { 0xA5, ENTRY_CopyBytes1 }, // MOVS/MOVSD
- { 0xA6, ENTRY_CopyBytes1 }, // CMPS/CMPSB
- { 0xA7, ENTRY_CopyBytes1 }, // CMPS/CMPSW
- { 0xA8, ENTRY_CopyBytes2 }, // TEST
- { 0xA9, ENTRY_CopyBytes3Or5 }, // TEST
- { 0xAA, ENTRY_CopyBytes1 }, // STOS/STOSB
- { 0xAB, ENTRY_CopyBytes1 }, // STOS/STOSW
- { 0xAC, ENTRY_CopyBytes1 }, // LODS/LODSB
- { 0xAD, ENTRY_CopyBytes1 }, // LODS/LODSW
- { 0xAE, ENTRY_CopyBytes1 }, // SCAS/SCASB
- { 0xAF, ENTRY_CopyBytes1 }, // SCAS/SCASD
- { 0xB0, ENTRY_CopyBytes2 }, // MOV B0+rb
- { 0xB1, ENTRY_CopyBytes2 }, // MOV B0+rb
- { 0xB2, ENTRY_CopyBytes2 }, // MOV B0+rb
- { 0xB3, ENTRY_CopyBytes2 }, // MOV B0+rb
- { 0xB4, ENTRY_CopyBytes2 }, // MOV B0+rb
- { 0xB5, ENTRY_CopyBytes2 }, // MOV B0+rb
- { 0xB6, ENTRY_CopyBytes2 }, // MOV B0+rb
- { 0xB7, ENTRY_CopyBytes2 }, // MOV B0+rb
- { 0xB8, ENTRY_CopyBytes3Or5Rax }, // MOV B8+rb
- { 0xB9, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
- { 0xBA, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
- { 0xBB, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
- { 0xBC, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
- { 0xBD, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
- { 0xBE, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
- { 0xBF, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
- { 0xC0, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc.
- { 0xC1, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc.
- { 0xC2, ENTRY_CopyBytes3 }, // RET
- { 0xC3, ENTRY_CopyBytes1 }, // RET
- { 0xC4, ENTRY_CopyBytes2Mod }, // LES
- { 0xC5, ENTRY_CopyBytes2Mod }, // LDS
- { 0xC6, ENTRY_CopyBytes2Mod1 }, // MOV
- { 0xC7, ENTRY_CopyBytes2ModOperand }, // MOV
- { 0xC8, ENTRY_CopyBytes4 }, // ENTER
- { 0xC9, ENTRY_CopyBytes1 }, // LEAVE
- { 0xCA, ENTRY_CopyBytes3Dynamic }, // RET
- { 0xCB, ENTRY_CopyBytes1Dynamic }, // RET
- { 0xCC, ENTRY_CopyBytes1Dynamic }, // INT 3
- { 0xCD, ENTRY_CopyBytes2Dynamic }, // INT ib
- { 0xCE, ENTRY_CopyBytes1Dynamic }, // INTO
- { 0xCF, ENTRY_CopyBytes1Dynamic }, // IRET
- { 0xD0, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
- { 0xD1, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
- { 0xD2, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
- { 0xD3, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
- { 0xD4, ENTRY_CopyBytes2 }, // AAM
- { 0xD5, ENTRY_CopyBytes2 }, // AAD
- { 0xD6, ENTRY_Invalid }, //
- { 0xD7, ENTRY_CopyBytes1 }, // XLAT/XLATB
- { 0xD8, ENTRY_CopyBytes2Mod }, // FADD, etc.
- { 0xD9, ENTRY_CopyBytes2Mod }, // F2XM1, etc.
- { 0xDA, ENTRY_CopyBytes2Mod }, // FLADD, etc.
- { 0xDB, ENTRY_CopyBytes2Mod }, // FCLEX, etc.
- { 0xDC, ENTRY_CopyBytes2Mod }, // FADD/0, etc.
- { 0xDD, ENTRY_CopyBytes2Mod }, // FFREE, etc.
- { 0xDE, ENTRY_CopyBytes2Mod }, // FADDP, etc.
- { 0xDF, ENTRY_CopyBytes2Mod }, // FBLD/4, etc.
- { 0xE0, ENTRY_CopyBytes2CantJump }, // LOOPNE cb
- { 0xE1, ENTRY_CopyBytes2CantJump }, // LOOPE cb
- { 0xE2, ENTRY_CopyBytes2CantJump }, // LOOP cb
- { 0xE3, ENTRY_CopyBytes2Jump }, // JCXZ/JECXZ
- { 0xE4, ENTRY_CopyBytes2 }, // IN ib
- { 0xE5, ENTRY_CopyBytes2 }, // IN id
- { 0xE6, ENTRY_CopyBytes2 }, // OUT ib
- { 0xE7, ENTRY_CopyBytes2 }, // OUT ib
- { 0xE8, ENTRY_CopyBytes3Or5Target }, // CALL cd
- { 0xE9, ENTRY_CopyBytes3Or5Target }, // JMP cd
- { 0xEA, ENTRY_CopyBytes5Or7Dynamic }, // JMP cp
- { 0xEB, ENTRY_CopyBytes2Jump }, // JMP cb
- { 0xEC, ENTRY_CopyBytes1 }, // IN ib
- { 0xED, ENTRY_CopyBytes1 }, // IN id
- { 0xEE, ENTRY_CopyBytes1 }, // OUT
- { 0xEF, ENTRY_CopyBytes1 }, // OUT
- { 0xF0, ENTRY_CopyBytesPrefix }, // LOCK prefix
- { 0xF1, ENTRY_Invalid }, //
- { 0xF2, ENTRY_CopyBytesPrefix }, // REPNE prefix
- { 0xF3, ENTRY_CopyBytesPrefix }, // REPE prefix
- { 0xF4, ENTRY_CopyBytes1 }, // HLT
- { 0xF5, ENTRY_CopyBytes1 }, // CMC
- { 0xF6, ENTRY_CopyF6 }, // TEST/0, DIV/6
- { 0xF7, ENTRY_CopyF7 }, // TEST/0, DIV/6
- { 0xF8, ENTRY_CopyBytes1 }, // CLC
- { 0xF9, ENTRY_CopyBytes1 }, // STC
- { 0xFA, ENTRY_CopyBytes1 }, // CLI
- { 0xFB, ENTRY_CopyBytes1 }, // STI
- { 0xFC, ENTRY_CopyBytes1 }, // CLD
- { 0xFD, ENTRY_CopyBytes1 }, // STD
- { 0xFE, ENTRY_CopyBytes2Mod }, // DEC/1,INC/0
- { 0xFF, ENTRY_CopyFF }, // CALL/2
- { 0, ENTRY_End }, };
- const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable0F[257] ={{ 0x00, ENTRY_CopyBytes2Mod }, // LLDT/2, etc.
- { 0x01, ENTRY_CopyBytes2Mod }, // INVLPG/7, etc.
- { 0x02, ENTRY_CopyBytes2Mod }, // LAR/r
- { 0x03, ENTRY_CopyBytes2Mod }, // LSL/r
- { 0x04, ENTRY_Invalid }, // _04
- { 0x05, ENTRY_Invalid }, // _05
- { 0x06, ENTRY_CopyBytes2 }, // CLTS
- { 0x07, ENTRY_Invalid }, // _07
- { 0x08, ENTRY_CopyBytes2 }, // INVD
- { 0x09, ENTRY_CopyBytes2 }, // WBINVD
- { 0x0A, ENTRY_Invalid }, // _0A
- { 0x0B, ENTRY_CopyBytes2 }, // UD2
- { 0x0C, ENTRY_Invalid }, // _0C
- { 0x0D, ENTRY_CopyBytes2Mod }, // PREFETCH
- { 0x0E, ENTRY_CopyBytes2 }, // FEMMS
- { 0x0F, ENTRY_CopyBytes3Mod }, // 3DNow Opcodes
- { 0x10, ENTRY_CopyBytes2Mod }, // MOVSS MOVUPD MOVSD
- { 0x11, ENTRY_CopyBytes2Mod }, // MOVSS MOVUPD MOVSD
- { 0x12, ENTRY_CopyBytes2Mod }, // MOVLPD
- { 0x13, ENTRY_CopyBytes2Mod }, // MOVLPD
- { 0x14, ENTRY_CopyBytes2Mod }, // UNPCKLPD
- { 0x15, ENTRY_CopyBytes2Mod }, // UNPCKHPD
- { 0x16, ENTRY_CopyBytes2Mod }, // MOVHPD
- { 0x17, ENTRY_CopyBytes2Mod }, // MOVHPD
- { 0x18, ENTRY_CopyBytes2Mod }, // PREFETCHINTA...
- { 0x19, ENTRY_Invalid }, // _19
- { 0x1A, ENTRY_Invalid }, // _1A
- { 0x1B, ENTRY_Invalid }, // _1B
- { 0x1C, ENTRY_Invalid }, // _1C
- { 0x1D, ENTRY_Invalid }, // _1D
- { 0x1E, ENTRY_Invalid }, // _1E
- { 0x1F, ENTRY_Invalid }, // _1F
- { 0x20, ENTRY_CopyBytes2Mod }, // MOV/r
- { 0x21, ENTRY_CopyBytes2Mod }, // MOV/r
- { 0x22, ENTRY_CopyBytes2Mod }, // MOV/r
- { 0x23, ENTRY_CopyBytes2Mod }, // MOV/r
- { 0x24, ENTRY_Invalid }, // _24
- { 0x25, ENTRY_Invalid }, // _25
- { 0x26, ENTRY_Invalid }, // _26
- { 0x27, ENTRY_Invalid }, // _27
- { 0x28, ENTRY_CopyBytes2Mod }, // MOVAPS MOVAPD
- { 0x29, ENTRY_CopyBytes2Mod }, // MOVAPS MOVAPD
- { 0x2A, ENTRY_CopyBytes2Mod }, // CVPI2PS &
- { 0x2B, ENTRY_CopyBytes2Mod }, // MOVNTPS MOVNTPD
- { 0x2C, ENTRY_CopyBytes2Mod }, // CVTTPS2PI &
- { 0x2D, ENTRY_CopyBytes2Mod }, // CVTPS2PI &
- { 0x2E, ENTRY_CopyBytes2Mod }, // UCOMISS UCOMISD
- { 0x2F, ENTRY_CopyBytes2Mod }, // COMISS COMISD
- { 0x30, ENTRY_CopyBytes2 }, // WRMSR
- { 0x31, ENTRY_CopyBytes2 }, // RDTSC
- { 0x32, ENTRY_CopyBytes2 }, // RDMSR
- { 0x33, ENTRY_CopyBytes2 }, // RDPMC
- { 0x34, ENTRY_CopyBytes2 }, // SYSENTER
- { 0x35, ENTRY_CopyBytes2 }, // SYSEXIT
- { 0x36, ENTRY_Invalid }, // _36
- { 0x37, ENTRY_Invalid }, // _37
- { 0x38, ENTRY_Invalid }, // _38
- { 0x39, ENTRY_Invalid }, // _39
- { 0x3A, ENTRY_Invalid }, // _3A
- { 0x3B, ENTRY_Invalid }, // _3B
- { 0x3C, ENTRY_Invalid }, // _3C
- { 0x3D, ENTRY_Invalid }, // _3D
- { 0x3E, ENTRY_Invalid }, // _3E
- { 0x3F, ENTRY_Invalid }, // _3F
- { 0x40, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40)
- { 0x41, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41)
- { 0x42, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVNE (0F 42)
- { 0x43, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB (0F 43)
- { 0x44, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44)
- { 0x45, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45)
- { 0x46, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46)
- { 0x47, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47)
- { 0x48, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48)
- { 0x49, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49)
- { 0x4A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A)
- { 0x4B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B)
- { 0x4C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C)
- { 0x4D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D)
- { 0x4E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E)
- { 0x4F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F)
- { 0x50, ENTRY_CopyBytes2Mod }, // MOVMSKPD MOVMSKPD
- { 0x51, ENTRY_CopyBytes2Mod }, // SQRTPS &
- { 0x52, ENTRY_CopyBytes2Mod }, // RSQRTTS RSQRTPS
- { 0x53, ENTRY_CopyBytes2Mod }, // RCPPS RCPSS
- { 0x54, ENTRY_CopyBytes2Mod }, // ANDPS ANDPD
- { 0x55, ENTRY_CopyBytes2Mod }, // ANDNPS ANDNPD
- { 0x56, ENTRY_CopyBytes2Mod }, // ORPS ORPD
- { 0x57, ENTRY_CopyBytes2Mod }, // XORPS XORPD
- { 0x58, ENTRY_CopyBytes2Mod }, // ADDPS &
- { 0x59, ENTRY_CopyBytes2Mod }, // MULPS &
- { 0x5A, ENTRY_CopyBytes2Mod }, // CVTPS2PD &
- { 0x5B, ENTRY_CopyBytes2Mod }, // CVTDQ2PS &
- { 0x5C, ENTRY_CopyBytes2Mod }, // SUBPS &
- { 0x5D, ENTRY_CopyBytes2Mod }, // MINPS &
- { 0x5E, ENTRY_CopyBytes2Mod }, // DIVPS &
- { 0x5F, ENTRY_CopyBytes2Mod }, // MASPS &
- { 0x60, ENTRY_CopyBytes2Mod }, // PUNPCKLBW/r
- { 0x61, ENTRY_CopyBytes2Mod }, // PUNPCKLWD/r
- { 0x62, ENTRY_CopyBytes2Mod }, // PUNPCKLWD/r
- { 0x63, ENTRY_CopyBytes2Mod }, // PACKSSWB/r
- { 0x64, ENTRY_CopyBytes2Mod }, // PCMPGTB/r
- { 0x65, ENTRY_CopyBytes2Mod }, // PCMPGTW/r
- { 0x66, ENTRY_CopyBytes2Mod }, // PCMPGTD/r
- { 0x67, ENTRY_CopyBytes2Mod }, // PACKUSWB/r
- { 0x68, ENTRY_CopyBytes2Mod }, // PUNPCKHBW/r
- { 0x69, ENTRY_CopyBytes2Mod }, // PUNPCKHWD/r
- { 0x6A, ENTRY_CopyBytes2Mod }, // PUNPCKHDQ/r
- { 0x6B, ENTRY_CopyBytes2Mod }, // PACKSSDW/r
- { 0x6C, ENTRY_CopyBytes2Mod }, // PUNPCKLQDQ
- { 0x6D, ENTRY_CopyBytes2Mod }, // PUNPCKHQDQ
- { 0x6E, ENTRY_CopyBytes2Mod }, // MOVD/r
- { 0x6F, ENTRY_CopyBytes2Mod }, // MOV/r
- { 0x70, ENTRY_CopyBytes2Mod1 }, // PSHUFW/r ib
- { 0x71, ENTRY_CopyBytes2Mod1 }, // PSLLW/6 ib,PSRAW/4 ib,PSRLW/2 ib
- { 0x72, ENTRY_CopyBytes2Mod1 }, // PSLLD/6 ib,PSRAD/4 ib,PSRLD/2 ib
- { 0x73, ENTRY_CopyBytes2Mod1 }, // PSLLQ/6 ib,PSRLQ/2 ib
- { 0x74, ENTRY_CopyBytes2Mod }, // PCMPEQB/r
- { 0x75, ENTRY_CopyBytes2Mod }, // PCMPEQW/r
- { 0x76, ENTRY_CopyBytes2Mod }, // PCMPEQD/r
- { 0x77, ENTRY_CopyBytes2 }, // EMMS
- { 0x78, ENTRY_Invalid }, // _78
- { 0x79, ENTRY_Invalid }, // _79
- { 0x7A, ENTRY_Invalid }, // _7A
- { 0x7B, ENTRY_Invalid }, // _7B
- { 0x7C, ENTRY_Invalid }, // _7C
- { 0x7D, ENTRY_Invalid }, // _7D
- { 0x7E, ENTRY_CopyBytes2Mod }, // MOVD/r
- { 0x7F, ENTRY_CopyBytes2Mod }, // MOV/r
- { 0x80, ENTRY_CopyBytes3Or5Target }, // JO
- { 0x81, ENTRY_CopyBytes3Or5Target }, // JNO
- { 0x82, ENTRY_CopyBytes3Or5Target }, // JB,JC,JNAE
- { 0x83, ENTRY_CopyBytes3Or5Target }, // JAE,JNB,JNC
- { 0x84, ENTRY_CopyBytes3Or5Target }, // JE,JZ,JZ
- { 0x85, ENTRY_CopyBytes3Or5Target }, // JNE,JNZ
- { 0x86, ENTRY_CopyBytes3Or5Target }, // JBE,JNA
- { 0x87, ENTRY_CopyBytes3Or5Target }, // JA,JNBE
- { 0x88, ENTRY_CopyBytes3Or5Target }, // JS
- { 0x89, ENTRY_CopyBytes3Or5Target }, // JNS
- { 0x8A, ENTRY_CopyBytes3Or5Target }, // JP,JPE
- { 0x8B, ENTRY_CopyBytes3Or5Target }, // JNP,JPO
- { 0x8C, ENTRY_CopyBytes3Or5Target }, // JL,NGE
- { 0x8D, ENTRY_CopyBytes3Or5Target }, // JGE,JNL
- { 0x8E, ENTRY_CopyBytes3Or5Target }, // JLE,JNG
- { 0x8F, ENTRY_CopyBytes3Or5Target }, // JG,JNLE
- { 0x90, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40)
- { 0x91, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41)
- { 0x92, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVC & CMOVNAE (0F 42)
- { 0x93, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB & CMOVNC (0F 43)
- { 0x94, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44)
- { 0x95, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45)
- { 0x96, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46)
- { 0x97, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47)
- { 0x98, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48)
- { 0x99, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49)
- { 0x9A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A)
- { 0x9B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B)
- { 0x9C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C)
- { 0x9D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D)
- { 0x9E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E)
- { 0x9F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F)
- { 0xA0, ENTRY_CopyBytes2 }, // PUSH
- { 0xA1, ENTRY_CopyBytes2 }, // POP
- { 0xA2, ENTRY_CopyBytes2 }, // CPUID
- { 0xA3, ENTRY_CopyBytes2Mod }, // BT (0F A3)
- { 0xA4, ENTRY_CopyBytes2Mod1 }, // SHLD
- { 0xA5, ENTRY_CopyBytes2Mod }, // SHLD
- { 0xA6, ENTRY_Invalid }, // _A6
- { 0xA7, ENTRY_Invalid }, // _A7
- { 0xA8, ENTRY_CopyBytes2 }, // PUSH
- { 0xA9, ENTRY_CopyBytes2 }, // POP
- { 0xAA, ENTRY_CopyBytes2 }, // RSM
- { 0xAB, ENTRY_CopyBytes2Mod }, // BTS (0F AB)
- { 0xAC, ENTRY_CopyBytes2Mod1 }, // SHRD
- { 0xAD, ENTRY_CopyBytes2Mod }, // SHRD
- { 0xAE, ENTRY_CopyBytes2Mod }, // FXRSTOR/1,FXSAVE/0
- { 0xAF, ENTRY_CopyBytes2Mod }, // IMUL (0F AF)
- { 0xB0, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B0)
- { 0xB1, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B1)
- { 0xB2, ENTRY_CopyBytes2Mod }, // LSS/r
- { 0xB3, ENTRY_CopyBytes2Mod }, // BTR (0F B3)
- { 0xB4, ENTRY_CopyBytes2Mod }, // LFS/r
- { 0xB5, ENTRY_CopyBytes2Mod }, // LGS/r
- { 0xB6, ENTRY_CopyBytes2Mod }, // MOVZX/r
- { 0xB7, ENTRY_CopyBytes2Mod }, // MOVZX/r
- { 0xB8, ENTRY_Invalid }, // _B8
- { 0xB9, ENTRY_Invalid }, // _B9
- { 0xBA, ENTRY_CopyBytes2Mod1 }, // BT & BTC & BTR & BTS (0F BA)
- { 0xBB, ENTRY_CopyBytes2Mod }, // BTC (0F BB)
- { 0xBC, ENTRY_CopyBytes2Mod }, // BSF (0F BC)
- { 0xBD, ENTRY_CopyBytes2Mod }, // BSR (0F BD)
- { 0xBE, ENTRY_CopyBytes2Mod }, // MOVSX/r
- { 0xBF, ENTRY_CopyBytes2Mod }, // MOVSX/r
- { 0xC0, ENTRY_CopyBytes2Mod }, // XADD/r
- { 0xC1, ENTRY_CopyBytes2Mod }, // XADD/r
- { 0xC2, ENTRY_CopyBytes2Mod }, // CMPPS &
- { 0xC3, ENTRY_CopyBytes2Mod }, // MOVNTI
- { 0xC4, ENTRY_CopyBytes2Mod1 }, // PINSRW /r ib
- { 0xC5, ENTRY_CopyBytes2Mod1 }, // PEXTRW /r ib
- { 0xC6, ENTRY_CopyBytes2Mod1 }, // SHUFPS & SHUFPD
- { 0xC7, ENTRY_CopyBytes2Mod }, // CMPXCHG8B (0F C7)
- { 0xC8, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
- { 0xC9, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
- { 0xCA, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
- { 0xCB, ENTRY_CopyBytes2 }, //CVTPD2PI BSWAP 0F C8 + rd
- { 0xCC, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
- { 0xCD, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
- { 0xCE, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
- { 0xCF, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
- { 0xD0, ENTRY_Invalid }, // _D0
- { 0xD1, ENTRY_CopyBytes2Mod }, // PSRLW/r
- { 0xD2, ENTRY_CopyBytes2Mod }, // PSRLD/r
- { 0xD3, ENTRY_CopyBytes2Mod }, // PSRLQ/r
- { 0xD4, ENTRY_CopyBytes2Mod }, // PADDQ
- { 0xD5, ENTRY_CopyBytes2Mod }, // PMULLW/r
- { 0xD6, ENTRY_CopyBytes2Mod }, // MOVDQ2Q / MOVQ2DQ
- { 0xD7, ENTRY_CopyBytes2Mod }, // PMOVMSKB/r
- { 0xD8, ENTRY_CopyBytes2Mod }, // PSUBUSB/r
- { 0xD9, ENTRY_CopyBytes2Mod }, // PSUBUSW/r
- { 0xDA, ENTRY_CopyBytes2Mod }, // PMINUB/r
- { 0xDB, ENTRY_CopyBytes2Mod }, // PAND/r
- { 0xDC, ENTRY_CopyBytes2Mod }, // PADDUSB/r
- { 0xDD, ENTRY_CopyBytes2Mod }, // PADDUSW/r
- { 0xDE, ENTRY_CopyBytes2Mod }, // PMAXUB/r
- { 0xDF, ENTRY_CopyBytes2Mod }, // PANDN/r
- { 0xE0, ENTRY_CopyBytes2Mod }, // PAVGB
- { 0xE1, ENTRY_CopyBytes2Mod }, // PSRAW/r
- { 0xE2, ENTRY_CopyBytes2Mod }, // PSRAD/r
- { 0xE3, ENTRY_CopyBytes2Mod }, // PAVGW
- { 0xE4, ENTRY_CopyBytes2Mod }, // PMULHUW/r
- { 0xE5, ENTRY_CopyBytes2Mod }, // PMULHW/r
- { 0xE6, ENTRY_CopyBytes2Mod }, // CTDQ2PD &
- { 0xE7, ENTRY_CopyBytes2Mod }, // MOVNTQ
- { 0xE8, ENTRY_CopyBytes2Mod }, // PSUBB/r
- { 0xE9, ENTRY_CopyBytes2Mod }, // PSUBW/r
- { 0xEA, ENTRY_CopyBytes2Mod }, // PMINSW/r
- { 0xEB, ENTRY_CopyBytes2Mod }, // POR/r
- { 0xEC, ENTRY_CopyBytes2Mod }, // PADDSB/r
- { 0xED, ENTRY_CopyBytes2Mod }, // PADDSW/r
- { 0xEE, ENTRY_CopyBytes2Mod }, // PMAXSW /r
- { 0xEF, ENTRY_CopyBytes2Mod }, // PXOR/r
- { 0xF0, ENTRY_Invalid }, // _F0
- { 0xF1, ENTRY_CopyBytes2Mod }, // PSLLW/r
- { 0xF2, ENTRY_CopyBytes2Mod }, // PSLLD/r
- { 0xF3, ENTRY_CopyBytes2Mod }, // PSLLQ/r
- { 0xF4, ENTRY_CopyBytes2Mod }, // PMULUDQ/r
- { 0xF5, ENTRY_CopyBytes2Mod }, // PMADDWD/r
- { 0xF6, ENTRY_CopyBytes2Mod }, // PSADBW/r
- { 0xF7, ENTRY_CopyBytes2Mod }, // MASKMOVQ
- { 0xF8, ENTRY_CopyBytes2Mod }, // PSUBB/r
- { 0xF9, ENTRY_CopyBytes2Mod }, // PSUBW/r
- { 0xFA, ENTRY_CopyBytes2Mod }, // PSUBD/r
- { 0xFB, ENTRY_CopyBytes2Mod }, // FSUBQ/r
- { 0xFC, ENTRY_CopyBytes2Mod }, // PADDB/r
- { 0xFD, ENTRY_CopyBytes2Mod }, // PADDW/r
- { 0xFE, ENTRY_CopyBytes2Mod }, // PADDD/r
- { 0xFF, ENTRY_Invalid }, // _FF
- { 0, ENTRY_End }, };
- BOOL CDetourDis::SanityCheckSystem()
- {
- ULONG n = 0;
- for ( ; n < 256; n++ )
- {
- REFCOPYENTRY pEntry = &s_rceCopyTable[n];
- if ( n != pEntry->nOpcode )
- {
- ASSERT( n == pEntry->nOpcode );
- return FALSE;
- }
- }
- if ( s_rceCopyTable[256].pfCopy != NULL )
- {
- ASSERT( !"Missing end marker." );
- return FALSE;
- }
- for ( n = 0; n < 256; n++ )
- {
- REFCOPYENTRY pEntry = &s_rceCopyTable0F[n];
- if ( n != pEntry->nOpcode )
- {
- ASSERT( n == pEntry->nOpcode );
- return FALSE;
- }
- }
- if ( s_rceCopyTable0F[256].pfCopy != NULL )
- {
- ASSERT( !"Missing end marker." );
- return FALSE;
- }
- return TRUE;
- }
- #endif // defined(DETOURS_X64) || defined(DETOURS_X86)
- /////////////////////////////////////////////////////////// IA64 Disassembler.
- //
- #ifdef DETOURS_IA64
- #error Feature not supported in this release.
- #endif // DETOURS_IA64
- //
- ///////////////////////////////////////////////////////////////// End of File.
|