From 931fc1c573e4847064f0e2dbe770b63f1c424528 Mon Sep 17 00:00:00 2001 From: Ratin Gao Date: Sun, 3 Dec 2023 02:26:02 +0800 Subject: [PATCH] [REFACTOR] Reduce code size for x86 and x64 - Deduplicate code - Reduce constant table size (see also https://github.com/microsoft/Detours/pull/191 by jdp1024) --- Source/detours.cpp | 288 ++-------- Source/disasm.cpp | 1368 +++++++++++++++++++++++--------------------- 2 files changed, 748 insertions(+), 908 deletions(-) diff --git a/Source/detours.cpp b/Source/detours.cpp index 02b34fee..bfecf40a 100644 --- a/Source/detours.cpp +++ b/Source/detours.cpp @@ -135,27 +135,35 @@ inline ULONG_PTR detour_2gb_above(ULONG_PTR address) #endif } -#if defined(_M_IX86) +#if defined(_M_IX86) || defined(_M_X64) struct _DETOUR_TRAMPOLINE { - BYTE rbCode[30]; // target code + jmp to pbRemain + // An X64 instuction can be 15 bytes long. + // In practice 11 seems to be the limit. + BYTE rbCode[30]; // target code + jmp to pbRemain. BYTE cbCode; // size of moved target code. BYTE cbCodeBreak; // padding to make debugging easier. +#if defined(_M_X64) + BYTE rbRestore[30]; // original target code. +#else BYTE rbRestore[22]; // original target code. +#endif BYTE cbRestore; // size of original target code. BYTE cbRestoreBreak; // padding to make debugging easier. _DETOUR_ALIGN rAlign[8]; // instruction alignment array. PBYTE pbRemain; // first instruction after moved code. [free list] PBYTE pbDetour; // first instruction of detour function. +#if defined(_M_X64) + BYTE rbCodeIn[8]; // jmp [pbDetour] +#endif }; +#if defined(_M_IX86) static_assert(sizeof(_DETOUR_TRAMPOLINE) == 72); - -enum -{ - SIZE_OF_JMP = 5 -}; +#else +static_assert(sizeof(_DETOUR_TRAMPOLINE) == 96); +#endif inline PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE pbJmpVal) { @@ -169,7 +177,11 @@ inline PBYTE detour_gen_jmp_indirect(PBYTE pbCode, PBYTE* ppbJmpVal) { *pbCode++ = 0xff; // jmp [+imm32] *pbCode++ = 0x25; +#if defined(_M_IX86) *((INT32*&)pbCode)++ = (INT32)((PBYTE)ppbJmpVal); +#else + *((INT32*&)pbCode)++ = (INT32)((PBYTE)ppbJmpVal - (pbCode + 6)); +#endif return pbCode; } @@ -196,9 +208,15 @@ inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID* ppGlobals) // First, skip over the import vector if there is one. if (pbCode[0] == 0xff && pbCode[1] == 0x25) { - // jmp [imm32] // Looks like an import alias jump, then get the code it points to. +#if defined(_M_IX86) + // jmp [imm32] PBYTE pbTarget = *(UNALIGNED PBYTE*) & pbCode[2]; +#else + // jmp [+imm32] + PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32*) & pbCode[2]; +#endif + if (detour_is_imported(pbCode, pbTarget)) { PBYTE pbNew = *(UNALIGNED PBYTE*)pbTarget; @@ -218,9 +236,14 @@ inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID* ppGlobals) // First, skip over the import vector if there is one. if (pbCode[0] == 0xff && pbCode[1] == 0x25) { - // jmp [imm32] // Looks like an import alias jump, then get the code it points to. +#if defined(_M_IX86) + // jmp [imm32] PBYTE pbTarget = *(UNALIGNED PBYTE*) & pbCode[2]; +#else + // jmp [+imm32] + PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32*) & pbCode[2]; +#endif if (detour_is_imported(pbCode, pbTarget)) { pbNew = *(UNALIGNED PBYTE*)pbTarget; @@ -262,227 +285,9 @@ inline void detour_find_jmp_bounds(PBYTE pbCode, PDETOUR_TRAMPOLINE* ppLower, PD } DETOUR_TRACE("[%p..%p..%p] +imm32\n", (PVOID)lo, pbCode, (PVOID)hi); } - - *ppLower = (PDETOUR_TRAMPOLINE)lo; - *ppUpper = (PDETOUR_TRAMPOLINE)hi; -} - -inline BOOL detour_does_code_end_function(PBYTE pbCode) -{ - if (pbCode[0] == 0xeb || // jmp +imm8 - pbCode[0] == 0xe9 || // jmp +imm32 - pbCode[0] == 0xe0 || // jmp eax - pbCode[0] == 0xc2 || // ret +imm8 - pbCode[0] == 0xc3 || // ret - pbCode[0] == 0xcc) - { - // brk - return TRUE; - } else if (pbCode[0] == 0xf3 && pbCode[1] == 0xc3) - { - // rep ret - return TRUE; - } else if (pbCode[0] == 0xff && pbCode[1] == 0x25) - { - // jmp [+imm32] - return TRUE; - } else if ((pbCode[0] == 0x26 || // jmp es: - pbCode[0] == 0x2e || // jmp cs: - pbCode[0] == 0x36 || // jmp ss: - pbCode[0] == 0x3e || // jmp ds: - pbCode[0] == 0x64 || // jmp fs: - pbCode[0] == 0x65) && // jmp gs: - pbCode[1] == 0xff && // jmp [+imm32] - pbCode[2] == 0x25) - { - return TRUE; - } - return FALSE; -} - -inline ULONG detour_is_code_filler(PBYTE pbCode) -{ - // 1-byte through 11-byte NOPs. - if (pbCode[0] == 0x90) - { - return 1; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x90) - { - return 2; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x00) - { - return 3; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x40 && pbCode[3] == 0x00) - { - return 4; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x44 && pbCode[3] == 0x00 && pbCode[4] == 0x00) - { - return 5; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && pbCode[3] == 0x44 && pbCode[4] == 0x00 && - pbCode[5] == 0x00) - { - return 6; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x80 && pbCode[3] == 0x00 && pbCode[4] == 0x00 && - pbCode[5] == 0x00 && pbCode[6] == 0x00) - { - return 7; - } - if (pbCode[0] == 0x0F && pbCode[1] == 0x1F && pbCode[2] == 0x84 && pbCode[3] == 0x00 && pbCode[4] == 0x00 && - pbCode[5] == 0x00 && pbCode[6] == 0x00 && pbCode[7] == 0x00) - { - return 8; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x0F && pbCode[2] == 0x1F && pbCode[3] == 0x84 && pbCode[4] == 0x00 && - pbCode[5] == 0x00 && pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00) - { - return 9; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x0F && pbCode[3] == 0x1F && pbCode[4] == 0x84 && - pbCode[5] == 0x00 && pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && pbCode[9] == 0x00) - { - return 10; - } - if (pbCode[0] == 0x66 && pbCode[1] == 0x66 && pbCode[2] == 0x66 && pbCode[3] == 0x0F && pbCode[4] == 0x1F && - pbCode[5] == 0x84 && pbCode[6] == 0x00 && pbCode[7] == 0x00 && pbCode[8] == 0x00 && pbCode[9] == 0x00 && - pbCode[10] == 0x00) - { - return 11; - } - - // int 3. - if (pbCode[0] == 0xCC) - { - return 1; - } - return 0; -} - -#endif // defined(_M_IX86) - #if defined(_M_X64) - -struct _DETOUR_TRAMPOLINE -{ - // An X64 instuction can be 15 bytes long. - // In practice 11 seems to be the limit. - BYTE rbCode[30]; // target code + jmp to pbRemain. - BYTE cbCode; // size of moved target code. - BYTE cbCodeBreak; // padding to make debugging easier. - BYTE rbRestore[30]; // original target code. - BYTE cbRestore; // size of original target code. - BYTE cbRestoreBreak; // padding to make debugging easier. - _DETOUR_ALIGN rAlign[8]; // instruction alignment array. - PBYTE pbRemain; // first instruction after moved code. [free list] - PBYTE pbDetour; // first instruction of detour function. - BYTE rbCodeIn[8]; // jmp [pbDetour] -}; - -static_assert(sizeof(_DETOUR_TRAMPOLINE) == 96); - -enum -{ - SIZE_OF_JMP = 5 -}; - -inline PBYTE detour_gen_jmp_immediate(PBYTE pbCode, PBYTE pbJmpVal) -{ - PBYTE pbJmpSrc = pbCode + 5; - *pbCode++ = 0xe9; // jmp +imm32 - *((INT32*&)pbCode)++ = (INT32)(pbJmpVal - pbJmpSrc); - return pbCode; -} - -inline PBYTE detour_gen_jmp_indirect(PBYTE pbCode, PBYTE* ppbJmpVal) -{ - PBYTE pbJmpSrc = pbCode + 6; - *pbCode++ = 0xff; // jmp [+imm32] - *pbCode++ = 0x25; - *((INT32*&)pbCode)++ = (INT32)((PBYTE)ppbJmpVal - pbJmpSrc); - return pbCode; -} - -inline PBYTE detour_gen_brk(PBYTE pbCode, PBYTE pbLimit) -{ - while (pbCode < pbLimit) - { - *pbCode++ = 0xcc; // brk; - } - return pbCode; -} - -inline PBYTE detour_skip_jmp(PBYTE pbCode, PVOID* ppGlobals) -{ - if (pbCode == NULL) - { - return NULL; - } - if (ppGlobals != NULL) - { - *ppGlobals = NULL; - } - - // First, skip over the import vector if there is one. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) - { - // jmp [+imm32] - // Looks like an import alias jump, then get the code it points to. - PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32*) & pbCode[2]; - if (detour_is_imported(pbCode, pbTarget)) - { - PBYTE pbNew = *(UNALIGNED PBYTE*)pbTarget; - DETOUR_TRACE("%p->%p: skipped over import table.\n", pbCode, pbNew); - pbCode = pbNew; - } - } - - // Then, skip over a patch jump - if (pbCode[0] == 0xeb) - { - // jmp +imm8 - PBYTE pbNew = pbCode + 2 + *(CHAR*)&pbCode[1]; - DETOUR_TRACE("%p->%p: skipped over short jump.\n", pbCode, pbNew); - pbCode = pbNew; - - // First, skip over the import vector if there is one. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) - { - // jmp [+imm32] - // Looks like an import alias jump, then get the code it points to. - PBYTE pbTarget = pbCode + 6 + *(UNALIGNED INT32*) & pbCode[2]; - if (detour_is_imported(pbCode, pbTarget)) - { - pbNew = *(UNALIGNED PBYTE*)pbTarget; - DETOUR_TRACE("%p->%p: skipped over import table.\n", pbCode, pbNew); - pbCode = pbNew; - } - } - // Finally, skip over a long jump if it is the target of the patch jump. - else if (pbCode[0] == 0xe9) - { - // jmp +imm32 - pbNew = pbCode + 5 + *(UNALIGNED INT32*) & pbCode[1]; - DETOUR_TRACE("%p->%p: skipped over long jump.\n", pbCode, pbNew); - pbCode = pbNew; - } - } - return pbCode; -} - -inline void detour_find_jmp_bounds(PBYTE pbCode, PDETOUR_TRAMPOLINE* ppLower, PDETOUR_TRAMPOLINE* ppUpper) -{ - // We have to place trampolines within +/- 2GB of code. - ULONG_PTR lo = detour_2gb_below((ULONG_PTR)pbCode); - ULONG_PTR hi = detour_2gb_above((ULONG_PTR)pbCode); - DETOUR_TRACE("[%p..%p..%p]\n", (PVOID)lo, pbCode, (PVOID)hi); - // And, within +/- 2GB of relative jmp vectors. - if (pbCode[0] == 0xff && pbCode[1] == 0x25) + else if (pbCode[0] == 0xff && pbCode[1] == 0x25) { // jmp [+imm32] PBYTE pbNew = pbCode + 6 + *(UNALIGNED INT32*) & pbCode[2]; @@ -496,22 +301,8 @@ inline void detour_find_jmp_bounds(PBYTE pbCode, PDETOUR_TRAMPOLINE* ppLower, PD } DETOUR_TRACE("[%p..%p..%p] [+imm32]\n", (PVOID)lo, pbCode, (PVOID)hi); } - // And, within +/- 2GB of relative jmp targets. - else if (pbCode[0] == 0xe9) - { - // jmp +imm32 - PBYTE pbNew = pbCode + 5 + *(UNALIGNED INT32*) & pbCode[1]; - - if (pbNew < pbCode) - { - hi = detour_2gb_above((ULONG_PTR)pbNew); - } else - { - lo = detour_2gb_below((ULONG_PTR)pbNew); - } - DETOUR_TRACE("[%p..%p..%p] +imm32\n", (PVOID)lo, pbCode, (PVOID)hi); - } - +#endif + *ppLower = (PDETOUR_TRAMPOLINE)lo; *ppUpper = (PDETOUR_TRAMPOLINE)hi; } @@ -612,7 +403,7 @@ inline ULONG detour_is_code_filler(PBYTE pbCode) return 0; } -#endif // defined(_M_X64) +#endif // defined(_M_IX86) || defined(_M_X64) #if defined(_M_ARM64) @@ -655,11 +446,6 @@ struct _DETOUR_TRAMPOLINE static_assert(sizeof(_DETOUR_TRAMPOLINE) == 184); -enum -{ - SIZE_OF_JMP = 12 -}; - inline ULONG fetch_opcode(PBYTE pbCode) { return *(ULONG*)pbCode; @@ -1849,7 +1635,7 @@ NTSTATUS NTAPI DetourAttachEx( PBYTE pbTrampoline = pTrampoline->rbCode; PBYTE pbPool = pbTrampoline + sizeof(pTrampoline->rbCode); ULONG cbTarget = 0; - ULONG cbJump = SIZE_OF_JMP; + ULONG cbJump = 5; ULONG nAlign = 0; while (cbTarget < cbJump) diff --git a/Source/disasm.cpp b/Source/disasm.cpp index 5de13a84..037e1a39 100644 --- a/Source/disasm.cpp +++ b/Source/disasm.cpp @@ -125,64 +125,56 @@ class CDetourDis COPYFUNC pfCopy; // Function pointer. }; -protected: -// These macros define common uses of nFixedSize, nFixedSize16, nModOffset, nRelOffset, nFlagBits, pfCopy. -#define ENTRY_DataIgnored 0, 0, 0, 0, 0, -#define ENTRY_CopyBytes1 { 1, 1, 0, 0, 0, &CDetourDis::CopyBytes } -#if defined(_M_X64) -#define ENTRY_CopyBytes1Address { 9, 5, 0, 0, ADDRESS, &CDetourDis::CopyBytes } -#else -#define ENTRY_CopyBytes1Address { 5, 3, 0, 0, ADDRESS, &CDetourDis::CopyBytes } -#endif -#define ENTRY_CopyBytes1Dynamic { 1, 1, 0, 0, DYNAMIC, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes2 { 2, 2, 0, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes2Jump { ENTRY_DataIgnored &CDetourDis::CopyBytesJump } -#define ENTRY_CopyBytes2CantJump { 2, 2, 0, 1, NOENLARGE, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes2Dynamic { 2, 2, 0, 0, DYNAMIC, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes3 { 3, 3, 0, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes3Dynamic { 3, 3, 0, 0, DYNAMIC, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes3Or5 { 5, 3, 0, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes3Or5Dynamic { 5, 3, 0, 0, DYNAMIC, &CDetourDis::CopyBytes } // x86 only -#if defined(_M_X64) -#define ENTRY_CopyBytes3Or5Rax { 5, 3, 0, 0, RAX, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes3Or5Target { 5, 5, 0, 1, 0, &CDetourDis::CopyBytes } -#else -#define ENTRY_CopyBytes3Or5Rax { 5, 3, 0, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes3Or5Target { 5, 3, 0, 1, 0, &CDetourDis::CopyBytes } -#endif -#define ENTRY_CopyBytes4 { 4, 4, 0, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes5 { 5, 5, 0, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes5Or7Dynamic { 7, 5, 0, 0, DYNAMIC, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes7 { 7, 7, 0, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes2Mod { 2, 2, 1, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes2ModDynamic { 2, 2, 1, 0, DYNAMIC, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes2Mod1 { 3, 3, 1, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes2ModOperand { 6, 4, 1, 0, 0, &CDetourDis::CopyBytes } -#define ENTRY_CopyBytes3Mod { 3, 3, 2, 0, 0, &CDetourDis::CopyBytes } // SSE3 0F 38 opcode modrm -#define ENTRY_CopyBytes3Mod1 { 4, 4, 2, 0, 0, &CDetourDis::CopyBytes } // SSE3 0F 3A opcode modrm .. imm8 -#define ENTRY_CopyBytesPrefix { ENTRY_DataIgnored &CDetourDis::CopyBytesPrefix } -#define ENTRY_CopyBytesSegment { ENTRY_DataIgnored &CDetourDis::CopyBytesSegment } -#define ENTRY_CopyBytesRax { ENTRY_DataIgnored &CDetourDis::CopyBytesRax } -#define ENTRY_CopyF2 { ENTRY_DataIgnored &CDetourDis::CopyF2 } -#define ENTRY_CopyF3 { ENTRY_DataIgnored &CDetourDis::CopyF3 } // 32bit x86 only -#define ENTRY_Copy0F { ENTRY_DataIgnored &CDetourDis::Copy0F } -#define ENTRY_Copy0F78 { ENTRY_DataIgnored &CDetourDis::Copy0F78 } -#define ENTRY_Copy0F00 { ENTRY_DataIgnored &CDetourDis::Copy0F00 } // 32bit x86 only -#define ENTRY_Copy0FB8 { ENTRY_DataIgnored &CDetourDis::Copy0FB8 } // 32bit x86 only -#define ENTRY_Copy66 { ENTRY_DataIgnored &CDetourDis::Copy66 } -#define ENTRY_Copy67 { ENTRY_DataIgnored &CDetourDis::Copy67 } -#define ENTRY_CopyF6 { ENTRY_DataIgnored &CDetourDis::CopyF6 } -#define ENTRY_CopyF7 { ENTRY_DataIgnored &CDetourDis::CopyF7 } -#define ENTRY_CopyFF { ENTRY_DataIgnored &CDetourDis::CopyFF } -#define ENTRY_CopyVex2 { ENTRY_DataIgnored &CDetourDis::CopyVex2 } -#define ENTRY_CopyVex3 { ENTRY_DataIgnored &CDetourDis::CopyVex3 } -#define ENTRY_CopyEvex { ENTRY_DataIgnored &CDetourDis::CopyEvex } // 62, 3 byte payload, then normal with implied prefixes like vex -#define ENTRY_CopyXop { ENTRY_DataIgnored &CDetourDis::CopyXop } // 0x8F ... POP /0 or AMD XOP -#define ENTRY_CopyBytesXop { 5, 5, 4, 0, 0, &CDetourDis::CopyBytes } // 0x8F xop1 xop2 opcode modrm -#define ENTRY_CopyBytesXop1 { 6, 6, 4, 0, 0, &CDetourDis::CopyBytes } // 0x8F xop1 xop2 opcode modrm ... imm8 -#define ENTRY_CopyBytesXop4 { 9, 9, 4, 0, 0, &CDetourDis::CopyBytes } // 0x8F xop1 xop2 opcode modrm ... imm32 -#define ENTRY_Invalid { ENTRY_DataIgnored &CDetourDis::Invalid } + enum + { + eENTRY_CopyBytes1 = 0, + eENTRY_CopyBytes1Address, + eENTRY_CopyBytes1Dynamic, + eENTRY_CopyBytes2, + eENTRY_CopyBytes2Jump, + eENTRY_CopyBytes2CantJump, + eENTRY_CopyBytes2Dynamic, + eENTRY_CopyBytes3, + eENTRY_CopyBytes3Dynamic, + eENTRY_CopyBytes3Or5, + eENTRY_CopyBytes3Or5Dynamic, + eENTRY_CopyBytes3Or5Rax, + eENTRY_CopyBytes3Or5Target, + eENTRY_CopyBytes4, + eENTRY_CopyBytes5, + eENTRY_CopyBytes5Or7Dynamic, + eENTRY_CopyBytes7, + eENTRY_CopyBytes2Mod, + eENTRY_CopyBytes2ModDynamic, + eENTRY_CopyBytes2Mod1, + eENTRY_CopyBytes2ModOperand, + eENTRY_CopyBytes3Mod, + eENTRY_CopyBytes3Mod1, + eENTRY_CopyBytesPrefix, + eENTRY_CopyBytesSegment, + eENTRY_CopyBytesRax, + eENTRY_CopyF2, + eENTRY_CopyF3, + eENTRY_Copy0F, + eENTRY_Copy0F78, + eENTRY_Copy0F00, + eENTRY_Copy0FB8, + eENTRY_Copy66, + eENTRY_Copy67, + eENTRY_CopyF6, + eENTRY_CopyF7, + eENTRY_CopyFF, + eENTRY_CopyVex2, + eENTRY_CopyVex3, + eENTRY_CopyEvex, + eENTRY_CopyXop, + eENTRY_CopyBytesXop, + eENTRY_CopyBytesXop1, + eENTRY_CopyBytesXop4, + eENTRY_Invalid + }; +protected: PBYTE CopyBytes(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyBytesPrefix(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); PBYTE CopyBytesSegment(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); @@ -214,8 +206,9 @@ class CDetourDis PBYTE CopyXop(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc); protected: - static const COPYENTRY s_rceCopyTable[]; - static const COPYENTRY s_rceCopyTable0F[]; + static const COPYENTRY s_rceCopyMap[]; + static const BYTE s_rceCopyTable[]; + static const BYTE s_rceCopyTable0F[]; static const BYTE s_rbModRm[256]; static PBYTE s_pbModuleBeg; static PBYTE s_pbModuleEnd; @@ -287,7 +280,7 @@ PBYTE CDetourDis::CopyInstruction(PBYTE pbDst, PBYTE pbSrc) // 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]]; + REFCOPYENTRY pEntry = &s_rceCopyMap[s_rceCopyTable[pbSrc[0]]]; return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); } @@ -387,7 +380,7 @@ PBYTE CDetourDis::CopyBytes(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc) PBYTE CDetourDis::CopyBytesPrefix(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc) { pbDst[0] = pbSrc[0]; - pEntry = &s_rceCopyTable[pbSrc[1]]; + pEntry = &s_rceCopyMap[s_rceCopyTable[pbSrc[1]]]; return (this->*pEntry->pfCopy)(pEntry, pbDst + 1, pbSrc + 1); } @@ -537,7 +530,7 @@ PBYTE CDetourDis::Invalid(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc) PBYTE CDetourDis::Copy0F(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc) { pbDst[0] = pbSrc[0]; - pEntry = &s_rceCopyTable0F[pbSrc[1]]; + pEntry = &s_rceCopyMap[s_rceCopyTable0F[pbSrc[1]]]; return (this->*pEntry->pfCopy)(pEntry, pbDst + 1, pbSrc + 1); } @@ -545,8 +538,8 @@ PBYTE CDetourDis::Copy0F78(REFCOPYENTRY, PBYTE pbDst, PBYTE pbSrc) { // vmread, 66/extrq, F2/insertq - static const COPYENTRY vmread = /* 78 */ ENTRY_CopyBytes2Mod; - static const COPYENTRY extrq_insertq = /* 78 */ ENTRY_CopyBytes4; + const BYTE vmread = /* 78 */ eENTRY_CopyBytes2Mod; + const BYTE extrq_insertq = /* 78 */ eENTRY_CopyBytes4; ASSERT(!(m_bF2 && m_bOperandOverride)); @@ -554,7 +547,7 @@ PBYTE CDetourDis::Copy0F78(REFCOPYENTRY, PBYTE pbDst, PBYTE pbSrc) // insertq/extrq/78 are followed by two immediate bytes, and given mode == 11, mod/rm byte is always one byte, // and the 0x78 makes 4 bytes (not counting the 66/F2/F which are accounted for elsewhere) - REFCOPYENTRY const pEntry = ((m_bF2 || m_bOperandOverride) ? &extrq_insertq : &vmread); + REFCOPYENTRY const pEntry = &s_rceCopyMap[((m_bF2 || m_bOperandOverride) ? extrq_insertq : vmread)]; return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); } @@ -564,10 +557,10 @@ PBYTE CDetourDis::Copy0F00(REFCOPYENTRY, PBYTE pbDst, PBYTE pbSrc) // jmpe is 32bit x86 only // Notice that the sizes are the same either way, but jmpe is marked as "dynamic". - static const COPYENTRY other = /* B8 */ ENTRY_CopyBytes2Mod; // sldt/0 str/1 lldt/2 ltr/3 err/4 verw/5 jmpe/6 invalid/7 - static const COPYENTRY jmpe = /* B8 */ ENTRY_CopyBytes2ModDynamic; // jmpe/6 x86-on-IA64 syscalls + const BYTE other = /* B8 */ eENTRY_CopyBytes2Mod; // sldt/0 str/1 lldt/2 ltr/3 err/4 verw/5 jmpe/6 invalid/7 + const BYTE jmpe = /* B8 */ eENTRY_CopyBytes2ModDynamic; // jmpe/6 x86-on-IA64 syscalls - REFCOPYENTRY const pEntry = (((6 << 3) == ((7 << 3) & pbSrc[1])) ? &jmpe : &other); + REFCOPYENTRY const pEntry = &s_rceCopyMap[(((6 << 3) == ((7 << 3) & pbSrc[1])) ? jmpe : other)]; return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); } @@ -575,9 +568,9 @@ PBYTE CDetourDis::Copy0FB8(REFCOPYENTRY, PBYTE pbDst, PBYTE pbSrc) { // jmpe is 32bit x86 only - static const COPYENTRY popcnt = /* B8 */ ENTRY_CopyBytes2Mod; - static const COPYENTRY jmpe = /* B8 */ ENTRY_CopyBytes3Or5Dynamic; // jmpe x86-on-IA64 syscalls - REFCOPYENTRY const pEntry = m_bF3 ? &popcnt : &jmpe; + const BYTE popcnt = /* B8 */ eENTRY_CopyBytes2Mod; + const BYTE jmpe = /* B8 */ eENTRY_CopyBytes3Or5Dynamic; // jmpe x86-on-IA64 syscalls + REFCOPYENTRY const pEntry = &s_rceCopyMap[m_bF3 ? popcnt : jmpe]; return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); } @@ -616,7 +609,7 @@ PBYTE CDetourDis::CopyF6(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc) if (0x00 == (0x38 & pbSrc[1])) { // reg(bits 543) of ModR/M == 0 - static const COPYENTRY ce = /* f6 */ ENTRY_CopyBytes2Mod1; + const COPYENTRY& ce = /* f6 */ s_rceCopyMap[eENTRY_CopyBytes2Mod1]; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } // DIV /6 @@ -626,7 +619,7 @@ PBYTE CDetourDis::CopyF6(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc) // NEG /3 // NOT /2 - static const COPYENTRY ce = /* f6 */ ENTRY_CopyBytes2Mod; + const COPYENTRY& ce = /* f6 */ s_rceCopyMap[eENTRY_CopyBytes2Mod]; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } @@ -638,7 +631,7 @@ PBYTE CDetourDis::CopyF7(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc) if (0x00 == (0x38 & pbSrc[1])) { // reg(bits 543) of ModR/M == 0 - static const COPYENTRY ce = /* f7 */ ENTRY_CopyBytes2ModOperand; + const COPYENTRY& ce = /* f7 */ s_rceCopyMap[eENTRY_CopyBytes2ModOperand]; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } @@ -648,7 +641,7 @@ PBYTE CDetourDis::CopyF7(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc) // MUL /4 // NEG /3 // NOT /2 - static const COPYENTRY ce = /* f7 */ ENTRY_CopyBytes2Mod; + const COPYENTRY& ce = /* f7 */ s_rceCopyMap[eENTRY_CopyBytes2Mod]; return (this->*ce.pfCopy)(&ce, pbDst, pbSrc); } @@ -664,7 +657,7 @@ PBYTE CDetourDis::CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc) // invalid/7 UNREFERENCED_PARAMETER(pEntry); - static const COPYENTRY ce = /* ff */ ENTRY_CopyBytes2Mod; + const COPYENTRY& ce = /* ff */ s_rceCopyMap[eENTRY_CopyBytes2Mod]; PBYTE pbOut = (this->*ce.pfCopy)(&ce, pbDst, pbSrc); BYTE const b1 = pbSrc[1]; @@ -711,9 +704,9 @@ PBYTE CDetourDis::CopyVexEvexCommon(BYTE m, PBYTE pbDst, PBYTE pbSrc, BYTE p, BY // m is first instead of last in the hopes of pbDst/pbSrc being // passed along efficiently in the registers they were already in. { - static const COPYENTRY ceF38 = /* 38 */ ENTRY_CopyBytes2Mod; - static const COPYENTRY ceF3A = /* 3A */ ENTRY_CopyBytes2Mod1; - static const COPYENTRY ceInvalid = /* C4 */ ENTRY_Invalid; + const BYTE ceF38 = /* 38 */ eENTRY_CopyBytes2Mod; + const BYTE ceF3A = /* 3A */ eENTRY_CopyBytes2Mod1; + const BYTE ceInvalid = /* C4 */ eENTRY_Invalid; switch (p & 3) { @@ -728,13 +721,13 @@ PBYTE CDetourDis::CopyVexEvexCommon(BYTE m, PBYTE pbDst, PBYTE pbSrc, BYTE p, BY // see https://software.intel.com/content/www/us/en/develop/download/intel-avx512-fp16-architecture-specification.html switch (m | fp16) { - default: return Invalid(&ceInvalid, pbDst, pbSrc); - case 1: pEntry = &s_rceCopyTable0F[pbSrc[0]]; + default: return Invalid(&s_rceCopyMap[ceInvalid], pbDst, pbSrc); + case 1: pEntry = &s_rceCopyMap[s_rceCopyTable0F[pbSrc[0]]]; return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); case 5: // fallthrough case 6: // fallthrough - case 2: return CopyBytes(&ceF38, pbDst, pbSrc); - case 3: return CopyBytes(&ceF3A, pbDst, pbSrc); + case 2: return CopyBytes(&s_rceCopyMap[ceF38], pbDst, pbSrc); + case 3: return CopyBytes(&s_rceCopyMap[ceF3A], pbDst, pbSrc); } } @@ -752,10 +745,10 @@ PBYTE CDetourDis::CopyVex3(REFCOPYENTRY, PBYTE pbDst, PBYTE pbSrc) // 3 byte VEX prefix 0xC4 { #if defined(_M_IX86) - const static COPYENTRY ceLES = /* C4 */ ENTRY_CopyBytes2Mod; + const BYTE ceLES = /* C4 */ eENTRY_CopyBytes2Mod; if ((pbSrc[1] & 0xC0) != 0xC0) { - REFCOPYENTRY pEntry = &ceLES; + REFCOPYENTRY pEntry = &s_rceCopyMap[ceLES]; return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); } #endif @@ -798,10 +791,10 @@ PBYTE CDetourDis::CopyVex2(REFCOPYENTRY, PBYTE pbDst, PBYTE pbSrc) // 2 byte VEX prefix 0xC5 { #if defined(_M_IX86) - const static COPYENTRY ceLDS = /* C5 */ ENTRY_CopyBytes2Mod; + const BYTE ceLDS = /* C5 */ eENTRY_CopyBytes2Mod; if ((pbSrc[1] & 0xC0) != 0xC0) { - REFCOPYENTRY pEntry = &ceLDS; + REFCOPYENTRY pEntry = &s_rceCopyMap[ceLDS]; return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc); } #endif @@ -820,24 +813,24 @@ PBYTE CDetourDis::CopyEvex(REFCOPYENTRY, PBYTE pbDst, PBYTE pbSrc) BYTE const p0 = pbSrc[1]; #if defined(_M_IX86) - const static COPYENTRY ceBound = /* 62 */ ENTRY_CopyBytes2Mod; + const BYTE ceBound = /* 62 */ eENTRY_CopyBytes2Mod; if ((p0 & 0xC0) != 0xC0) { - return CopyBytes(&ceBound, pbDst, pbSrc); + return CopyBytes(&s_rceCopyMap[ceBound], pbDst, pbSrc); } #endif - static const COPYENTRY ceInvalid = /* 62 */ ENTRY_Invalid; + const BYTE ceInvalid = /* 62 */ eENTRY_Invalid; // This could also be handled by default in CopyVexEvexCommon // if 4u changed to 4|8. if (p0 & 8u) - return Invalid(&ceInvalid, pbDst, pbSrc); + return Invalid(&s_rceCopyMap[ceInvalid], pbDst, pbSrc); BYTE const p1 = pbSrc[2]; if ((p1 & 0x04) != 0x04) - return Invalid(&ceInvalid, pbDst, pbSrc); + return Invalid(&s_rceCopyMap[ceInvalid], pbDst, pbSrc); // Copy 4 byte prefix. *(UNALIGNED ULONG*)pbDst = *(UNALIGNED ULONG*)pbSrc; @@ -862,26 +855,26 @@ mmmmm only otherwise defined for 8, 9, A. pp is like VEX but only instructions with 0 are defined */ { - const static COPYENTRY cePop = /* 8F */ ENTRY_CopyBytes2Mod; - const static COPYENTRY ceXop = /* 8F */ ENTRY_CopyBytesXop; - const static COPYENTRY ceXop1 = /* 8F */ ENTRY_CopyBytesXop1; - const static COPYENTRY ceXop4 = /* 8F */ ENTRY_CopyBytesXop4; + const BYTE cePop = /* 8F */ eENTRY_CopyBytes2Mod; + const BYTE ceXop = /* 8F */ eENTRY_CopyBytesXop; + const BYTE ceXop1 = /* 8F */ eENTRY_CopyBytesXop1; + const BYTE ceXop4 = /* 8F */ eENTRY_CopyBytesXop4; BYTE const m = (BYTE)(pbSrc[1] & 0x1F); ASSERT(m <= 10); switch (m) { default: - return CopyBytes(&cePop, pbDst, pbSrc); + return CopyBytes(&s_rceCopyMap[cePop], pbDst, pbSrc); case 8: // modrm with 8bit immediate - return CopyBytes(&ceXop1, pbDst, pbSrc); + return CopyBytes(&s_rceCopyMap[ceXop1], pbDst, pbSrc); case 9: // modrm with no immediate - return CopyBytes(&ceXop, pbDst, pbSrc); + return CopyBytes(&s_rceCopyMap[ceXop], pbDst, pbSrc); case 10: // modrm with 32bit immediate - return CopyBytes(&ceXop4, pbDst, pbSrc); + return CopyBytes(&s_rceCopyMap[ceXop4], pbDst, pbSrc); } } @@ -926,542 +919,602 @@ const BYTE CDetourDis::s_rbModRm[256] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 // Fx }; -const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable[] = +// These macros define common uses of nFixedSize, nFixedSize16, nModOffset, nRelOffset, nFlagBits, pfCopy. +#define ENTRY_DataIgnored 0, 0, 0, 0, 0, + +const CDetourDis::COPYENTRY CDetourDis::s_rceCopyMap[] = { + /* eENTRY_CopyBytes1 */ { 1, 1, 0, 0, 0, &CDetourDis::CopyBytes }, +#if defined(_M_X64) + /* eENTRY_CopyBytes1Address */ { 9, 5, 0, 0, ADDRESS, &CDetourDis::CopyBytes }, +#else + /* eENTRY_CopyBytes1Address */ { 5, 3, 0, 0, ADDRESS, &CDetourDis::CopyBytes }, +#endif + /* eENTRY_CopyBytes1Dynamic */ { 1, 1, 0, 0, DYNAMIC, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes2 */ { 2, 2, 0, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes2Jump */ { ENTRY_DataIgnored & CDetourDis::CopyBytesJump }, + /* eENTRY_CopyBytes2CantJump */ { 2, 2, 0, 1, NOENLARGE, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes2Dynamic */ { 2, 2, 0, 0, DYNAMIC, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes3 */ { 3, 3, 0, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes3Dynamic */ { 3, 3, 0, 0, DYNAMIC, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes3Or5 */ { 5, 3, 0, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes3Or5Dynamic */ { 5, 3, 0, 0, DYNAMIC, &CDetourDis::CopyBytes }, // x86 only +#if defined(_M_X64) + /* eENTRY_CopyBytes3Or5Rax */ { 5, 3, 0, 0, RAX, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes3Or5Target */ { 5, 5, 0, 1, 0, &CDetourDis::CopyBytes }, +#else + /* eENTRY_CopyBytes3Or5Rax */ { 5, 3, 0, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes3Or5Target */ { 5, 3, 0, 1, 0, &CDetourDis::CopyBytes }, +#endif + /* eENTRY_CopyBytes4 */ { 4, 4, 0, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes5 */ { 5, 5, 0, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes5Or7Dynamic */ { 7, 5, 0, 0, DYNAMIC, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes7 */ { 7, 7, 0, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes2Mod */ { 2, 2, 1, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes2ModDynamic */ { 2, 2, 1, 0, DYNAMIC, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes2Mod1 */ { 3, 3, 1, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes2ModOperand */ { 6, 4, 1, 0, 0, &CDetourDis::CopyBytes }, + /* eENTRY_CopyBytes3Mod */ { 3, 3, 2, 0, 0, &CDetourDis::CopyBytes }, // SSE3 0F 38 opcode modrm + /* eENTRY_CopyBytes3Mod1 */ { 4, 4, 2, 0, 0, &CDetourDis::CopyBytes }, // SSE3 0F 3A opcode modrm .. imm8 + /* eENTRY_CopyBytesPrefix */ { ENTRY_DataIgnored & CDetourDis::CopyBytesPrefix }, + /* eENTRY_CopyBytesSegment */ { ENTRY_DataIgnored & CDetourDis::CopyBytesSegment }, + /* eENTRY_CopyBytesRax */ { ENTRY_DataIgnored & CDetourDis::CopyBytesRax }, + /* eENTRY_CopyF2 */ { ENTRY_DataIgnored & CDetourDis::CopyF2 }, + /* eENTRY_CopyF3 */ { ENTRY_DataIgnored & CDetourDis::CopyF3 }, // 32bit x86 only + /* eENTRY_Copy0F */ { ENTRY_DataIgnored & CDetourDis::Copy0F }, + /* eENTRY_Copy0F78 */ { ENTRY_DataIgnored & CDetourDis::Copy0F78 }, + /* eENTRY_Copy0F00 */ { ENTRY_DataIgnored & CDetourDis::Copy0F00 }, // 32bit x86 only + /* eENTRY_Copy0FB8 */ { ENTRY_DataIgnored & CDetourDis::Copy0FB8 }, // 32bit x86 only + /* eENTRY_Copy66 */ { ENTRY_DataIgnored & CDetourDis::Copy66 }, + /* eENTRY_Copy67 */ { ENTRY_DataIgnored & CDetourDis::Copy67 }, + /* eENTRY_CopyF6 */ { ENTRY_DataIgnored & CDetourDis::CopyF6 }, + /* eENTRY_CopyF7 */ { ENTRY_DataIgnored & CDetourDis::CopyF7 }, + /* eENTRY_CopyFF */ { ENTRY_DataIgnored & CDetourDis::CopyFF }, + /* eENTRY_CopyVex2 */ { ENTRY_DataIgnored & CDetourDis::CopyVex2 }, + /* eENTRY_CopyVex3 */ { ENTRY_DataIgnored & CDetourDis::CopyVex3 }, + /* eENTRY_CopyEvex */ { ENTRY_DataIgnored & CDetourDis::CopyEvex }, // 62, 3 byte payload, then normal with implied prefixes like vex + /* eENTRY_CopyXop */ { ENTRY_DataIgnored & CDetourDis::CopyXop }, // 0x8F ... POP /0 or AMD XOP + /* eENTRY_CopyBytesXop */ { 5, 5, 4, 0, 0, &CDetourDis::CopyBytes }, // 0x8F xop1 xop2 opcode modrm + /* eENTRY_CopyBytesXop1 */ { 6, 6, 4, 0, 0, &CDetourDis::CopyBytes }, // 0x8F xop1 xop2 opcode modrm ... imm8 + /* eENTRY_CopyBytesXop4 */ { 9, 9, 4, 0, 0, &CDetourDis::CopyBytes }, // 0x8F xop1 xop2 opcode modrm ... imm32 + /* eENTRY_Invalid */ { ENTRY_DataIgnored & CDetourDis::Invalid } +}; + +const BYTE CDetourDis::s_rceCopyTable[] = { - /* 00 */ ENTRY_CopyBytes2Mod, // ADD /r - /* 01 */ ENTRY_CopyBytes2Mod, // ADD /r - /* 02 */ ENTRY_CopyBytes2Mod, // ADD /r - /* 03 */ ENTRY_CopyBytes2Mod, // ADD /r - /* 04 */ ENTRY_CopyBytes2, // ADD ib - /* 05 */ ENTRY_CopyBytes3Or5, // ADD iw + /* 00 */ eENTRY_CopyBytes2Mod, // ADD /r + /* 01 */ eENTRY_CopyBytes2Mod, // ADD /r + /* 02 */ eENTRY_CopyBytes2Mod, // ADD /r + /* 03 */ eENTRY_CopyBytes2Mod, // ADD /r + /* 04 */ eENTRY_CopyBytes2, // ADD ib + /* 05 */ eENTRY_CopyBytes3Or5, // ADD iw #if defined(_M_X64) - /* 06 */ ENTRY_Invalid, // Invalid - /* 07 */ ENTRY_Invalid, // Invalid + /* 06 */ eENTRY_Invalid, // Invalid + /* 07 */ eENTRY_Invalid, // Invalid #else - /* 06 */ ENTRY_CopyBytes1, // PUSH - /* 07 */ ENTRY_CopyBytes1, // POP + /* 06 */ eENTRY_CopyBytes1, // PUSH + /* 07 */ eENTRY_CopyBytes1, // POP #endif - /* 08 */ ENTRY_CopyBytes2Mod, // OR /r - /* 09 */ ENTRY_CopyBytes2Mod, // OR /r - /* 0A */ ENTRY_CopyBytes2Mod, // OR /r - /* 0B */ ENTRY_CopyBytes2Mod, // OR /r - /* 0C */ ENTRY_CopyBytes2, // OR ib - /* 0D */ ENTRY_CopyBytes3Or5, // OR iw + /* 08 */ eENTRY_CopyBytes2Mod, // OR /r + /* 09 */ eENTRY_CopyBytes2Mod, // OR /r + /* 0A */ eENTRY_CopyBytes2Mod, // OR /r + /* 0B */ eENTRY_CopyBytes2Mod, // OR /r + /* 0C */ eENTRY_CopyBytes2, // OR ib + /* 0D */ eENTRY_CopyBytes3Or5, // OR iw #if defined(_M_X64) - /* 0E */ ENTRY_Invalid, // Invalid + /* 0E */ eENTRY_Invalid, // Invalid #else - /* 0E */ ENTRY_CopyBytes1, // PUSH + /* 0E */ eENTRY_CopyBytes1, // PUSH #endif - /* 0F */ ENTRY_Copy0F, // Extension Ops - /* 10 */ ENTRY_CopyBytes2Mod, // ADC /r - /* 11 */ ENTRY_CopyBytes2Mod, // ADC /r - /* 12 */ ENTRY_CopyBytes2Mod, // ADC /r - /* 13 */ ENTRY_CopyBytes2Mod, // ADC /r - /* 14 */ ENTRY_CopyBytes2, // ADC ib - /* 15 */ ENTRY_CopyBytes3Or5, // ADC id + /* 0F */ eENTRY_Copy0F, // Extension Ops + /* 10 */ eENTRY_CopyBytes2Mod, // ADC /r + /* 11 */ eENTRY_CopyBytes2Mod, // ADC /r + /* 12 */ eENTRY_CopyBytes2Mod, // ADC /r + /* 13 */ eENTRY_CopyBytes2Mod, // ADC /r + /* 14 */ eENTRY_CopyBytes2, // ADC ib + /* 15 */ eENTRY_CopyBytes3Or5, // ADC id #if defined(_M_X64) - /* 16 */ ENTRY_Invalid, // Invalid - /* 17 */ ENTRY_Invalid, // Invalid + /* 16 */ eENTRY_Invalid, // Invalid + /* 17 */ eENTRY_Invalid, // Invalid #else - /* 16 */ ENTRY_CopyBytes1, // PUSH - /* 17 */ ENTRY_CopyBytes1, // POP + /* 16 */ eENTRY_CopyBytes1, // PUSH + /* 17 */ eENTRY_CopyBytes1, // POP #endif - /* 18 */ ENTRY_CopyBytes2Mod, // SBB /r - /* 19 */ ENTRY_CopyBytes2Mod, // SBB /r - /* 1A */ ENTRY_CopyBytes2Mod, // SBB /r - /* 1B */ ENTRY_CopyBytes2Mod, // SBB /r - /* 1C */ ENTRY_CopyBytes2, // SBB ib - /* 1D */ ENTRY_CopyBytes3Or5, // SBB id + /* 18 */ eENTRY_CopyBytes2Mod, // SBB /r + /* 19 */ eENTRY_CopyBytes2Mod, // SBB /r + /* 1A */ eENTRY_CopyBytes2Mod, // SBB /r + /* 1B */ eENTRY_CopyBytes2Mod, // SBB /r + /* 1C */ eENTRY_CopyBytes2, // SBB ib + /* 1D */ eENTRY_CopyBytes3Or5, // SBB id #if defined(_M_X64) - /* 1E */ ENTRY_Invalid, // Invalid - /* 1F */ ENTRY_Invalid, // Invalid + /* 1E */ eENTRY_Invalid, // Invalid + /* 1F */ eENTRY_Invalid, // Invalid #else - /* 1E */ ENTRY_CopyBytes1, // PUSH - /* 1F */ ENTRY_CopyBytes1, // POP + /* 1E */ eENTRY_CopyBytes1, // PUSH + /* 1F */ eENTRY_CopyBytes1, // POP #endif - /* 20 */ ENTRY_CopyBytes2Mod, // AND /r - /* 21 */ ENTRY_CopyBytes2Mod, // AND /r - /* 22 */ ENTRY_CopyBytes2Mod, // AND /r - /* 23 */ ENTRY_CopyBytes2Mod, // AND /r - /* 24 */ ENTRY_CopyBytes2, // AND ib - /* 25 */ ENTRY_CopyBytes3Or5, // AND id - /* 26 */ ENTRY_CopyBytesSegment, // ES prefix + /* 20 */ eENTRY_CopyBytes2Mod, // AND /r + /* 21 */ eENTRY_CopyBytes2Mod, // AND /r + /* 22 */ eENTRY_CopyBytes2Mod, // AND /r + /* 23 */ eENTRY_CopyBytes2Mod, // AND /r + /* 24 */ eENTRY_CopyBytes2, // AND ib + /* 25 */ eENTRY_CopyBytes3Or5, // AND id + /* 26 */ eENTRY_CopyBytesSegment, // ES prefix #if defined(_M_X64) - /* 27 */ ENTRY_Invalid, // Invalid + /* 27 */ eENTRY_Invalid, // Invalid #else - /* 27 */ ENTRY_CopyBytes1, // DAA + /* 27 */ eENTRY_CopyBytes1, // DAA #endif - /* 28 */ ENTRY_CopyBytes2Mod, // SUB /r - /* 29 */ ENTRY_CopyBytes2Mod, // SUB /r - /* 2A */ ENTRY_CopyBytes2Mod, // SUB /r - /* 2B */ ENTRY_CopyBytes2Mod, // SUB /r - /* 2C */ ENTRY_CopyBytes2, // SUB ib - /* 2D */ ENTRY_CopyBytes3Or5, // SUB id - /* 2E */ ENTRY_CopyBytesSegment, // CS prefix + /* 28 */ eENTRY_CopyBytes2Mod, // SUB /r + /* 29 */ eENTRY_CopyBytes2Mod, // SUB /r + /* 2A */ eENTRY_CopyBytes2Mod, // SUB /r + /* 2B */ eENTRY_CopyBytes2Mod, // SUB /r + /* 2C */ eENTRY_CopyBytes2, // SUB ib + /* 2D */ eENTRY_CopyBytes3Or5, // SUB id + /* 2E */ eENTRY_CopyBytesSegment, // CS prefix #if defined(_M_X64) - /* 2F */ ENTRY_Invalid, // Invalid + /* 2F */ eENTRY_Invalid, // Invalid #else - /* 2F */ ENTRY_CopyBytes1, // DAS + /* 2F */ eENTRY_CopyBytes1, // DAS #endif - /* 30 */ ENTRY_CopyBytes2Mod, // XOR /r - /* 31 */ ENTRY_CopyBytes2Mod, // XOR /r - /* 32 */ ENTRY_CopyBytes2Mod, // XOR /r - /* 33 */ ENTRY_CopyBytes2Mod, // XOR /r - /* 34 */ ENTRY_CopyBytes2, // XOR ib - /* 35 */ ENTRY_CopyBytes3Or5, // XOR id - /* 36 */ ENTRY_CopyBytesSegment, // SS prefix + /* 30 */ eENTRY_CopyBytes2Mod, // XOR /r + /* 31 */ eENTRY_CopyBytes2Mod, // XOR /r + /* 32 */ eENTRY_CopyBytes2Mod, // XOR /r + /* 33 */ eENTRY_CopyBytes2Mod, // XOR /r + /* 34 */ eENTRY_CopyBytes2, // XOR ib + /* 35 */ eENTRY_CopyBytes3Or5, // XOR id + /* 36 */ eENTRY_CopyBytesSegment, // SS prefix #if defined(_M_X64) - /* 37 */ ENTRY_Invalid, // Invalid + /* 37 */ eENTRY_Invalid, // Invalid #else - /* 37 */ ENTRY_CopyBytes1, // AAA + /* 37 */ eENTRY_CopyBytes1, // AAA #endif - /* 38 */ ENTRY_CopyBytes2Mod, // CMP /r - /* 39 */ ENTRY_CopyBytes2Mod, // CMP /r - /* 3A */ ENTRY_CopyBytes2Mod, // CMP /r - /* 3B */ ENTRY_CopyBytes2Mod, // CMP /r - /* 3C */ ENTRY_CopyBytes2, // CMP ib - /* 3D */ ENTRY_CopyBytes3Or5, // CMP id - /* 3E */ ENTRY_CopyBytesSegment, // DS prefix + /* 38 */ eENTRY_CopyBytes2Mod, // CMP /r + /* 39 */ eENTRY_CopyBytes2Mod, // CMP /r + /* 3A */ eENTRY_CopyBytes2Mod, // CMP /r + /* 3B */ eENTRY_CopyBytes2Mod, // CMP /r + /* 3C */ eENTRY_CopyBytes2, // CMP ib + /* 3D */ eENTRY_CopyBytes3Or5, // CMP id + /* 3E */ eENTRY_CopyBytesSegment, // DS prefix #if defined(_M_X64) - /* 3F */ ENTRY_Invalid, // Invalid + /* 3F */ eENTRY_Invalid, // Invalid #else - /* 3F */ ENTRY_CopyBytes1, // AAS + /* 3F */ eENTRY_CopyBytes1, // AAS #endif #if defined(_M_X64) // For Rax Prefix - /* 40 */ ENTRY_CopyBytesRax, // Rax - /* 41 */ ENTRY_CopyBytesRax, // Rax - /* 42 */ ENTRY_CopyBytesRax, // Rax - /* 43 */ ENTRY_CopyBytesRax, // Rax - /* 44 */ ENTRY_CopyBytesRax, // Rax - /* 45 */ ENTRY_CopyBytesRax, // Rax - /* 46 */ ENTRY_CopyBytesRax, // Rax - /* 47 */ ENTRY_CopyBytesRax, // Rax - /* 48 */ ENTRY_CopyBytesRax, // Rax - /* 49 */ ENTRY_CopyBytesRax, // Rax - /* 4A */ ENTRY_CopyBytesRax, // Rax - /* 4B */ ENTRY_CopyBytesRax, // Rax - /* 4C */ ENTRY_CopyBytesRax, // Rax - /* 4D */ ENTRY_CopyBytesRax, // Rax - /* 4E */ ENTRY_CopyBytesRax, // Rax - /* 4F */ ENTRY_CopyBytesRax, // Rax + /* 40 */ eENTRY_CopyBytesRax, // Rax + /* 41 */ eENTRY_CopyBytesRax, // Rax + /* 42 */ eENTRY_CopyBytesRax, // Rax + /* 43 */ eENTRY_CopyBytesRax, // Rax + /* 44 */ eENTRY_CopyBytesRax, // Rax + /* 45 */ eENTRY_CopyBytesRax, // Rax + /* 46 */ eENTRY_CopyBytesRax, // Rax + /* 47 */ eENTRY_CopyBytesRax, // Rax + /* 48 */ eENTRY_CopyBytesRax, // Rax + /* 49 */ eENTRY_CopyBytesRax, // Rax + /* 4A */ eENTRY_CopyBytesRax, // Rax + /* 4B */ eENTRY_CopyBytesRax, // Rax + /* 4C */ eENTRY_CopyBytesRax, // Rax + /* 4D */ eENTRY_CopyBytesRax, // Rax + /* 4E */ eENTRY_CopyBytesRax, // Rax + /* 4F */ eENTRY_CopyBytesRax, // Rax #else - /* 40 */ ENTRY_CopyBytes1, // INC - /* 41 */ ENTRY_CopyBytes1, // INC - /* 42 */ ENTRY_CopyBytes1, // INC - /* 43 */ ENTRY_CopyBytes1, // INC - /* 44 */ ENTRY_CopyBytes1, // INC - /* 45 */ ENTRY_CopyBytes1, // INC - /* 46 */ ENTRY_CopyBytes1, // INC - /* 47 */ ENTRY_CopyBytes1, // INC - /* 48 */ ENTRY_CopyBytes1, // DEC - /* 49 */ ENTRY_CopyBytes1, // DEC - /* 4A */ ENTRY_CopyBytes1, // DEC - /* 4B */ ENTRY_CopyBytes1, // DEC - /* 4C */ ENTRY_CopyBytes1, // DEC - /* 4D */ ENTRY_CopyBytes1, // DEC - /* 4E */ ENTRY_CopyBytes1, // DEC - /* 4F */ ENTRY_CopyBytes1, // DEC + /* 40 */ eENTRY_CopyBytes1, // INC + /* 41 */ eENTRY_CopyBytes1, // INC + /* 42 */ eENTRY_CopyBytes1, // INC + /* 43 */ eENTRY_CopyBytes1, // INC + /* 44 */ eENTRY_CopyBytes1, // INC + /* 45 */ eENTRY_CopyBytes1, // INC + /* 46 */ eENTRY_CopyBytes1, // INC + /* 47 */ eENTRY_CopyBytes1, // INC + /* 48 */ eENTRY_CopyBytes1, // DEC + /* 49 */ eENTRY_CopyBytes1, // DEC + /* 4A */ eENTRY_CopyBytes1, // DEC + /* 4B */ eENTRY_CopyBytes1, // DEC + /* 4C */ eENTRY_CopyBytes1, // DEC + /* 4D */ eENTRY_CopyBytes1, // DEC + /* 4E */ eENTRY_CopyBytes1, // DEC + /* 4F */ eENTRY_CopyBytes1, // DEC #endif - /* 50 */ ENTRY_CopyBytes1, // PUSH - /* 51 */ ENTRY_CopyBytes1, // PUSH - /* 52 */ ENTRY_CopyBytes1, // PUSH - /* 53 */ ENTRY_CopyBytes1, // PUSH - /* 54 */ ENTRY_CopyBytes1, // PUSH - /* 55 */ ENTRY_CopyBytes1, // PUSH - /* 56 */ ENTRY_CopyBytes1, // PUSH - /* 57 */ ENTRY_CopyBytes1, // PUSH - /* 58 */ ENTRY_CopyBytes1, // POP - /* 59 */ ENTRY_CopyBytes1, // POP - /* 5A */ ENTRY_CopyBytes1, // POP - /* 5B */ ENTRY_CopyBytes1, // POP - /* 5C */ ENTRY_CopyBytes1, // POP - /* 5D */ ENTRY_CopyBytes1, // POP - /* 5E */ ENTRY_CopyBytes1, // POP - /* 5F */ ENTRY_CopyBytes1, // POP + /* 50 */ eENTRY_CopyBytes1, // PUSH + /* 51 */ eENTRY_CopyBytes1, // PUSH + /* 52 */ eENTRY_CopyBytes1, // PUSH + /* 53 */ eENTRY_CopyBytes1, // PUSH + /* 54 */ eENTRY_CopyBytes1, // PUSH + /* 55 */ eENTRY_CopyBytes1, // PUSH + /* 56 */ eENTRY_CopyBytes1, // PUSH + /* 57 */ eENTRY_CopyBytes1, // PUSH + /* 58 */ eENTRY_CopyBytes1, // POP + /* 59 */ eENTRY_CopyBytes1, // POP + /* 5A */ eENTRY_CopyBytes1, // POP + /* 5B */ eENTRY_CopyBytes1, // POP + /* 5C */ eENTRY_CopyBytes1, // POP + /* 5D */ eENTRY_CopyBytes1, // POP + /* 5E */ eENTRY_CopyBytes1, // POP + /* 5F */ eENTRY_CopyBytes1, // POP #if defined(_M_X64) - /* 60 */ ENTRY_Invalid, // Invalid - /* 61 */ ENTRY_Invalid, // Invalid - /* 62 */ ENTRY_CopyEvex, // EVEX / AVX512 + /* 60 */ eENTRY_Invalid, // Invalid + /* 61 */ eENTRY_Invalid, // Invalid + /* 62 */ eENTRY_CopyEvex, // EVEX / AVX512 #else - /* 60 */ ENTRY_CopyBytes1, // PUSHAD - /* 61 */ ENTRY_CopyBytes1, // POPAD - /* 62 */ ENTRY_CopyEvex, // BOUND /r and EVEX / AVX512 + /* 60 */ eENTRY_CopyBytes1, // PUSHAD + /* 61 */ eENTRY_CopyBytes1, // POPAD + /* 62 */ eENTRY_CopyEvex, // BOUND /r and EVEX / AVX512 #endif - /* 63 */ ENTRY_CopyBytes2Mod, // 32bit ARPL /r, 64bit MOVSXD - /* 64 */ ENTRY_CopyBytesSegment, // FS prefix - /* 65 */ ENTRY_CopyBytesSegment, // GS prefix - /* 66 */ ENTRY_Copy66, // Operand Prefix - /* 67 */ ENTRY_Copy67, // Address Prefix - /* 68 */ ENTRY_CopyBytes3Or5, // PUSH - /* 69 */ ENTRY_CopyBytes2ModOperand, // IMUL /r iz - /* 6A */ ENTRY_CopyBytes2, // PUSH - /* 6B */ ENTRY_CopyBytes2Mod1, // IMUL /r ib - /* 6C */ ENTRY_CopyBytes1, // INS - /* 6D */ ENTRY_CopyBytes1, // INS - /* 6E */ ENTRY_CopyBytes1, // OUTS/OUTSB - /* 6F */ ENTRY_CopyBytes1, // OUTS/OUTSW - /* 70 */ ENTRY_CopyBytes2Jump, // JO // 0f80 - /* 71 */ ENTRY_CopyBytes2Jump, // JNO // 0f81 - /* 72 */ ENTRY_CopyBytes2Jump, // JB/JC/JNAE // 0f82 - /* 73 */ ENTRY_CopyBytes2Jump, // JAE/JNB/JNC // 0f83 - /* 74 */ ENTRY_CopyBytes2Jump, // JE/JZ // 0f84 - /* 75 */ ENTRY_CopyBytes2Jump, // JNE/JNZ // 0f85 - /* 76 */ ENTRY_CopyBytes2Jump, // JBE/JNA // 0f86 - /* 77 */ ENTRY_CopyBytes2Jump, // JA/JNBE // 0f87 - /* 78 */ ENTRY_CopyBytes2Jump, // JS // 0f88 - /* 79 */ ENTRY_CopyBytes2Jump, // JNS // 0f89 - /* 7A */ ENTRY_CopyBytes2Jump, // JP/JPE // 0f8a - /* 7B */ ENTRY_CopyBytes2Jump, // JNP/JPO // 0f8b - /* 7C */ ENTRY_CopyBytes2Jump, // JL/JNGE // 0f8c - /* 7D */ ENTRY_CopyBytes2Jump, // JGE/JNL // 0f8d - /* 7E */ ENTRY_CopyBytes2Jump, // JLE/JNG // 0f8e - /* 7F */ ENTRY_CopyBytes2Jump, // JG/JNLE // 0f8f - /* 80 */ ENTRY_CopyBytes2Mod1, // ADD/0 OR/1 ADC/2 SBB/3 AND/4 SUB/5 XOR/6 CMP/7 byte reg, immediate byte - /* 81 */ ENTRY_CopyBytes2ModOperand, // ADD/0 OR/1 ADC/2 SBB/3 AND/4 SUB/5 XOR/6 CMP/7 byte reg, immediate word or dword + /* 63 */ eENTRY_CopyBytes2Mod, // 32bit ARPL /r, 64bit MOVSXD + /* 64 */ eENTRY_CopyBytesSegment, // FS prefix + /* 65 */ eENTRY_CopyBytesSegment, // GS prefix + /* 66 */ eENTRY_Copy66, // Operand Prefix + /* 67 */ eENTRY_Copy67, // Address Prefix + /* 68 */ eENTRY_CopyBytes3Or5, // PUSH + /* 69 */ eENTRY_CopyBytes2ModOperand, // IMUL /r iz + /* 6A */ eENTRY_CopyBytes2, // PUSH + /* 6B */ eENTRY_CopyBytes2Mod1, // IMUL /r ib + /* 6C */ eENTRY_CopyBytes1, // INS + /* 6D */ eENTRY_CopyBytes1, // INS + /* 6E */ eENTRY_CopyBytes1, // OUTS/OUTSB + /* 6F */ eENTRY_CopyBytes1, // OUTS/OUTSW + /* 70 */ eENTRY_CopyBytes2Jump, // JO // 0f80 + /* 71 */ eENTRY_CopyBytes2Jump, // JNO // 0f81 + /* 72 */ eENTRY_CopyBytes2Jump, // JB/JC/JNAE // 0f82 + /* 73 */ eENTRY_CopyBytes2Jump, // JAE/JNB/JNC // 0f83 + /* 74 */ eENTRY_CopyBytes2Jump, // JE/JZ // 0f84 + /* 75 */ eENTRY_CopyBytes2Jump, // JNE/JNZ // 0f85 + /* 76 */ eENTRY_CopyBytes2Jump, // JBE/JNA // 0f86 + /* 77 */ eENTRY_CopyBytes2Jump, // JA/JNBE // 0f87 + /* 78 */ eENTRY_CopyBytes2Jump, // JS // 0f88 + /* 79 */ eENTRY_CopyBytes2Jump, // JNS // 0f89 + /* 7A */ eENTRY_CopyBytes2Jump, // JP/JPE // 0f8a + /* 7B */ eENTRY_CopyBytes2Jump, // JNP/JPO // 0f8b + /* 7C */ eENTRY_CopyBytes2Jump, // JL/JNGE // 0f8c + /* 7D */ eENTRY_CopyBytes2Jump, // JGE/JNL // 0f8d + /* 7E */ eENTRY_CopyBytes2Jump, // JLE/JNG // 0f8e + /* 7F */ eENTRY_CopyBytes2Jump, // JG/JNLE // 0f8f + /* 80 */ eENTRY_CopyBytes2Mod1, // ADD/0 OR/1 ADC/2 SBB/3 AND/4 SUB/5 XOR/6 CMP/7 byte reg, immediate byte + /* 81 */ eENTRY_CopyBytes2ModOperand, // ADD/0 OR/1 ADC/2 SBB/3 AND/4 SUB/5 XOR/6 CMP/7 byte reg, immediate word or dword #if defined(_M_X64) - /* 82 */ ENTRY_Invalid, // Invalid + /* 82 */ eENTRY_Invalid, // Invalid #else - /* 82 */ ENTRY_CopyBytes2Mod1, // MOV al,x + /* 82 */ eENTRY_CopyBytes2Mod1, // MOV al,x #endif - /* 83 */ ENTRY_CopyBytes2Mod1, // ADD/0 OR/1 ADC/2 SBB/3 AND/4 SUB/5 XOR/6 CMP/7 reg, immediate byte - /* 84 */ ENTRY_CopyBytes2Mod, // TEST /r - /* 85 */ ENTRY_CopyBytes2Mod, // TEST /r - /* 86 */ ENTRY_CopyBytes2Mod, // XCHG /r @todo - /* 87 */ ENTRY_CopyBytes2Mod, // XCHG /r @todo - /* 88 */ ENTRY_CopyBytes2Mod, // MOV /r - /* 89 */ ENTRY_CopyBytes2Mod, // MOV /r - /* 8A */ ENTRY_CopyBytes2Mod, // MOV /r - /* 8B */ ENTRY_CopyBytes2Mod, // MOV /r - /* 8C */ ENTRY_CopyBytes2Mod, // MOV /r - /* 8D */ ENTRY_CopyBytes2Mod, // LEA /r - /* 8E */ ENTRY_CopyBytes2Mod, // MOV /r - /* 8F */ ENTRY_CopyXop, // POP /0 or AMD XOP - /* 90 */ ENTRY_CopyBytes1, // NOP - /* 91 */ ENTRY_CopyBytes1, // XCHG - /* 92 */ ENTRY_CopyBytes1, // XCHG - /* 93 */ ENTRY_CopyBytes1, // XCHG - /* 94 */ ENTRY_CopyBytes1, // XCHG - /* 95 */ ENTRY_CopyBytes1, // XCHG - /* 96 */ ENTRY_CopyBytes1, // XCHG - /* 97 */ ENTRY_CopyBytes1, // XCHG - /* 98 */ ENTRY_CopyBytes1, // CWDE - /* 99 */ ENTRY_CopyBytes1, // CDQ + /* 83 */ eENTRY_CopyBytes2Mod1, // ADD/0 OR/1 ADC/2 SBB/3 AND/4 SUB/5 XOR/6 CMP/7 reg, immediate byte + /* 84 */ eENTRY_CopyBytes2Mod, // TEST /r + /* 85 */ eENTRY_CopyBytes2Mod, // TEST /r + /* 86 */ eENTRY_CopyBytes2Mod, // XCHG /r @todo + /* 87 */ eENTRY_CopyBytes2Mod, // XCHG /r @todo + /* 88 */ eENTRY_CopyBytes2Mod, // MOV /r + /* 89 */ eENTRY_CopyBytes2Mod, // MOV /r + /* 8A */ eENTRY_CopyBytes2Mod, // MOV /r + /* 8B */ eENTRY_CopyBytes2Mod, // MOV /r + /* 8C */ eENTRY_CopyBytes2Mod, // MOV /r + /* 8D */ eENTRY_CopyBytes2Mod, // LEA /r + /* 8E */ eENTRY_CopyBytes2Mod, // MOV /r + /* 8F */ eENTRY_CopyXop, // POP /0 or AMD XOP + /* 90 */ eENTRY_CopyBytes1, // NOP + /* 91 */ eENTRY_CopyBytes1, // XCHG + /* 92 */ eENTRY_CopyBytes1, // XCHG + /* 93 */ eENTRY_CopyBytes1, // XCHG + /* 94 */ eENTRY_CopyBytes1, // XCHG + /* 95 */ eENTRY_CopyBytes1, // XCHG + /* 96 */ eENTRY_CopyBytes1, // XCHG + /* 97 */ eENTRY_CopyBytes1, // XCHG + /* 98 */ eENTRY_CopyBytes1, // CWDE + /* 99 */ eENTRY_CopyBytes1, // CDQ #if defined(_M_X64) - /* 9A */ ENTRY_Invalid, // Invalid + /* 9A */ eENTRY_Invalid, // Invalid #else - /* 9A */ ENTRY_CopyBytes5Or7Dynamic, // CALL cp + /* 9A */ eENTRY_CopyBytes5Or7Dynamic, // CALL cp #endif - /* 9B */ ENTRY_CopyBytes1, // WAIT/FWAIT - /* 9C */ ENTRY_CopyBytes1, // PUSHFD - /* 9D */ ENTRY_CopyBytes1, // POPFD - /* 9E */ ENTRY_CopyBytes1, // SAHF - /* 9F */ ENTRY_CopyBytes1, // LAHF - /* A0 */ ENTRY_CopyBytes1Address, // MOV - /* A1 */ ENTRY_CopyBytes1Address, // MOV - /* A2 */ ENTRY_CopyBytes1Address, // MOV - /* A3 */ ENTRY_CopyBytes1Address, // MOV - /* A4 */ ENTRY_CopyBytes1, // MOVS - /* A5 */ ENTRY_CopyBytes1, // MOVS/MOVSD - /* A6 */ ENTRY_CopyBytes1, // CMPS/CMPSB - /* A7 */ ENTRY_CopyBytes1, // CMPS/CMPSW - /* A8 */ ENTRY_CopyBytes2, // TEST - /* A9 */ ENTRY_CopyBytes3Or5, // TEST - /* AA */ ENTRY_CopyBytes1, // STOS/STOSB - /* AB */ ENTRY_CopyBytes1, // STOS/STOSW - /* AC */ ENTRY_CopyBytes1, // LODS/LODSB - /* AD */ ENTRY_CopyBytes1, // LODS/LODSW - /* AE */ ENTRY_CopyBytes1, // SCAS/SCASB - /* AF */ ENTRY_CopyBytes1, // SCAS/SCASD - /* B0 */ ENTRY_CopyBytes2, // MOV B0+rb - /* B1 */ ENTRY_CopyBytes2, // MOV B0+rb - /* B2 */ ENTRY_CopyBytes2, // MOV B0+rb - /* B3 */ ENTRY_CopyBytes2, // MOV B0+rb - /* B4 */ ENTRY_CopyBytes2, // MOV B0+rb - /* B5 */ ENTRY_CopyBytes2, // MOV B0+rb - /* B6 */ ENTRY_CopyBytes2, // MOV B0+rb - /* B7 */ ENTRY_CopyBytes2, // MOV B0+rb - /* B8 */ ENTRY_CopyBytes3Or5Rax, // MOV B8+rb - /* B9 */ ENTRY_CopyBytes3Or5Rax, // MOV B8+rb - /* BA */ ENTRY_CopyBytes3Or5Rax, // MOV B8+rb - /* BB */ ENTRY_CopyBytes3Or5Rax, // MOV B8+rb - /* BC */ ENTRY_CopyBytes3Or5Rax, // MOV B8+rb - /* BD */ ENTRY_CopyBytes3Or5Rax, // MOV B8+rb - /* BE */ ENTRY_CopyBytes3Or5Rax, // MOV B8+rb - /* BF */ ENTRY_CopyBytes3Or5Rax, // MOV B8+rb - /* C0 */ ENTRY_CopyBytes2Mod1, // RCL/2 ib, etc. - /* C1 */ ENTRY_CopyBytes2Mod1, // RCL/2 ib, etc. - /* C2 */ ENTRY_CopyBytes3, // RET - /* C3 */ ENTRY_CopyBytes1, // RET - /* C4 */ ENTRY_CopyVex3, // LES, VEX 3-byte opcodes. - /* C5 */ ENTRY_CopyVex2, // LDS, VEX 2-byte opcodes. - /* C6 */ ENTRY_CopyBytes2Mod1, // MOV - /* C7 */ ENTRY_CopyBytes2ModOperand, // MOV/0 XBEGIN/7 - /* C8 */ ENTRY_CopyBytes4, // ENTER - /* C9 */ ENTRY_CopyBytes1, // LEAVE - /* CA */ ENTRY_CopyBytes3Dynamic, // RET - /* CB */ ENTRY_CopyBytes1Dynamic, // RET - /* CC */ ENTRY_CopyBytes1Dynamic, // INT 3 - /* CD */ ENTRY_CopyBytes2Dynamic, // INT ib + /* 9B */ eENTRY_CopyBytes1, // WAIT/FWAIT + /* 9C */ eENTRY_CopyBytes1, // PUSHFD + /* 9D */ eENTRY_CopyBytes1, // POPFD + /* 9E */ eENTRY_CopyBytes1, // SAHF + /* 9F */ eENTRY_CopyBytes1, // LAHF + /* A0 */ eENTRY_CopyBytes1Address, // MOV + /* A1 */ eENTRY_CopyBytes1Address, // MOV + /* A2 */ eENTRY_CopyBytes1Address, // MOV + /* A3 */ eENTRY_CopyBytes1Address, // MOV + /* A4 */ eENTRY_CopyBytes1, // MOVS + /* A5 */ eENTRY_CopyBytes1, // MOVS/MOVSD + /* A6 */ eENTRY_CopyBytes1, // CMPS/CMPSB + /* A7 */ eENTRY_CopyBytes1, // CMPS/CMPSW + /* A8 */ eENTRY_CopyBytes2, // TEST + /* A9 */ eENTRY_CopyBytes3Or5, // TEST + /* AA */ eENTRY_CopyBytes1, // STOS/STOSB + /* AB */ eENTRY_CopyBytes1, // STOS/STOSW + /* AC */ eENTRY_CopyBytes1, // LODS/LODSB + /* AD */ eENTRY_CopyBytes1, // LODS/LODSW + /* AE */ eENTRY_CopyBytes1, // SCAS/SCASB + /* AF */ eENTRY_CopyBytes1, // SCAS/SCASD + /* B0 */ eENTRY_CopyBytes2, // MOV B0+rb + /* B1 */ eENTRY_CopyBytes2, // MOV B0+rb + /* B2 */ eENTRY_CopyBytes2, // MOV B0+rb + /* B3 */ eENTRY_CopyBytes2, // MOV B0+rb + /* B4 */ eENTRY_CopyBytes2, // MOV B0+rb + /* B5 */ eENTRY_CopyBytes2, // MOV B0+rb + /* B6 */ eENTRY_CopyBytes2, // MOV B0+rb + /* B7 */ eENTRY_CopyBytes2, // MOV B0+rb + /* B8 */ eENTRY_CopyBytes3Or5Rax, // MOV B8+rb + /* B9 */ eENTRY_CopyBytes3Or5Rax, // MOV B8+rb + /* BA */ eENTRY_CopyBytes3Or5Rax, // MOV B8+rb + /* BB */ eENTRY_CopyBytes3Or5Rax, // MOV B8+rb + /* BC */ eENTRY_CopyBytes3Or5Rax, // MOV B8+rb + /* BD */ eENTRY_CopyBytes3Or5Rax, // MOV B8+rb + /* BE */ eENTRY_CopyBytes3Or5Rax, // MOV B8+rb + /* BF */ eENTRY_CopyBytes3Or5Rax, // MOV B8+rb + /* C0 */ eENTRY_CopyBytes2Mod1, // RCL/2 ib, etc. + /* C1 */ eENTRY_CopyBytes2Mod1, // RCL/2 ib, etc. + /* C2 */ eENTRY_CopyBytes3, // RET + /* C3 */ eENTRY_CopyBytes1, // RET + /* C4 */ eENTRY_CopyVex3, // LES, VEX 3-byte opcodes. + /* C5 */ eENTRY_CopyVex2, // LDS, VEX 2-byte opcodes. + /* C6 */ eENTRY_CopyBytes2Mod1, // MOV + /* C7 */ eENTRY_CopyBytes2ModOperand, // MOV/0 XBEGIN/7 + /* C8 */ eENTRY_CopyBytes4, // ENTER + /* C9 */ eENTRY_CopyBytes1, // LEAVE + /* CA */ eENTRY_CopyBytes3Dynamic, // RET + /* CB */ eENTRY_CopyBytes1Dynamic, // RET + /* CC */ eENTRY_CopyBytes1Dynamic, // INT 3 + /* CD */ eENTRY_CopyBytes2Dynamic, // INT ib #if defined(_M_X64) - /* CE */ ENTRY_Invalid, // Invalid + /* CE */ eENTRY_Invalid, // Invalid #else - /* CE */ ENTRY_CopyBytes1Dynamic, // INTO + /* CE */ eENTRY_CopyBytes1Dynamic, // INTO #endif - /* CF */ ENTRY_CopyBytes1Dynamic, // IRET - /* D0 */ ENTRY_CopyBytes2Mod, // RCL/2, etc. - /* D1 */ ENTRY_CopyBytes2Mod, // RCL/2, etc. - /* D2 */ ENTRY_CopyBytes2Mod, // RCL/2, etc. - /* D3 */ ENTRY_CopyBytes2Mod, // RCL/2, etc. + /* CF */ eENTRY_CopyBytes1Dynamic, // IRET + /* D0 */ eENTRY_CopyBytes2Mod, // RCL/2, etc. + /* D1 */ eENTRY_CopyBytes2Mod, // RCL/2, etc. + /* D2 */ eENTRY_CopyBytes2Mod, // RCL/2, etc. + /* D3 */ eENTRY_CopyBytes2Mod, // RCL/2, etc. #if defined(_M_X64) - /* D4 */ ENTRY_Invalid, // Invalid - /* D5 */ ENTRY_Invalid, // Invalid + /* D4 */ eENTRY_Invalid, // Invalid + /* D5 */ eENTRY_Invalid, // Invalid #else - /* D4 */ ENTRY_CopyBytes2, // AAM - /* D5 */ ENTRY_CopyBytes2, // AAD + /* D4 */ eENTRY_CopyBytes2, // AAM + /* D5 */ eENTRY_CopyBytes2, // AAD #endif - /* D6 */ ENTRY_Invalid, // Invalid - /* D7 */ ENTRY_CopyBytes1, // XLAT/XLATB - /* D8 */ ENTRY_CopyBytes2Mod, // FADD, etc. - /* D9 */ ENTRY_CopyBytes2Mod, // F2XM1, etc. - /* DA */ ENTRY_CopyBytes2Mod, // FLADD, etc. - /* DB */ ENTRY_CopyBytes2Mod, // FCLEX, etc. - /* DC */ ENTRY_CopyBytes2Mod, // FADD/0, etc. - /* DD */ ENTRY_CopyBytes2Mod, // FFREE, etc. - /* DE */ ENTRY_CopyBytes2Mod, // FADDP, etc. - /* DF */ ENTRY_CopyBytes2Mod, // FBLD/4, etc. - /* E0 */ ENTRY_CopyBytes2CantJump, // LOOPNE cb - /* E1 */ ENTRY_CopyBytes2CantJump, // LOOPE cb - /* E2 */ ENTRY_CopyBytes2CantJump, // LOOP cb - /* E3 */ ENTRY_CopyBytes2CantJump, // JCXZ/JECXZ - /* E4 */ ENTRY_CopyBytes2, // IN ib - /* E5 */ ENTRY_CopyBytes2, // IN id - /* E6 */ ENTRY_CopyBytes2, // OUT ib - /* E7 */ ENTRY_CopyBytes2, // OUT ib - /* E8 */ ENTRY_CopyBytes3Or5Target, // CALL cd - /* E9 */ ENTRY_CopyBytes3Or5Target, // JMP cd + /* D6 */ eENTRY_Invalid, // Invalid + /* D7 */ eENTRY_CopyBytes1, // XLAT/XLATB + /* D8 */ eENTRY_CopyBytes2Mod, // FADD, etc. + /* D9 */ eENTRY_CopyBytes2Mod, // F2XM1, etc. + /* DA */ eENTRY_CopyBytes2Mod, // FLADD, etc. + /* DB */ eENTRY_CopyBytes2Mod, // FCLEX, etc. + /* DC */ eENTRY_CopyBytes2Mod, // FADD/0, etc. + /* DD */ eENTRY_CopyBytes2Mod, // FFREE, etc. + /* DE */ eENTRY_CopyBytes2Mod, // FADDP, etc. + /* DF */ eENTRY_CopyBytes2Mod, // FBLD/4, etc. + /* E0 */ eENTRY_CopyBytes2CantJump, // LOOPNE cb + /* E1 */ eENTRY_CopyBytes2CantJump, // LOOPE cb + /* E2 */ eENTRY_CopyBytes2CantJump, // LOOP cb + /* E3 */ eENTRY_CopyBytes2CantJump, // JCXZ/JECXZ + /* E4 */ eENTRY_CopyBytes2, // IN ib + /* E5 */ eENTRY_CopyBytes2, // IN id + /* E6 */ eENTRY_CopyBytes2, // OUT ib + /* E7 */ eENTRY_CopyBytes2, // OUT ib + /* E8 */ eENTRY_CopyBytes3Or5Target, // CALL cd + /* E9 */ eENTRY_CopyBytes3Or5Target, // JMP cd #if defined(_M_X64) - /* EA */ ENTRY_Invalid, // Invalid + /* EA */ eENTRY_Invalid, // Invalid #else - /* EA */ ENTRY_CopyBytes5Or7Dynamic, // JMP cp + /* EA */ eENTRY_CopyBytes5Or7Dynamic, // JMP cp #endif - /* EB */ ENTRY_CopyBytes2Jump, // JMP cb - /* EC */ ENTRY_CopyBytes1, // IN ib - /* ED */ ENTRY_CopyBytes1, // IN id - /* EE */ ENTRY_CopyBytes1, // OUT - /* EF */ ENTRY_CopyBytes1, // OUT - /* F0 */ ENTRY_CopyBytesPrefix, // LOCK prefix - /* F1 */ ENTRY_CopyBytes1Dynamic, // INT1 / ICEBP somewhat documented by AMD, not by Intel - /* F2 */ ENTRY_CopyF2, // REPNE prefix + /* EB */ eENTRY_CopyBytes2Jump, // JMP cb + /* EC */ eENTRY_CopyBytes1, // IN ib + /* ED */ eENTRY_CopyBytes1, // IN id + /* EE */ eENTRY_CopyBytes1, // OUT + /* EF */ eENTRY_CopyBytes1, // OUT + /* F0 */ eENTRY_CopyBytesPrefix, // LOCK prefix + /* F1 */ eENTRY_CopyBytes1Dynamic, // INT1 / ICEBP somewhat documented by AMD, not by Intel + /* F2 */ eENTRY_CopyF2, // REPNE prefix // This does presently suffice for AMD64 but it requires tracing // through a bunch of code to verify and seems not worth maintaining. - // For x64: /* F3 */ ENTRY_CopyBytesPrefix - /* F3 */ ENTRY_CopyF3, // REPE prefix - - /* F4 */ ENTRY_CopyBytes1, // HLT - /* F5 */ ENTRY_CopyBytes1, // CMC - /* F6 */ ENTRY_CopyF6, // TEST/0, DIV/6 - /* F7 */ ENTRY_CopyF7, // TEST/0, DIV/6 - /* F8 */ ENTRY_CopyBytes1, // CLC - /* F9 */ ENTRY_CopyBytes1, // STC - /* FA */ ENTRY_CopyBytes1, // CLI - /* FB */ ENTRY_CopyBytes1, // STI - /* FC */ ENTRY_CopyBytes1, // CLD - /* FD */ ENTRY_CopyBytes1, // STD - /* FE */ ENTRY_CopyBytes2Mod, // DEC/1,INC/0 - /* FF */ ENTRY_CopyFF, // CALL/2 + // For x64: /* F3 */ eENTRY_CopyBytesPrefix + /* F3 */ eENTRY_CopyF3, // REPE prefix + + /* F4 */ eENTRY_CopyBytes1, // HLT + /* F5 */ eENTRY_CopyBytes1, // CMC + /* F6 */ eENTRY_CopyF6, // TEST/0, DIV/6 + /* F7 */ eENTRY_CopyF7, // TEST/0, DIV/6 + /* F8 */ eENTRY_CopyBytes1, // CLC + /* F9 */ eENTRY_CopyBytes1, // STC + /* FA */ eENTRY_CopyBytes1, // CLI + /* FB */ eENTRY_CopyBytes1, // STI + /* FC */ eENTRY_CopyBytes1, // CLD + /* FD */ eENTRY_CopyBytes1, // STD + /* FE */ eENTRY_CopyBytes2Mod, // DEC/1,INC/0 + /* FF */ eENTRY_CopyFF, // CALL/2 }; -const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable0F[] = +const BYTE CDetourDis::s_rceCopyTable0F[] = { #if defined(_M_IX86) - /* 00 */ ENTRY_Copy0F00, // sldt/0 str/1 lldt/2 ltr/3 err/4 verw/5 jmpe/6/dynamic invalid/7 + /* 00 */ eENTRY_Copy0F00, // sldt/0 str/1 lldt/2 ltr/3 err/4 verw/5 jmpe/6/dynamic invalid/7 #else - /* 00 */ ENTRY_CopyBytes2Mod, // sldt/0 str/1 lldt/2 ltr/3 err/4 verw/5 jmpe/6/dynamic invalid/7 + /* 00 */ eENTRY_CopyBytes2Mod, // sldt/0 str/1 lldt/2 ltr/3 err/4 verw/5 jmpe/6/dynamic invalid/7 #endif - /* 01 */ ENTRY_CopyBytes2Mod, // INVLPG/7, etc. - /* 02 */ ENTRY_CopyBytes2Mod, // LAR/r - /* 03 */ ENTRY_CopyBytes2Mod, // LSL/r - /* 04 */ ENTRY_Invalid, // _04 - /* 05 */ ENTRY_CopyBytes1, // SYSCALL - /* 06 */ ENTRY_CopyBytes1, // CLTS - /* 07 */ ENTRY_CopyBytes1, // SYSRET - /* 08 */ ENTRY_CopyBytes1, // INVD - /* 09 */ ENTRY_CopyBytes1, // WBINVD - /* 0A */ ENTRY_Invalid, // _0A - /* 0B */ ENTRY_CopyBytes1, // UD2 - /* 0C */ ENTRY_Invalid, // _0C - /* 0D */ ENTRY_CopyBytes2Mod, // PREFETCH - /* 0E */ ENTRY_CopyBytes1, // FEMMS (3DNow -- not in Intel documentation) - /* 0F */ ENTRY_CopyBytes2Mod1, // 3DNow Opcodes - /* 10 */ ENTRY_CopyBytes2Mod, // MOVSS MOVUPD MOVSD - /* 11 */ ENTRY_CopyBytes2Mod, // MOVSS MOVUPD MOVSD - /* 12 */ ENTRY_CopyBytes2Mod, // MOVLPD - /* 13 */ ENTRY_CopyBytes2Mod, // MOVLPD - /* 14 */ ENTRY_CopyBytes2Mod, // UNPCKLPD - /* 15 */ ENTRY_CopyBytes2Mod, // UNPCKHPD - /* 16 */ ENTRY_CopyBytes2Mod, // MOVHPD - /* 17 */ ENTRY_CopyBytes2Mod, // MOVHPD - /* 18 */ ENTRY_CopyBytes2Mod, // PREFETCHINTA... - /* 19 */ ENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD - /* 1A */ ENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD - /* 1B */ ENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD - /* 1C */ ENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD - /* 1D */ ENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD - /* 1E */ ENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD - /* 1F */ ENTRY_CopyBytes2Mod, // NOP/r multi byte nop - /* 20 */ ENTRY_CopyBytes2Mod, // MOV/r - /* 21 */ ENTRY_CopyBytes2Mod, // MOV/r - /* 22 */ ENTRY_CopyBytes2Mod, // MOV/r - /* 23 */ ENTRY_CopyBytes2Mod, // MOV/r + /* 01 */ eENTRY_CopyBytes2Mod, // INVLPG/7, etc. + /* 02 */ eENTRY_CopyBytes2Mod, // LAR/r + /* 03 */ eENTRY_CopyBytes2Mod, // LSL/r + /* 04 */ eENTRY_Invalid, // _04 + /* 05 */ eENTRY_CopyBytes1, // SYSCALL + /* 06 */ eENTRY_CopyBytes1, // CLTS + /* 07 */ eENTRY_CopyBytes1, // SYSRET + /* 08 */ eENTRY_CopyBytes1, // INVD + /* 09 */ eENTRY_CopyBytes1, // WBINVD + /* 0A */ eENTRY_Invalid, // _0A + /* 0B */ eENTRY_CopyBytes1, // UD2 + /* 0C */ eENTRY_Invalid, // _0C + /* 0D */ eENTRY_CopyBytes2Mod, // PREFETCH + /* 0E */ eENTRY_CopyBytes1, // FEMMS (3DNow -- not in Intel documentation) + /* 0F */ eENTRY_CopyBytes2Mod1, // 3DNow Opcodes + /* 10 */ eENTRY_CopyBytes2Mod, // MOVSS MOVUPD MOVSD + /* 11 */ eENTRY_CopyBytes2Mod, // MOVSS MOVUPD MOVSD + /* 12 */ eENTRY_CopyBytes2Mod, // MOVLPD + /* 13 */ eENTRY_CopyBytes2Mod, // MOVLPD + /* 14 */ eENTRY_CopyBytes2Mod, // UNPCKLPD + /* 15 */ eENTRY_CopyBytes2Mod, // UNPCKHPD + /* 16 */ eENTRY_CopyBytes2Mod, // MOVHPD + /* 17 */ eENTRY_CopyBytes2Mod, // MOVHPD + /* 18 */ eENTRY_CopyBytes2Mod, // PREFETCHINTA... + /* 19 */ eENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD + /* 1A */ eENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD + /* 1B */ eENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD + /* 1C */ eENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD + /* 1D */ eENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD + /* 1E */ eENTRY_CopyBytes2Mod, // NOP/r multi byte nop, not documented by Intel, documented by AMD + /* 1F */ eENTRY_CopyBytes2Mod, // NOP/r multi byte nop + /* 20 */ eENTRY_CopyBytes2Mod, // MOV/r + /* 21 */ eENTRY_CopyBytes2Mod, // MOV/r + /* 22 */ eENTRY_CopyBytes2Mod, // MOV/r + /* 23 */ eENTRY_CopyBytes2Mod, // MOV/r #if defined(_M_X64) - /* 24 */ ENTRY_Invalid, // _24 + /* 24 */ eENTRY_Invalid, // _24 #else - /* 24 */ ENTRY_CopyBytes2Mod, // MOV/r,TR TR is test register on 80386 and 80486, removed in Pentium + /* 24 */ eENTRY_CopyBytes2Mod, // MOV/r,TR TR is test register on 80386 and 80486, removed in Pentium #endif - /* 25 */ ENTRY_Invalid, // _25 + /* 25 */ eENTRY_Invalid, // _25 #if defined(_M_X64) - /* 26 */ ENTRY_Invalid, // _26 + /* 26 */ eENTRY_Invalid, // _26 #else - /* 26 */ ENTRY_CopyBytes2Mod, // MOV TR/r TR is test register on 80386 and 80486, removed in Pentium + /* 26 */ eENTRY_CopyBytes2Mod, // MOV TR/r TR is test register on 80386 and 80486, removed in Pentium #endif - /* 27 */ ENTRY_Invalid, // _27 - /* 28 */ ENTRY_CopyBytes2Mod, // MOVAPS MOVAPD - /* 29 */ ENTRY_CopyBytes2Mod, // MOVAPS MOVAPD - /* 2A */ ENTRY_CopyBytes2Mod, // CVPI2PS & - /* 2B */ ENTRY_CopyBytes2Mod, // MOVNTPS MOVNTPD - /* 2C */ ENTRY_CopyBytes2Mod, // CVTTPS2PI & - /* 2D */ ENTRY_CopyBytes2Mod, // CVTPS2PI & - /* 2E */ ENTRY_CopyBytes2Mod, // UCOMISS UCOMISD - /* 2F */ ENTRY_CopyBytes2Mod, // COMISS COMISD - /* 30 */ ENTRY_CopyBytes1, // WRMSR - /* 31 */ ENTRY_CopyBytes1, // RDTSC - /* 32 */ ENTRY_CopyBytes1, // RDMSR - /* 33 */ ENTRY_CopyBytes1, // RDPMC - /* 34 */ ENTRY_CopyBytes1, // SYSENTER - /* 35 */ ENTRY_CopyBytes1, // SYSEXIT - /* 36 */ ENTRY_Invalid, // _36 - /* 37 */ ENTRY_CopyBytes1, // GETSEC - /* 38 */ ENTRY_CopyBytes3Mod, // SSE3 Opcodes - /* 39 */ ENTRY_Invalid, // _39 - /* 3A */ ENTRY_CopyBytes3Mod1, // SSE3 Opcodes - /* 3B */ ENTRY_Invalid, // _3B - /* 3C */ ENTRY_Invalid, // _3C - /* 3D */ ENTRY_Invalid, // _3D - /* 3E */ ENTRY_Invalid, // _3E - /* 3F */ ENTRY_Invalid, // _3F - /* 40 */ ENTRY_CopyBytes2Mod, // CMOVO (0F 40) - /* 41 */ ENTRY_CopyBytes2Mod, // CMOVNO (0F 41) - /* 42 */ ENTRY_CopyBytes2Mod, // CMOVB & CMOVNE (0F 42) - /* 43 */ ENTRY_CopyBytes2Mod, // CMOVAE & CMOVNB (0F 43) - /* 44 */ ENTRY_CopyBytes2Mod, // CMOVE & CMOVZ (0F 44) - /* 45 */ ENTRY_CopyBytes2Mod, // CMOVNE & CMOVNZ (0F 45) - /* 46 */ ENTRY_CopyBytes2Mod, // CMOVBE & CMOVNA (0F 46) - /* 47 */ ENTRY_CopyBytes2Mod, // CMOVA & CMOVNBE (0F 47) - /* 48 */ ENTRY_CopyBytes2Mod, // CMOVS (0F 48) - /* 49 */ ENTRY_CopyBytes2Mod, // CMOVNS (0F 49) - /* 4A */ ENTRY_CopyBytes2Mod, // CMOVP & CMOVPE (0F 4A) - /* 4B */ ENTRY_CopyBytes2Mod, // CMOVNP & CMOVPO (0F 4B) - /* 4C */ ENTRY_CopyBytes2Mod, // CMOVL & CMOVNGE (0F 4C) - /* 4D */ ENTRY_CopyBytes2Mod, // CMOVGE & CMOVNL (0F 4D) - /* 4E */ ENTRY_CopyBytes2Mod, // CMOVLE & CMOVNG (0F 4E) - /* 4F */ ENTRY_CopyBytes2Mod, // CMOVG & CMOVNLE (0F 4F) - /* 50 */ ENTRY_CopyBytes2Mod, // MOVMSKPD MOVMSKPD - /* 51 */ ENTRY_CopyBytes2Mod, // SQRTPS & - /* 52 */ ENTRY_CopyBytes2Mod, // RSQRTTS RSQRTPS - /* 53 */ ENTRY_CopyBytes2Mod, // RCPPS RCPSS - /* 54 */ ENTRY_CopyBytes2Mod, // ANDPS ANDPD - /* 55 */ ENTRY_CopyBytes2Mod, // ANDNPS ANDNPD - /* 56 */ ENTRY_CopyBytes2Mod, // ORPS ORPD - /* 57 */ ENTRY_CopyBytes2Mod, // XORPS XORPD - /* 58 */ ENTRY_CopyBytes2Mod, // ADDPS & - /* 59 */ ENTRY_CopyBytes2Mod, // MULPS & - /* 5A */ ENTRY_CopyBytes2Mod, // CVTPS2PD & - /* 5B */ ENTRY_CopyBytes2Mod, // CVTDQ2PS & - /* 5C */ ENTRY_CopyBytes2Mod, // SUBPS & - /* 5D */ ENTRY_CopyBytes2Mod, // MINPS & - /* 5E */ ENTRY_CopyBytes2Mod, // DIVPS & - /* 5F */ ENTRY_CopyBytes2Mod, // MASPS & - /* 60 */ ENTRY_CopyBytes2Mod, // PUNPCKLBW/r - /* 61 */ ENTRY_CopyBytes2Mod, // PUNPCKLWD/r - /* 62 */ ENTRY_CopyBytes2Mod, // PUNPCKLWD/r - /* 63 */ ENTRY_CopyBytes2Mod, // PACKSSWB/r - /* 64 */ ENTRY_CopyBytes2Mod, // PCMPGTB/r - /* 65 */ ENTRY_CopyBytes2Mod, // PCMPGTW/r - /* 66 */ ENTRY_CopyBytes2Mod, // PCMPGTD/r - /* 67 */ ENTRY_CopyBytes2Mod, // PACKUSWB/r - /* 68 */ ENTRY_CopyBytes2Mod, // PUNPCKHBW/r - /* 69 */ ENTRY_CopyBytes2Mod, // PUNPCKHWD/r - /* 6A */ ENTRY_CopyBytes2Mod, // PUNPCKHDQ/r - /* 6B */ ENTRY_CopyBytes2Mod, // PACKSSDW/r - /* 6C */ ENTRY_CopyBytes2Mod, // PUNPCKLQDQ - /* 6D */ ENTRY_CopyBytes2Mod, // PUNPCKHQDQ - /* 6E */ ENTRY_CopyBytes2Mod, // MOVD/r - /* 6F */ ENTRY_CopyBytes2Mod, // MOV/r - /* 70 */ ENTRY_CopyBytes2Mod1, // PSHUFW/r ib - /* 71 */ ENTRY_CopyBytes2Mod1, // PSLLW/6 ib,PSRAW/4 ib,PSRLW/2 ib - /* 72 */ ENTRY_CopyBytes2Mod1, // PSLLD/6 ib,PSRAD/4 ib,PSRLD/2 ib - /* 73 */ ENTRY_CopyBytes2Mod1, // PSLLQ/6 ib,PSRLQ/2 ib - /* 74 */ ENTRY_CopyBytes2Mod, // PCMPEQB/r - /* 75 */ ENTRY_CopyBytes2Mod, // PCMPEQW/r - /* 76 */ ENTRY_CopyBytes2Mod, // PCMPEQD/r - /* 77 */ ENTRY_CopyBytes1, // EMMS + /* 27 */ eENTRY_Invalid, // _27 + /* 28 */ eENTRY_CopyBytes2Mod, // MOVAPS MOVAPD + /* 29 */ eENTRY_CopyBytes2Mod, // MOVAPS MOVAPD + /* 2A */ eENTRY_CopyBytes2Mod, // CVPI2PS & + /* 2B */ eENTRY_CopyBytes2Mod, // MOVNTPS MOVNTPD + /* 2C */ eENTRY_CopyBytes2Mod, // CVTTPS2PI & + /* 2D */ eENTRY_CopyBytes2Mod, // CVTPS2PI & + /* 2E */ eENTRY_CopyBytes2Mod, // UCOMISS UCOMISD + /* 2F */ eENTRY_CopyBytes2Mod, // COMISS COMISD + /* 30 */ eENTRY_CopyBytes1, // WRMSR + /* 31 */ eENTRY_CopyBytes1, // RDTSC + /* 32 */ eENTRY_CopyBytes1, // RDMSR + /* 33 */ eENTRY_CopyBytes1, // RDPMC + /* 34 */ eENTRY_CopyBytes1, // SYSENTER + /* 35 */ eENTRY_CopyBytes1, // SYSEXIT + /* 36 */ eENTRY_Invalid, // _36 + /* 37 */ eENTRY_CopyBytes1, // GETSEC + /* 38 */ eENTRY_CopyBytes3Mod, // SSE3 Opcodes + /* 39 */ eENTRY_Invalid, // _39 + /* 3A */ eENTRY_CopyBytes3Mod1, // SSE3 Opcodes + /* 3B */ eENTRY_Invalid, // _3B + /* 3C */ eENTRY_Invalid, // _3C + /* 3D */ eENTRY_Invalid, // _3D + /* 3E */ eENTRY_Invalid, // _3E + /* 3F */ eENTRY_Invalid, // _3F + /* 40 */ eENTRY_CopyBytes2Mod, // CMOVO (0F 40) + /* 41 */ eENTRY_CopyBytes2Mod, // CMOVNO (0F 41) + /* 42 */ eENTRY_CopyBytes2Mod, // CMOVB & CMOVNE (0F 42) + /* 43 */ eENTRY_CopyBytes2Mod, // CMOVAE & CMOVNB (0F 43) + /* 44 */ eENTRY_CopyBytes2Mod, // CMOVE & CMOVZ (0F 44) + /* 45 */ eENTRY_CopyBytes2Mod, // CMOVNE & CMOVNZ (0F 45) + /* 46 */ eENTRY_CopyBytes2Mod, // CMOVBE & CMOVNA (0F 46) + /* 47 */ eENTRY_CopyBytes2Mod, // CMOVA & CMOVNBE (0F 47) + /* 48 */ eENTRY_CopyBytes2Mod, // CMOVS (0F 48) + /* 49 */ eENTRY_CopyBytes2Mod, // CMOVNS (0F 49) + /* 4A */ eENTRY_CopyBytes2Mod, // CMOVP & CMOVPE (0F 4A) + /* 4B */ eENTRY_CopyBytes2Mod, // CMOVNP & CMOVPO (0F 4B) + /* 4C */ eENTRY_CopyBytes2Mod, // CMOVL & CMOVNGE (0F 4C) + /* 4D */ eENTRY_CopyBytes2Mod, // CMOVGE & CMOVNL (0F 4D) + /* 4E */ eENTRY_CopyBytes2Mod, // CMOVLE & CMOVNG (0F 4E) + /* 4F */ eENTRY_CopyBytes2Mod, // CMOVG & CMOVNLE (0F 4F) + /* 50 */ eENTRY_CopyBytes2Mod, // MOVMSKPD MOVMSKPD + /* 51 */ eENTRY_CopyBytes2Mod, // SQRTPS & + /* 52 */ eENTRY_CopyBytes2Mod, // RSQRTTS RSQRTPS + /* 53 */ eENTRY_CopyBytes2Mod, // RCPPS RCPSS + /* 54 */ eENTRY_CopyBytes2Mod, // ANDPS ANDPD + /* 55 */ eENTRY_CopyBytes2Mod, // ANDNPS ANDNPD + /* 56 */ eENTRY_CopyBytes2Mod, // ORPS ORPD + /* 57 */ eENTRY_CopyBytes2Mod, // XORPS XORPD + /* 58 */ eENTRY_CopyBytes2Mod, // ADDPS & + /* 59 */ eENTRY_CopyBytes2Mod, // MULPS & + /* 5A */ eENTRY_CopyBytes2Mod, // CVTPS2PD & + /* 5B */ eENTRY_CopyBytes2Mod, // CVTDQ2PS & + /* 5C */ eENTRY_CopyBytes2Mod, // SUBPS & + /* 5D */ eENTRY_CopyBytes2Mod, // MINPS & + /* 5E */ eENTRY_CopyBytes2Mod, // DIVPS & + /* 5F */ eENTRY_CopyBytes2Mod, // MASPS & + /* 60 */ eENTRY_CopyBytes2Mod, // PUNPCKLBW/r + /* 61 */ eENTRY_CopyBytes2Mod, // PUNPCKLWD/r + /* 62 */ eENTRY_CopyBytes2Mod, // PUNPCKLWD/r + /* 63 */ eENTRY_CopyBytes2Mod, // PACKSSWB/r + /* 64 */ eENTRY_CopyBytes2Mod, // PCMPGTB/r + /* 65 */ eENTRY_CopyBytes2Mod, // PCMPGTW/r + /* 66 */ eENTRY_CopyBytes2Mod, // PCMPGTD/r + /* 67 */ eENTRY_CopyBytes2Mod, // PACKUSWB/r + /* 68 */ eENTRY_CopyBytes2Mod, // PUNPCKHBW/r + /* 69 */ eENTRY_CopyBytes2Mod, // PUNPCKHWD/r + /* 6A */ eENTRY_CopyBytes2Mod, // PUNPCKHDQ/r + /* 6B */ eENTRY_CopyBytes2Mod, // PACKSSDW/r + /* 6C */ eENTRY_CopyBytes2Mod, // PUNPCKLQDQ + /* 6D */ eENTRY_CopyBytes2Mod, // PUNPCKHQDQ + /* 6E */ eENTRY_CopyBytes2Mod, // MOVD/r + /* 6F */ eENTRY_CopyBytes2Mod, // MOV/r + /* 70 */ eENTRY_CopyBytes2Mod1, // PSHUFW/r ib + /* 71 */ eENTRY_CopyBytes2Mod1, // PSLLW/6 ib,PSRAW/4 ib,PSRLW/2 ib + /* 72 */ eENTRY_CopyBytes2Mod1, // PSLLD/6 ib,PSRAD/4 ib,PSRLD/2 ib + /* 73 */ eENTRY_CopyBytes2Mod1, // PSLLQ/6 ib,PSRLQ/2 ib + /* 74 */ eENTRY_CopyBytes2Mod, // PCMPEQB/r + /* 75 */ eENTRY_CopyBytes2Mod, // PCMPEQW/r + /* 76 */ eENTRY_CopyBytes2Mod, // PCMPEQD/r + /* 77 */ eENTRY_CopyBytes1, // EMMS // extrq/insertq require mode=3 and are followed by two immediate bytes - /* 78 */ ENTRY_Copy0F78, // VMREAD/r, 66/EXTRQ/r/ib/ib, F2/INSERTQ/r/ib/ib - // extrq/insertq require mod=3, therefore ENTRY_CopyBytes2, but it ends up the same - /* 79 */ ENTRY_CopyBytes2Mod, // VMWRITE/r, 66/EXTRQ/r, F2/INSERTQ/r - /* 7A */ ENTRY_Invalid, // _7A - /* 7B */ ENTRY_Invalid, // _7B - /* 7C */ ENTRY_CopyBytes2Mod, // HADDPS - /* 7D */ ENTRY_CopyBytes2Mod, // HSUBPS - /* 7E */ ENTRY_CopyBytes2Mod, // MOVD/r - /* 7F */ ENTRY_CopyBytes2Mod, // MOV/r - /* 80 */ ENTRY_CopyBytes3Or5Target, // JO - /* 81 */ ENTRY_CopyBytes3Or5Target, // JNO - /* 82 */ ENTRY_CopyBytes3Or5Target, // JB,JC,JNAE - /* 83 */ ENTRY_CopyBytes3Or5Target, // JAE,JNB,JNC - /* 84 */ ENTRY_CopyBytes3Or5Target, // JE,JZ,JZ - /* 85 */ ENTRY_CopyBytes3Or5Target, // JNE,JNZ - /* 86 */ ENTRY_CopyBytes3Or5Target, // JBE,JNA - /* 87 */ ENTRY_CopyBytes3Or5Target, // JA,JNBE - /* 88 */ ENTRY_CopyBytes3Or5Target, // JS - /* 89 */ ENTRY_CopyBytes3Or5Target, // JNS - /* 8A */ ENTRY_CopyBytes3Or5Target, // JP,JPE - /* 8B */ ENTRY_CopyBytes3Or5Target, // JNP,JPO - /* 8C */ ENTRY_CopyBytes3Or5Target, // JL,NGE - /* 8D */ ENTRY_CopyBytes3Or5Target, // JGE,JNL - /* 8E */ ENTRY_CopyBytes3Or5Target, // JLE,JNG - /* 8F */ ENTRY_CopyBytes3Or5Target, // JG,JNLE - /* 90 */ ENTRY_CopyBytes2Mod, // CMOVO (0F 40) - /* 91 */ ENTRY_CopyBytes2Mod, // CMOVNO (0F 41) - /* 92 */ ENTRY_CopyBytes2Mod, // CMOVB & CMOVC & CMOVNAE (0F 42) - /* 93 */ ENTRY_CopyBytes2Mod, // CMOVAE & CMOVNB & CMOVNC (0F 43) - /* 94 */ ENTRY_CopyBytes2Mod, // CMOVE & CMOVZ (0F 44) - /* 95 */ ENTRY_CopyBytes2Mod, // CMOVNE & CMOVNZ (0F 45) - /* 96 */ ENTRY_CopyBytes2Mod, // CMOVBE & CMOVNA (0F 46) - /* 97 */ ENTRY_CopyBytes2Mod, // CMOVA & CMOVNBE (0F 47) - /* 98 */ ENTRY_CopyBytes2Mod, // CMOVS (0F 48) - /* 99 */ ENTRY_CopyBytes2Mod, // CMOVNS (0F 49) - /* 9A */ ENTRY_CopyBytes2Mod, // CMOVP & CMOVPE (0F 4A) - /* 9B */ ENTRY_CopyBytes2Mod, // CMOVNP & CMOVPO (0F 4B) - /* 9C */ ENTRY_CopyBytes2Mod, // CMOVL & CMOVNGE (0F 4C) - /* 9D */ ENTRY_CopyBytes2Mod, // CMOVGE & CMOVNL (0F 4D) - /* 9E */ ENTRY_CopyBytes2Mod, // CMOVLE & CMOVNG (0F 4E) - /* 9F */ ENTRY_CopyBytes2Mod, // CMOVG & CMOVNLE (0F 4F) - /* A0 */ ENTRY_CopyBytes1, // PUSH - /* A1 */ ENTRY_CopyBytes1, // POP - /* A2 */ ENTRY_CopyBytes1, // CPUID - /* A3 */ ENTRY_CopyBytes2Mod, // BT (0F A3) - /* A4 */ ENTRY_CopyBytes2Mod1, // SHLD - /* A5 */ ENTRY_CopyBytes2Mod, // SHLD - /* A6 */ ENTRY_CopyBytes2Mod, // XBTS - /* A7 */ ENTRY_CopyBytes2Mod, // IBTS - /* A8 */ ENTRY_CopyBytes1, // PUSH - /* A9 */ ENTRY_CopyBytes1, // POP - /* AA */ ENTRY_CopyBytes1, // RSM - /* AB */ ENTRY_CopyBytes2Mod, // BTS (0F AB) - /* AC */ ENTRY_CopyBytes2Mod1, // SHRD - /* AD */ ENTRY_CopyBytes2Mod, // SHRD + /* 78 */ eENTRY_Copy0F78, // VMREAD/r, 66/EXTRQ/r/ib/ib, F2/INSERTQ/r/ib/ib + // extrq/insertq require mod=3, therefore eENTRY_CopyBytes2, but it ends up the same + /* 79 */ eENTRY_CopyBytes2Mod, // VMWRITE/r, 66/EXTRQ/r, F2/INSERTQ/r + /* 7A */ eENTRY_Invalid, // _7A + /* 7B */ eENTRY_Invalid, // _7B + /* 7C */ eENTRY_CopyBytes2Mod, // HADDPS + /* 7D */ eENTRY_CopyBytes2Mod, // HSUBPS + /* 7E */ eENTRY_CopyBytes2Mod, // MOVD/r + /* 7F */ eENTRY_CopyBytes2Mod, // MOV/r + /* 80 */ eENTRY_CopyBytes3Or5Target, // JO + /* 81 */ eENTRY_CopyBytes3Or5Target, // JNO + /* 82 */ eENTRY_CopyBytes3Or5Target, // JB,JC,JNAE + /* 83 */ eENTRY_CopyBytes3Or5Target, // JAE,JNB,JNC + /* 84 */ eENTRY_CopyBytes3Or5Target, // JE,JZ,JZ + /* 85 */ eENTRY_CopyBytes3Or5Target, // JNE,JNZ + /* 86 */ eENTRY_CopyBytes3Or5Target, // JBE,JNA + /* 87 */ eENTRY_CopyBytes3Or5Target, // JA,JNBE + /* 88 */ eENTRY_CopyBytes3Or5Target, // JS + /* 89 */ eENTRY_CopyBytes3Or5Target, // JNS + /* 8A */ eENTRY_CopyBytes3Or5Target, // JP,JPE + /* 8B */ eENTRY_CopyBytes3Or5Target, // JNP,JPO + /* 8C */ eENTRY_CopyBytes3Or5Target, // JL,NGE + /* 8D */ eENTRY_CopyBytes3Or5Target, // JGE,JNL + /* 8E */ eENTRY_CopyBytes3Or5Target, // JLE,JNG + /* 8F */ eENTRY_CopyBytes3Or5Target, // JG,JNLE + /* 90 */ eENTRY_CopyBytes2Mod, // CMOVO (0F 40) + /* 91 */ eENTRY_CopyBytes2Mod, // CMOVNO (0F 41) + /* 92 */ eENTRY_CopyBytes2Mod, // CMOVB & CMOVC & CMOVNAE (0F 42) + /* 93 */ eENTRY_CopyBytes2Mod, // CMOVAE & CMOVNB & CMOVNC (0F 43) + /* 94 */ eENTRY_CopyBytes2Mod, // CMOVE & CMOVZ (0F 44) + /* 95 */ eENTRY_CopyBytes2Mod, // CMOVNE & CMOVNZ (0F 45) + /* 96 */ eENTRY_CopyBytes2Mod, // CMOVBE & CMOVNA (0F 46) + /* 97 */ eENTRY_CopyBytes2Mod, // CMOVA & CMOVNBE (0F 47) + /* 98 */ eENTRY_CopyBytes2Mod, // CMOVS (0F 48) + /* 99 */ eENTRY_CopyBytes2Mod, // CMOVNS (0F 49) + /* 9A */ eENTRY_CopyBytes2Mod, // CMOVP & CMOVPE (0F 4A) + /* 9B */ eENTRY_CopyBytes2Mod, // CMOVNP & CMOVPO (0F 4B) + /* 9C */ eENTRY_CopyBytes2Mod, // CMOVL & CMOVNGE (0F 4C) + /* 9D */ eENTRY_CopyBytes2Mod, // CMOVGE & CMOVNL (0F 4D) + /* 9E */ eENTRY_CopyBytes2Mod, // CMOVLE & CMOVNG (0F 4E) + /* 9F */ eENTRY_CopyBytes2Mod, // CMOVG & CMOVNLE (0F 4F) + /* A0 */ eENTRY_CopyBytes1, // PUSH + /* A1 */ eENTRY_CopyBytes1, // POP + /* A2 */ eENTRY_CopyBytes1, // CPUID + /* A3 */ eENTRY_CopyBytes2Mod, // BT (0F A3) + /* A4 */ eENTRY_CopyBytes2Mod1, // SHLD + /* A5 */ eENTRY_CopyBytes2Mod, // SHLD + /* A6 */ eENTRY_CopyBytes2Mod, // XBTS + /* A7 */ eENTRY_CopyBytes2Mod, // IBTS + /* A8 */ eENTRY_CopyBytes1, // PUSH + /* A9 */ eENTRY_CopyBytes1, // POP + /* AA */ eENTRY_CopyBytes1, // RSM + /* AB */ eENTRY_CopyBytes2Mod, // BTS (0F AB) + /* AC */ eENTRY_CopyBytes2Mod1, // SHRD + /* AD */ eENTRY_CopyBytes2Mod, // SHRD // 0F AE mod76=mem mod543=0 fxsave // 0F AE mod76=mem mod543=1 fxrstor @@ -1478,96 +1531,97 @@ const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable0F[] = // F3 0F AE mod76=11b mod543=1 rdgsbase // F3 0F AE mod76=11b mod543=2 wrfsbase // F3 0F AE mod76=11b mod543=3 wrgsbase - /* AE */ ENTRY_CopyBytes2Mod, // fxsave fxrstor ldmxcsr stmxcsr xsave xrstor saveopt clflush lfence mfence sfence rdfsbase rdgsbase wrfsbase wrgsbase - /* AF */ ENTRY_CopyBytes2Mod, // IMUL (0F AF) - /* B0 */ ENTRY_CopyBytes2Mod, // CMPXCHG (0F B0) - /* B1 */ ENTRY_CopyBytes2Mod, // CMPXCHG (0F B1) - /* B2 */ ENTRY_CopyBytes2Mod, // LSS/r - /* B3 */ ENTRY_CopyBytes2Mod, // BTR (0F B3) - /* B4 */ ENTRY_CopyBytes2Mod, // LFS/r - /* B5 */ ENTRY_CopyBytes2Mod, // LGS/r - /* B6 */ ENTRY_CopyBytes2Mod, // MOVZX/r - /* B7 */ ENTRY_CopyBytes2Mod, // MOVZX/r + /* AE */ eENTRY_CopyBytes2Mod, // fxsave fxrstor ldmxcsr stmxcsr xsave xrstor saveopt clflush lfence mfence sfence rdfsbase rdgsbase wrfsbase wrgsbase + /* AF */ eENTRY_CopyBytes2Mod, // IMUL (0F AF) + /* B0 */ eENTRY_CopyBytes2Mod, // CMPXCHG (0F B0) + /* B1 */ eENTRY_CopyBytes2Mod, // CMPXCHG (0F B1) + /* B2 */ eENTRY_CopyBytes2Mod, // LSS/r + /* B3 */ eENTRY_CopyBytes2Mod, // BTR (0F B3) + /* B4 */ eENTRY_CopyBytes2Mod, // LFS/r + /* B5 */ eENTRY_CopyBytes2Mod, // LGS/r + /* B6 */ eENTRY_CopyBytes2Mod, // MOVZX/r + /* B7 */ eENTRY_CopyBytes2Mod, // MOVZX/r #if defined(_M_IX86) - /* B8 */ ENTRY_Copy0FB8, // jmpe f3/popcnt + /* B8 */ eENTRY_Copy0FB8, // jmpe f3/popcnt #else - /* B8 */ ENTRY_CopyBytes2Mod, // f3/popcnt + /* B8 */ eENTRY_CopyBytes2Mod, // f3/popcnt #endif - /* B9 */ ENTRY_Invalid, // _B9 - /* BA */ ENTRY_CopyBytes2Mod1, // BT & BTC & BTR & BTS (0F BA) - /* BB */ ENTRY_CopyBytes2Mod, // BTC (0F BB) - /* BC */ ENTRY_CopyBytes2Mod, // BSF (0F BC) - /* BD */ ENTRY_CopyBytes2Mod, // BSR (0F BD) - /* BE */ ENTRY_CopyBytes2Mod, // MOVSX/r - /* BF */ ENTRY_CopyBytes2Mod, // MOVSX/r - /* C0 */ ENTRY_CopyBytes2Mod, // XADD/r - /* C1 */ ENTRY_CopyBytes2Mod, // XADD/r - /* C2 */ ENTRY_CopyBytes2Mod1, // CMPPS & - /* C3 */ ENTRY_CopyBytes2Mod, // MOVNTI - /* C4 */ ENTRY_CopyBytes2Mod1, // PINSRW /r ib - /* C5 */ ENTRY_CopyBytes2Mod1, // PEXTRW /r ib - /* C6 */ ENTRY_CopyBytes2Mod1, // SHUFPS & SHUFPD - /* C7 */ ENTRY_CopyBytes2Mod, // CMPXCHG8B (0F C7) - /* C8 */ ENTRY_CopyBytes1, // BSWAP 0F C8 + rd - /* C9 */ ENTRY_CopyBytes1, // BSWAP 0F C8 + rd - /* CA */ ENTRY_CopyBytes1, // BSWAP 0F C8 + rd - /* CB */ ENTRY_CopyBytes1, // CVTPD2PI BSWAP 0F C8 + rd - /* CC */ ENTRY_CopyBytes1, // BSWAP 0F C8 + rd - /* CD */ ENTRY_CopyBytes1, // BSWAP 0F C8 + rd - /* CE */ ENTRY_CopyBytes1, // BSWAP 0F C8 + rd - /* CF */ ENTRY_CopyBytes1, // BSWAP 0F C8 + rd - /* D0 */ ENTRY_CopyBytes2Mod, // ADDSUBPS (untestd) - /* D1 */ ENTRY_CopyBytes2Mod, // PSRLW/r - /* D2 */ ENTRY_CopyBytes2Mod, // PSRLD/r - /* D3 */ ENTRY_CopyBytes2Mod, // PSRLQ/r - /* D4 */ ENTRY_CopyBytes2Mod, // PADDQ - /* D5 */ ENTRY_CopyBytes2Mod, // PMULLW/r - /* D6 */ ENTRY_CopyBytes2Mod, // MOVDQ2Q / MOVQ2DQ - /* D7 */ ENTRY_CopyBytes2Mod, // PMOVMSKB/r - /* D8 */ ENTRY_CopyBytes2Mod, // PSUBUSB/r - /* D9 */ ENTRY_CopyBytes2Mod, // PSUBUSW/r - /* DA */ ENTRY_CopyBytes2Mod, // PMINUB/r - /* DB */ ENTRY_CopyBytes2Mod, // PAND/r - /* DC */ ENTRY_CopyBytes2Mod, // PADDUSB/r - /* DD */ ENTRY_CopyBytes2Mod, // PADDUSW/r - /* DE */ ENTRY_CopyBytes2Mod, // PMAXUB/r - /* DF */ ENTRY_CopyBytes2Mod, // PANDN/r - /* E0 */ ENTRY_CopyBytes2Mod , // PAVGB - /* E1 */ ENTRY_CopyBytes2Mod, // PSRAW/r - /* E2 */ ENTRY_CopyBytes2Mod, // PSRAD/r - /* E3 */ ENTRY_CopyBytes2Mod, // PAVGW - /* E4 */ ENTRY_CopyBytes2Mod, // PMULHUW/r - /* E5 */ ENTRY_CopyBytes2Mod, // PMULHW/r - /* E6 */ ENTRY_CopyBytes2Mod, // CTDQ2PD & - /* E7 */ ENTRY_CopyBytes2Mod, // MOVNTQ - /* E8 */ ENTRY_CopyBytes2Mod, // PSUBB/r - /* E9 */ ENTRY_CopyBytes2Mod, // PSUBW/r - /* EA */ ENTRY_CopyBytes2Mod, // PMINSW/r - /* EB */ ENTRY_CopyBytes2Mod, // POR/r - /* EC */ ENTRY_CopyBytes2Mod, // PADDSB/r - /* ED */ ENTRY_CopyBytes2Mod, // PADDSW/r - /* EE */ ENTRY_CopyBytes2Mod, // PMAXSW /r - /* EF */ ENTRY_CopyBytes2Mod, // PXOR/r - /* F0 */ ENTRY_CopyBytes2Mod, // LDDQU - /* F1 */ ENTRY_CopyBytes2Mod, // PSLLW/r - /* F2 */ ENTRY_CopyBytes2Mod, // PSLLD/r - /* F3 */ ENTRY_CopyBytes2Mod, // PSLLQ/r - /* F4 */ ENTRY_CopyBytes2Mod, // PMULUDQ/r - /* F5 */ ENTRY_CopyBytes2Mod, // PMADDWD/r - /* F6 */ ENTRY_CopyBytes2Mod, // PSADBW/r - /* F7 */ ENTRY_CopyBytes2Mod, // MASKMOVQ - /* F8 */ ENTRY_CopyBytes2Mod, // PSUBB/r - /* F9 */ ENTRY_CopyBytes2Mod, // PSUBW/r - /* FA */ ENTRY_CopyBytes2Mod, // PSUBD/r - /* FB */ ENTRY_CopyBytes2Mod, // FSUBQ/r - /* FC */ ENTRY_CopyBytes2Mod, // PADDB/r - /* FD */ ENTRY_CopyBytes2Mod, // PADDW/r - /* FE */ ENTRY_CopyBytes2Mod, // PADDD/r - /* FF */ ENTRY_Invalid, // _FF + /* B9 */ eENTRY_Invalid, // _B9 + /* BA */ eENTRY_CopyBytes2Mod1, // BT & BTC & BTR & BTS (0F BA) + /* BB */ eENTRY_CopyBytes2Mod, // BTC (0F BB) + /* BC */ eENTRY_CopyBytes2Mod, // BSF (0F BC) + /* BD */ eENTRY_CopyBytes2Mod, // BSR (0F BD) + /* BE */ eENTRY_CopyBytes2Mod, // MOVSX/r + /* BF */ eENTRY_CopyBytes2Mod, // MOVSX/r + /* C0 */ eENTRY_CopyBytes2Mod, // XADD/r + /* C1 */ eENTRY_CopyBytes2Mod, // XADD/r + /* C2 */ eENTRY_CopyBytes2Mod1, // CMPPS & + /* C3 */ eENTRY_CopyBytes2Mod, // MOVNTI + /* C4 */ eENTRY_CopyBytes2Mod1, // PINSRW /r ib + /* C5 */ eENTRY_CopyBytes2Mod1, // PEXTRW /r ib + /* C6 */ eENTRY_CopyBytes2Mod1, // SHUFPS & SHUFPD + /* C7 */ eENTRY_CopyBytes2Mod, // CMPXCHG8B (0F C7) + /* C8 */ eENTRY_CopyBytes1, // BSWAP 0F C8 + rd + /* C9 */ eENTRY_CopyBytes1, // BSWAP 0F C8 + rd + /* CA */ eENTRY_CopyBytes1, // BSWAP 0F C8 + rd + /* CB */ eENTRY_CopyBytes1, // CVTPD2PI BSWAP 0F C8 + rd + /* CC */ eENTRY_CopyBytes1, // BSWAP 0F C8 + rd + /* CD */ eENTRY_CopyBytes1, // BSWAP 0F C8 + rd + /* CE */ eENTRY_CopyBytes1, // BSWAP 0F C8 + rd + /* CF */ eENTRY_CopyBytes1, // BSWAP 0F C8 + rd + /* D0 */ eENTRY_CopyBytes2Mod, // ADDSUBPS (untestd) + /* D1 */ eENTRY_CopyBytes2Mod, // PSRLW/r + /* D2 */ eENTRY_CopyBytes2Mod, // PSRLD/r + /* D3 */ eENTRY_CopyBytes2Mod, // PSRLQ/r + /* D4 */ eENTRY_CopyBytes2Mod, // PADDQ + /* D5 */ eENTRY_CopyBytes2Mod, // PMULLW/r + /* D6 */ eENTRY_CopyBytes2Mod, // MOVDQ2Q / MOVQ2DQ + /* D7 */ eENTRY_CopyBytes2Mod, // PMOVMSKB/r + /* D8 */ eENTRY_CopyBytes2Mod, // PSUBUSB/r + /* D9 */ eENTRY_CopyBytes2Mod, // PSUBUSW/r + /* DA */ eENTRY_CopyBytes2Mod, // PMINUB/r + /* DB */ eENTRY_CopyBytes2Mod, // PAND/r + /* DC */ eENTRY_CopyBytes2Mod, // PADDUSB/r + /* DD */ eENTRY_CopyBytes2Mod, // PADDUSW/r + /* DE */ eENTRY_CopyBytes2Mod, // PMAXUB/r + /* DF */ eENTRY_CopyBytes2Mod, // PANDN/r + /* E0 */ eENTRY_CopyBytes2Mod , // PAVGB + /* E1 */ eENTRY_CopyBytes2Mod, // PSRAW/r + /* E2 */ eENTRY_CopyBytes2Mod, // PSRAD/r + /* E3 */ eENTRY_CopyBytes2Mod, // PAVGW + /* E4 */ eENTRY_CopyBytes2Mod, // PMULHUW/r + /* E5 */ eENTRY_CopyBytes2Mod, // PMULHW/r + /* E6 */ eENTRY_CopyBytes2Mod, // CTDQ2PD & + /* E7 */ eENTRY_CopyBytes2Mod, // MOVNTQ + /* E8 */ eENTRY_CopyBytes2Mod, // PSUBB/r + /* E9 */ eENTRY_CopyBytes2Mod, // PSUBW/r + /* EA */ eENTRY_CopyBytes2Mod, // PMINSW/r + /* EB */ eENTRY_CopyBytes2Mod, // POR/r + /* EC */ eENTRY_CopyBytes2Mod, // PADDSB/r + /* ED */ eENTRY_CopyBytes2Mod, // PADDSW/r + /* EE */ eENTRY_CopyBytes2Mod, // PMAXSW /r + /* EF */ eENTRY_CopyBytes2Mod, // PXOR/r + /* F0 */ eENTRY_CopyBytes2Mod, // LDDQU + /* F1 */ eENTRY_CopyBytes2Mod, // PSLLW/r + /* F2 */ eENTRY_CopyBytes2Mod, // PSLLD/r + /* F3 */ eENTRY_CopyBytes2Mod, // PSLLQ/r + /* F4 */ eENTRY_CopyBytes2Mod, // PMULUDQ/r + /* F5 */ eENTRY_CopyBytes2Mod, // PMADDWD/r + /* F6 */ eENTRY_CopyBytes2Mod, // PSADBW/r + /* F7 */ eENTRY_CopyBytes2Mod, // MASKMOVQ + /* F8 */ eENTRY_CopyBytes2Mod, // PSUBB/r + /* F9 */ eENTRY_CopyBytes2Mod, // PSUBW/r + /* FA */ eENTRY_CopyBytes2Mod, // PSUBD/r + /* FB */ eENTRY_CopyBytes2Mod, // FSUBQ/r + /* FC */ eENTRY_CopyBytes2Mod, // PADDB/r + /* FD */ eENTRY_CopyBytes2Mod, // PADDW/r + /* FE */ eENTRY_CopyBytes2Mod, // PADDD/r + /* FF */ eENTRY_Invalid, // _FF }; BOOL CDetourDis::SanityCheckSystem() { + static_assert(ARRAYSIZE(CDetourDis::s_rceCopyMap) == eENTRY_Invalid + 1); static_assert(ARRAYSIZE(CDetourDis::s_rceCopyTable) == 256); static_assert(ARRAYSIZE(CDetourDis::s_rceCopyTable0F) == 256); return TRUE;