CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/byakugan/detours/disasm.cpp
Views: 11779
1
//////////////////////////////////////////////////////////////////////////////
2
//
3
// Detours Disassembler (disasm.cpp of detours.lib)
4
//
5
// Microsoft Research Detours Package, Version 2.1.
6
//
7
// Copyright (c) Microsoft Corporation. All rights reserved.
8
//
9
10
#include <windows.h>
11
#include <limits.h>
12
13
// #define DETOUR_DEBUG 1
14
#define DETOURS_INTERNAL
15
16
#include "detours.h"
17
18
#if !defined(DETOURS_X86) && !defined(DETOURS_X64) && !defined(DETOURS_IA64)
19
#error Must define one of DETOURS_X86, DETOURS_X64, or DETOURS_IA64
20
#endif
21
22
#undef ASSERT
23
#define ASSERT(x)
24
25
//////////////////////////////////////////////////////////////////////////////
26
//
27
// Function:
28
// DetourCopyInstructionEx(PVOID pDst,
29
// PVOID pSrc,
30
// PVOID *ppTarget,
31
// LONG *plExtra)
32
// Purpose:
33
// Copy a single instruction from pSrc to pDst.
34
//
35
// Arguments:
36
// pDst:
37
// Destination address for the instruction. May be NULL in which
38
// case DetourCopyInstruction is used to measure an instruction.
39
// If not NULL then the source instruction is copied to the
40
// destination instruction and any relative arguments are adjusted.
41
// pSrc:
42
// Source address of the instruction.
43
// ppTarget:
44
// Out parameter for any target instruction address pointed to by
45
// the instruction. For example, a branch or a jump insruction has
46
// a target, but a load or store instruction doesn't. A target is
47
// another instruction that may be executed as a result of this
48
// instruction. ppTarget may be NULL.
49
// plExtra:
50
// Out parameter for the number of extra bytes needed by the
51
// instruction to reach the target. For example, lExtra = 3 if the
52
// instruction had an 8-bit relative offset, but needs a 32-bit
53
// relative offset.
54
//
55
// Returns:
56
// Returns the address of the next instruction (following in the source)
57
// instruction. By subtracting pSrc from the return value, the caller
58
// can determinte the size of the instruction copied.
59
//
60
// Comments:
61
// By following the pTarget, the caller can follow alternate
62
// instruction streams. However, it is not always possible to determine
63
// the target based on static analysis. For example, the destination of
64
// a jump relative to a register cannot be determined from just the
65
// instruction stream. The output value, pTarget, can have any of the
66
// following outputs:
67
// DETOUR_INSTRUCTION_TARGET_NONE:
68
// The instruction has no targets.
69
// DETOUR_INSTRUCTION_TARGET_DYNAMIC:
70
// The instruction has a non-deterministic (dynamic) target.
71
// (i.e. the jump is to an address held in a register.)
72
// Address: The instruction has the specified target.
73
//
74
// When copying instructions, DetourCopyInstruction insures that any
75
// targets remain constant. It does so by adjusting any IP relative
76
// offsets.
77
//
78
79
PVOID WINAPI DetourCopyInstruction(PVOID pDst, PVOID pSrc, PVOID *ppTarget)
80
{
81
return DetourCopyInstructionEx(pDst, pSrc, ppTarget, NULL);
82
}
83
84
//////////////////////////////////////////////////// X86 and X64 Disassembler.
85
//
86
// Includes full support for all x86 chips prior to the Pentium III.
87
//
88
#if defined(DETOURS_X64) || defined(DETOURS_X86)
89
90
class CDetourDis
91
{
92
public:
93
CDetourDis(PBYTE *ppbTarget, LONG *plExtra);
94
95
PBYTE CopyInstruction(PBYTE pbDst, PBYTE pbSrc);
96
static BOOL SanityCheckSystem();
97
98
public:
99
struct COPYENTRY;
100
typedef const COPYENTRY * REFCOPYENTRY;
101
102
typedef PBYTE (CDetourDis::* COPYFUNC)(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
103
104
enum {
105
DYNAMIC = 0x1u,
106
ADDRESS = 0x2u,
107
NOENLARGE = 0x4u,
108
RAX = 0x8u,
109
110
SIB = 0x10u,
111
RIP = 0x20u,
112
NOTSIB = 0x0fu,
113
};
114
struct COPYENTRY
115
{
116
ULONG nOpcode : 8; // Opcode
117
ULONG nFixedSize : 4; // Fixed size of opcode
118
ULONG nFixedSize16 : 4; // Fixed size when 16 bit operand
119
ULONG nModOffset : 4; // Offset to mod/rm byte (0=none)
120
LONG nRelOffset : 4; // Offset to relative target.
121
LONG nTargetBack : 4; // Offset back to absolute or rip target
122
ULONG nFlagBits : 4; // Flags for DYNAMIC, etc.
123
COPYFUNC pfCopy; // Function pointer.
124
};
125
126
protected:
127
// These macros define common uses of nFixedSize..pfCopy.
128
#define ENTRY_CopyBytes1 1, 1, 0, 0, 0, 0, &CDetourDis::CopyBytes
129
#define ENTRY_CopyBytes1Dynamic 1, 1, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
130
#define ENTRY_CopyBytes2 2, 2, 0, 0, 0, 0, &CDetourDis::CopyBytes
131
#define ENTRY_CopyBytes2Jump 2, 2, 0, 1, 0, 0, &CDetourDis::CopyBytes
132
#define ENTRY_CopyBytes2CantJump 2, 2, 0, 1, 0, NOENLARGE, &CDetourDis::CopyBytes
133
#define ENTRY_CopyBytes2Dynamic 2, 2, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
134
#define ENTRY_CopyBytes3 3, 3, 0, 0, 0, 0, &CDetourDis::CopyBytes
135
#define ENTRY_CopyBytes3Dynamic 3, 3, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
136
#define ENTRY_CopyBytes3Or5 5, 3, 0, 0, 0, 0, &CDetourDis::CopyBytes
137
#define ENTRY_CopyBytes3Or5Rax 5, 3, 0, 0, 0, RAX, &CDetourDis::CopyBytes
138
#define ENTRY_CopyBytes3Or5Target 5, 3, 0, 1, 0, 0, &CDetourDis::CopyBytes
139
#define ENTRY_CopyBytes5Or7Dynamic 7, 5, 0, 0, 0, DYNAMIC, &CDetourDis::CopyBytes
140
#define ENTRY_CopyBytes3Or5Address 5, 3, 0, 0, 0, ADDRESS, &CDetourDis::CopyBytes
141
#define ENTRY_CopyBytes4 4, 4, 0, 0, 0, 0, &CDetourDis::CopyBytes
142
#define ENTRY_CopyBytes5 5, 5, 0, 0, 0, 0, &CDetourDis::CopyBytes
143
#define ENTRY_CopyBytes7 7, 7, 0, 0, 0, 0, &CDetourDis::CopyBytes
144
#define ENTRY_CopyBytes2Mod 2, 2, 1, 0, 0, 0, &CDetourDis::CopyBytes
145
#define ENTRY_CopyBytes2Mod1 3, 3, 1, 0, 1, 0, &CDetourDis::CopyBytes
146
#define ENTRY_CopyBytes2ModOperand 6, 4, 1, 0, 4, 0, &CDetourDis::CopyBytes
147
#define ENTRY_CopyBytes3Mod 3, 3, 2, 0, 0, 0, &CDetourDis::CopyBytes
148
#define ENTRY_CopyBytesPrefix 1, 1, 0, 0, 0, 0, &CDetourDis::CopyBytesPrefix
149
#define ENTRY_CopyBytesRax 1, 1, 0, 0, 0, 0, &CDetourDis::CopyBytesRax
150
#define ENTRY_Copy0F 1, 1, 0, 0, 0, 0, &CDetourDis::Copy0F
151
#define ENTRY_Copy66 1, 1, 0, 0, 0, 0, &CDetourDis::Copy66
152
#define ENTRY_Copy67 1, 1, 0, 0, 0, 0, &CDetourDis::Copy67
153
#define ENTRY_CopyF6 0, 0, 0, 0, 0, 0, &CDetourDis::CopyF6
154
#define ENTRY_CopyF7 0, 0, 0, 0, 0, 0, &CDetourDis::CopyF7
155
#define ENTRY_CopyFF 0, 0, 0, 0, 0, 0, &CDetourDis::CopyFF
156
#define ENTRY_Invalid 1, 1, 0, 0, 0, 0, &CDetourDis::Invalid
157
#define ENTRY_End 0, 0, 0, 0, 0, 0, NULL
158
159
PBYTE CopyBytes(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
160
PBYTE CopyBytesPrefix(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
161
PBYTE CopyBytesRax(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
162
163
PBYTE Invalid(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
164
165
PBYTE AdjustTarget(PBYTE pbDst, PBYTE pbSrc, LONG cbOp,
166
LONG cbTargetOffset, LONG cbTargetSize);
167
168
protected:
169
PBYTE Copy0F(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
170
PBYTE Copy66(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
171
PBYTE Copy67(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
172
PBYTE CopyF6(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
173
PBYTE CopyF7(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
174
PBYTE CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc);
175
176
protected:
177
static const COPYENTRY s_rceCopyTable[257];
178
static const COPYENTRY s_rceCopyTable0F[257];
179
static const BYTE s_rbModRm[256];
180
181
protected:
182
BOOL m_bOperandOverride;
183
BOOL m_bAddressOverride;
184
BOOL m_bRaxOverride;
185
186
PBYTE * m_ppbTarget;
187
LONG * m_plExtra;
188
189
LONG m_lScratchExtra;
190
PBYTE m_pbScratchTarget;
191
BYTE m_rbScratchDst[64];
192
};
193
194
PVOID WINAPI DetourCopyInstructionEx(PVOID pDst,
195
PVOID pSrc,
196
PVOID *ppTarget,
197
LONG *plExtra)
198
{
199
CDetourDis oDetourDisasm((PBYTE*)ppTarget, plExtra);
200
return oDetourDisasm.CopyInstruction((PBYTE)pDst, (PBYTE)pSrc);
201
}
202
203
/////////////////////////////////////////////////////////// Disassembler Code.
204
//
205
CDetourDis::CDetourDis(PBYTE *ppbTarget, LONG *plExtra)
206
{
207
m_bOperandOverride = FALSE;
208
m_bAddressOverride = FALSE;
209
m_bRaxOverride = FALSE;
210
211
m_ppbTarget = ppbTarget ? ppbTarget : &m_pbScratchTarget;
212
m_plExtra = plExtra ? plExtra : &m_lScratchExtra;
213
214
*m_ppbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_NONE;
215
*m_plExtra = 0;
216
}
217
218
PBYTE CDetourDis::CopyInstruction(PBYTE pbDst, PBYTE pbSrc)
219
{
220
// Configure scratch areas if real areas are not available.
221
if (NULL == pbDst) {
222
pbDst = m_rbScratchDst;
223
}
224
if (NULL == pbSrc) {
225
// We can't copy a non-existent instruction.
226
SetLastError(ERROR_INVALID_DATA);
227
return NULL;
228
}
229
230
// Figure out how big the instruction is, do the appropriate copy,
231
// and figure out what the target of the instruction is if any.
232
//
233
REFCOPYENTRY pEntry = &s_rceCopyTable[pbSrc[0]];
234
return (this->*pEntry->pfCopy)(pEntry, pbDst, pbSrc);
235
}
236
237
PBYTE CDetourDis::CopyBytes(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
238
{
239
#ifdef DETOURS_X64
240
#error Feature not supported in this release.
241
242
243
244
245
#else
246
LONG nBytesFixed = (pEntry->nFlagBits & ADDRESS)
247
? (m_bAddressOverride ? pEntry->nFixedSize16 : pEntry->nFixedSize)
248
: (m_bOperandOverride ? pEntry->nFixedSize16 : pEntry->nFixedSize);
249
#endif
250
251
LONG nBytes = nBytesFixed;
252
LONG nRelOffset = pEntry->nRelOffset;
253
LONG cbTarget = nBytes - nRelOffset;
254
if (pEntry->nModOffset > 0) {
255
BYTE bModRm = pbSrc[pEntry->nModOffset];
256
BYTE bFlags = s_rbModRm[bModRm];
257
258
nBytes += bFlags & NOTSIB;
259
260
if (bFlags & SIB) {
261
BYTE bSib = pbSrc[pEntry->nModOffset + 1];
262
263
if ((bSib & 0x07) == 0x05) {
264
if ((bModRm & 0xc0) == 0x00) {
265
nBytes += 4;
266
}
267
else if ((bModRm & 0xc0) == 0x40) {
268
nBytes += 1;
269
}
270
else if ((bModRm & 0xc0) == 0x80) {
271
nBytes += 4;
272
}
273
}
274
cbTarget = nBytes - nRelOffset;
275
}
276
else if (bFlags & RIP) {
277
#ifdef DETOURS_X64
278
#error Feature not supported in this release.
279
280
281
#endif
282
}
283
}
284
CopyMemory(pbDst, pbSrc, nBytes);
285
286
if (nRelOffset) {
287
*m_ppbTarget = AdjustTarget(pbDst, pbSrc, nBytesFixed, nRelOffset, cbTarget);
288
#ifdef DETOURS_X64
289
#error Feature not supported in this release.
290
291
292
293
#endif
294
}
295
if (pEntry->nFlagBits & NOENLARGE) {
296
*m_plExtra = -*m_plExtra;
297
}
298
if (pEntry->nFlagBits & DYNAMIC) {
299
*m_ppbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;
300
}
301
return pbSrc + nBytes;
302
}
303
304
PBYTE CDetourDis::CopyBytesPrefix(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
305
{
306
CopyBytes(pEntry, pbDst, pbSrc);
307
308
pEntry = &s_rceCopyTable[pbSrc[1]];
309
return (this->*pEntry->pfCopy)(pEntry, pbDst + 1, pbSrc + 1);
310
}
311
312
PBYTE CDetourDis::CopyBytesRax(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
313
{
314
CopyBytes(pEntry, pbDst, pbSrc);
315
316
if (*pbSrc & 0x8) {
317
m_bRaxOverride = TRUE;
318
}
319
320
pEntry = &s_rceCopyTable[pbSrc[1]];
321
return (this->*pEntry->pfCopy)(pEntry, pbDst + 1, pbSrc + 1);
322
}
323
324
PBYTE CDetourDis::AdjustTarget(PBYTE pbDst, PBYTE pbSrc, LONG cbOp,
325
LONG cbTargetOffset, LONG cbTargetSize)
326
{
327
PBYTE pbTarget = NULL;
328
PVOID pvTargetAddr = &pbDst[cbTargetOffset];
329
LONG_PTR nOldOffset = 0;
330
331
switch (cbTargetSize) {
332
case 1:
333
nOldOffset = (LONG_PTR)*(CHAR*&)pvTargetAddr;
334
break;
335
case 2:
336
nOldOffset = (LONG_PTR)*(SHORT*&)pvTargetAddr;
337
break;
338
case 4:
339
nOldOffset = (LONG_PTR)*(LONG*&)pvTargetAddr;
340
break;
341
case 8:
342
nOldOffset = (LONG_PTR)*(LONG_PTR*&)pvTargetAddr;
343
break;
344
default:
345
ASSERT(!"cbTargetSize is invalid.");
346
break;
347
}
348
349
pbTarget = pbSrc + cbOp + nOldOffset;
350
LONG_PTR nNewOffset = nOldOffset - (pbDst - pbSrc);
351
352
switch (cbTargetSize) {
353
case 1:
354
*(CHAR*&)pvTargetAddr = (CHAR)nNewOffset;
355
if (nNewOffset < SCHAR_MIN || nNewOffset > SCHAR_MAX) {
356
*m_plExtra = sizeof(ULONG_PTR) - 1;
357
}
358
break;
359
case 2:
360
*(SHORT*&)pvTargetAddr = (SHORT)nNewOffset;
361
if (nNewOffset < SHRT_MIN || nNewOffset > SHRT_MAX) {
362
*m_plExtra = sizeof(ULONG_PTR) - 2;
363
}
364
break;
365
case 4:
366
*(LONG*&)pvTargetAddr = (LONG)nNewOffset;
367
if (nNewOffset < LONG_MIN || nNewOffset > LONG_MAX) {
368
*m_plExtra = sizeof(ULONG_PTR) - 4;
369
}
370
break;
371
case 8:
372
*(LONG_PTR*&)pvTargetAddr = (LONG_PTR)nNewOffset;
373
break;
374
}
375
ASSERT(pbDst + cbOp + nNewOffset == pbTarget);
376
return pbTarget;
377
}
378
379
PBYTE CDetourDis::Invalid(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
380
{
381
(void)pbDst;
382
(void)pEntry;
383
ASSERT(!"Invalid Instruction");
384
return pbSrc + 1;
385
}
386
387
////////////////////////////////////////////////////// Individual Bytes Codes.
388
//
389
PBYTE CDetourDis::Copy0F(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
390
{
391
CopyBytes(pEntry, pbDst, pbSrc);
392
393
pEntry = &s_rceCopyTable0F[pbSrc[1]];
394
return (this->*pEntry->pfCopy)(pEntry, pbDst + 1, pbSrc + 1);
395
}
396
397
PBYTE CDetourDis::Copy66(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
398
{ // Operand-size override prefix
399
m_bOperandOverride = TRUE;
400
return CopyBytesPrefix(pEntry, pbDst, pbSrc);
401
}
402
403
PBYTE CDetourDis::Copy67(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
404
{ // Address size override prefix
405
m_bAddressOverride = TRUE;
406
return CopyBytesPrefix(pEntry, pbDst, pbSrc);
407
}
408
409
PBYTE CDetourDis::CopyF6(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
410
{
411
(void)pEntry;
412
413
// TEST BYTE /0
414
if (0x00 == (0x38 & pbSrc[1])) { // reg(bits 543) of ModR/M == 0
415
const COPYENTRY ce = { 0xf6, ENTRY_CopyBytes2Mod1 };
416
return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);
417
}
418
// DIV /6
419
// IDIV /7
420
// IMUL /5
421
// MUL /4
422
// NEG /3
423
// NOT /2
424
425
const COPYENTRY ce = { 0xf6, ENTRY_CopyBytes2Mod };
426
return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);
427
}
428
429
PBYTE CDetourDis::CopyF7(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
430
{
431
(void)pEntry;
432
433
// TEST WORD /0
434
if (0x00 == (0x38 & pbSrc[1])) { // reg(bits 543) of ModR/M == 0
435
const COPYENTRY ce = { 0xf7, ENTRY_CopyBytes2ModOperand };
436
return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);
437
}
438
439
// DIV /6
440
// IDIV /7
441
// IMUL /5
442
// MUL /4
443
// NEG /3
444
// NOT /2
445
const COPYENTRY ce = { 0xf7, ENTRY_CopyBytes2Mod };
446
return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);
447
}
448
449
PBYTE CDetourDis::CopyFF(REFCOPYENTRY pEntry, PBYTE pbDst, PBYTE pbSrc)
450
{ // CALL /2
451
// CALL /3
452
// INC /0
453
// JMP /4
454
// JMP /5
455
// PUSH /6
456
(void)pEntry;
457
458
if (0x15 == pbSrc[1] || 0x25 == pbSrc[1]) { // CALL [], JMP []
459
#ifdef DETOURS_X64
460
#error Feature not supported in this release.
461
462
463
#else
464
PBYTE *ppbTarget = *(PBYTE**)&pbSrc[2];
465
*m_ppbTarget = *ppbTarget;
466
#endif
467
}
468
else if (0x10 == (0x38 & pbSrc[1]) || // CALL /2 --> reg(bits 543) of ModR/M == 010
469
0x18 == (0x38 & pbSrc[1]) || // CALL /3 --> reg(bits 543) of ModR/M == 011
470
0x20 == (0x38 & pbSrc[1]) || // JMP /4 --> reg(bits 543) of ModR/M == 100
471
0x28 == (0x38 & pbSrc[1]) // JMP /5 --> reg(bits 543) of ModR/M == 101
472
) {
473
*m_ppbTarget = (PBYTE)DETOUR_INSTRUCTION_TARGET_DYNAMIC;
474
}
475
const COPYENTRY ce = { 0xff, ENTRY_CopyBytes2Mod };
476
return (this->*ce.pfCopy)(&ce, pbDst, pbSrc);
477
}
478
479
///////////////////////////////////////////////////////// Disassembler Tables.
480
//
481
const BYTE CDetourDis::s_rbModRm[256] = {
482
0,0,0,0, SIB|1,RIP|4,0,0, 0,0,0,0, SIB|1,RIP|4,0,0, // 0x
483
0,0,0,0, SIB|1,RIP|4,0,0, 0,0,0,0, SIB|1,RIP|4,0,0, // 1x
484
0,0,0,0, SIB|1,RIP|4,0,0, 0,0,0,0, SIB|1,RIP|4,0,0, // 2x
485
0,0,0,0, SIB|1,RIP|4,0,0, 0,0,0,0, SIB|1,RIP|4,0,0, // 3x
486
1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 4x
487
1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 5x
488
1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 6x
489
1,1,1,1, 2,1,1,1, 1,1,1,1, 2,1,1,1, // 7x
490
4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // 8x
491
4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // 9x
492
4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // Ax
493
4,4,4,4, 5,4,4,4, 4,4,4,4, 5,4,4,4, // Bx
494
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // Cx
495
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // Dx
496
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // Ex
497
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 // Fx
498
};
499
500
const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable[257] =
501
{
502
{ 0x00, ENTRY_CopyBytes2Mod }, // ADD /r
503
{ 0x01, ENTRY_CopyBytes2Mod }, // ADD /r
504
{ 0x02, ENTRY_CopyBytes2Mod }, // ADD /r
505
{ 0x03, ENTRY_CopyBytes2Mod }, // ADD /r
506
{ 0x04, ENTRY_CopyBytes2 }, // ADD ib
507
{ 0x05, ENTRY_CopyBytes3Or5 }, // ADD iw
508
{ 0x06, ENTRY_CopyBytes1 }, // PUSH
509
{ 0x07, ENTRY_CopyBytes1 }, // POP
510
{ 0x08, ENTRY_CopyBytes2Mod }, // OR /r
511
{ 0x09, ENTRY_CopyBytes2Mod }, // OR /r
512
{ 0x0A, ENTRY_CopyBytes2Mod }, // OR /r
513
{ 0x0B, ENTRY_CopyBytes2Mod }, // OR /r
514
{ 0x0C, ENTRY_CopyBytes2 }, // OR ib
515
{ 0x0D, ENTRY_CopyBytes3Or5 }, // OR iw
516
{ 0x0E, ENTRY_CopyBytes1 }, // PUSH
517
{ 0x0F, ENTRY_Copy0F }, // Extension Ops
518
{ 0x10, ENTRY_CopyBytes2Mod }, // ADC /r
519
{ 0x11, ENTRY_CopyBytes2Mod }, // ADC /r
520
{ 0x12, ENTRY_CopyBytes2Mod }, // ADC /r
521
{ 0x13, ENTRY_CopyBytes2Mod }, // ADC /r
522
{ 0x14, ENTRY_CopyBytes2 }, // ADC ib
523
{ 0x15, ENTRY_CopyBytes3Or5 }, // ADC id
524
{ 0x16, ENTRY_CopyBytes1 }, // PUSH
525
{ 0x17, ENTRY_CopyBytes1 }, // POP
526
{ 0x18, ENTRY_CopyBytes2Mod }, // SBB /r
527
{ 0x19, ENTRY_CopyBytes2Mod }, // SBB /r
528
{ 0x1A, ENTRY_CopyBytes2Mod }, // SBB /r
529
{ 0x1B, ENTRY_CopyBytes2Mod }, // SBB /r
530
{ 0x1C, ENTRY_CopyBytes2 }, // SBB ib
531
{ 0x1D, ENTRY_CopyBytes3Or5 }, // SBB id
532
{ 0x1E, ENTRY_CopyBytes1 }, // PUSH
533
{ 0x1F, ENTRY_CopyBytes1 }, // POP
534
{ 0x20, ENTRY_CopyBytes2Mod }, // AND /r
535
{ 0x21, ENTRY_CopyBytes2Mod }, // AND /r
536
{ 0x22, ENTRY_CopyBytes2Mod }, // AND /r
537
{ 0x23, ENTRY_CopyBytes2Mod }, // AND /r
538
{ 0x24, ENTRY_CopyBytes2 }, // AND ib
539
{ 0x25, ENTRY_CopyBytes3Or5 }, // AND id
540
{ 0x26, ENTRY_CopyBytesPrefix }, // ES prefix
541
{ 0x27, ENTRY_CopyBytes1 }, // DAA
542
{ 0x28, ENTRY_CopyBytes2Mod }, // SUB /r
543
{ 0x29, ENTRY_CopyBytes2Mod }, // SUB /r
544
{ 0x2A, ENTRY_CopyBytes2Mod }, // SUB /r
545
{ 0x2B, ENTRY_CopyBytes2Mod }, // SUB /r
546
{ 0x2C, ENTRY_CopyBytes2 }, // SUB ib
547
{ 0x2D, ENTRY_CopyBytes3Or5 }, // SUB id
548
{ 0x2E, ENTRY_CopyBytesPrefix }, // CS prefix
549
{ 0x2F, ENTRY_CopyBytes1 }, // DAS
550
{ 0x30, ENTRY_CopyBytes2Mod }, // XOR /r
551
{ 0x31, ENTRY_CopyBytes2Mod }, // XOR /r
552
{ 0x32, ENTRY_CopyBytes2Mod }, // XOR /r
553
{ 0x33, ENTRY_CopyBytes2Mod }, // XOR /r
554
{ 0x34, ENTRY_CopyBytes2 }, // XOR ib
555
{ 0x35, ENTRY_CopyBytes3Or5 }, // XOR id
556
{ 0x36, ENTRY_CopyBytesPrefix }, // SS prefix
557
{ 0x37, ENTRY_CopyBytes1 }, // AAA
558
{ 0x38, ENTRY_CopyBytes2Mod }, // CMP /r
559
{ 0x39, ENTRY_CopyBytes2Mod }, // CMP /r
560
{ 0x3A, ENTRY_CopyBytes2Mod }, // CMP /r
561
{ 0x3B, ENTRY_CopyBytes2Mod }, // CMP /r
562
{ 0x3C, ENTRY_CopyBytes2 }, // CMP ib
563
{ 0x3D, ENTRY_CopyBytes3Or5 }, // CMP id
564
{ 0x3E, ENTRY_CopyBytesPrefix }, // DS prefix
565
{ 0x3F, ENTRY_CopyBytes1 }, // AAS
566
#ifdef DETOURS_X64 // For Rax Prefix
567
#error Feature not supported in this release.
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
#else
584
{ 0x40, ENTRY_CopyBytes1 }, // INC
585
{ 0x41, ENTRY_CopyBytes1 }, // INC
586
{ 0x42, ENTRY_CopyBytes1 }, // INC
587
{ 0x43, ENTRY_CopyBytes1 }, // INC
588
{ 0x44, ENTRY_CopyBytes1 }, // INC
589
{ 0x45, ENTRY_CopyBytes1 }, // INC
590
{ 0x46, ENTRY_CopyBytes1 }, // INC
591
{ 0x47, ENTRY_CopyBytes1 }, // INC
592
{ 0x48, ENTRY_CopyBytes1 }, // DEC
593
{ 0x49, ENTRY_CopyBytes1 }, // DEC
594
{ 0x4A, ENTRY_CopyBytes1 }, // DEC
595
{ 0x4B, ENTRY_CopyBytes1 }, // DEC
596
{ 0x4C, ENTRY_CopyBytes1 }, // DEC
597
{ 0x4D, ENTRY_CopyBytes1 }, // DEC
598
{ 0x4E, ENTRY_CopyBytes1 }, // DEC
599
{ 0x4F, ENTRY_CopyBytes1 }, // DEC
600
#endif
601
{ 0x50, ENTRY_CopyBytes1 }, // PUSH
602
{ 0x51, ENTRY_CopyBytes1 }, // PUSH
603
{ 0x52, ENTRY_CopyBytes1 }, // PUSH
604
{ 0x53, ENTRY_CopyBytes1 }, // PUSH
605
{ 0x54, ENTRY_CopyBytes1 }, // PUSH
606
{ 0x55, ENTRY_CopyBytes1 }, // PUSH
607
{ 0x56, ENTRY_CopyBytes1 }, // PUSH
608
{ 0x57, ENTRY_CopyBytes1 }, // PUSH
609
{ 0x58, ENTRY_CopyBytes1 }, // POP
610
{ 0x59, ENTRY_CopyBytes1 }, // POP
611
{ 0x5A, ENTRY_CopyBytes1 }, // POP
612
{ 0x5B, ENTRY_CopyBytes1 }, // POP
613
{ 0x5C, ENTRY_CopyBytes1 }, // POP
614
{ 0x5D, ENTRY_CopyBytes1 }, // POP
615
{ 0x5E, ENTRY_CopyBytes1 }, // POP
616
{ 0x5F, ENTRY_CopyBytes1 }, // POP
617
{ 0x60, ENTRY_CopyBytes1 }, // PUSHAD
618
{ 0x61, ENTRY_CopyBytes1 }, // POPAD
619
{ 0x62, ENTRY_CopyBytes2Mod }, // BOUND /r
620
{ 0x63, ENTRY_CopyBytes2Mod }, // ARPL /r
621
{ 0x64, ENTRY_CopyBytesPrefix }, // FS prefix
622
{ 0x65, ENTRY_CopyBytesPrefix }, // GS prefix
623
{ 0x66, ENTRY_Copy66 }, // Operand Prefix
624
{ 0x67, ENTRY_Copy67 }, // Address Prefix
625
{ 0x68, ENTRY_CopyBytes3Or5 }, // PUSH
626
{ 0x69, ENTRY_CopyBytes2ModOperand }, //
627
{ 0x6A, ENTRY_CopyBytes2 }, // PUSH
628
{ 0x6B, ENTRY_CopyBytes2Mod1 }, // IMUL /r ib
629
{ 0x6C, ENTRY_CopyBytes1 }, // INS
630
{ 0x6D, ENTRY_CopyBytes1 }, // INS
631
{ 0x6E, ENTRY_CopyBytes1 }, // OUTS/OUTSB
632
{ 0x6F, ENTRY_CopyBytes1 }, // OUTS/OUTSW
633
{ 0x70, ENTRY_CopyBytes2Jump }, // JO
634
{ 0x71, ENTRY_CopyBytes2Jump }, // JNO
635
{ 0x72, ENTRY_CopyBytes2Jump }, // JB/JC/JNAE
636
{ 0x73, ENTRY_CopyBytes2Jump }, // JAE/JNB/JNC
637
{ 0x74, ENTRY_CopyBytes2Jump }, // JE/JZ
638
{ 0x75, ENTRY_CopyBytes2Jump }, // JNE/JNZ
639
{ 0x76, ENTRY_CopyBytes2Jump }, // JBE/JNA
640
{ 0x77, ENTRY_CopyBytes2Jump }, // JA/JNBE
641
{ 0x78, ENTRY_CopyBytes2Jump }, // JS
642
{ 0x79, ENTRY_CopyBytes2Jump }, // JNS
643
{ 0x7A, ENTRY_CopyBytes2Jump }, // JP/JPE
644
{ 0x7B, ENTRY_CopyBytes2Jump }, // JNP/JPO
645
{ 0x7C, ENTRY_CopyBytes2Jump }, // JL/JNGE
646
{ 0x7D, ENTRY_CopyBytes2Jump }, // JGE/JNL
647
{ 0x7E, ENTRY_CopyBytes2Jump }, // JLE/JNG
648
{ 0x7F, ENTRY_CopyBytes2Jump }, // JG/JNLE
649
{ 0x80, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc.s
650
{ 0x81, ENTRY_CopyBytes2ModOperand }, //
651
{ 0x82, ENTRY_CopyBytes2 }, // MOV al,x
652
{ 0x83, ENTRY_CopyBytes2Mod1 }, // ADC/2 ib, etc.
653
{ 0x84, ENTRY_CopyBytes2Mod }, // TEST /r
654
{ 0x85, ENTRY_CopyBytes2Mod }, // TEST /r
655
{ 0x86, ENTRY_CopyBytes2Mod }, // XCHG /r @todo
656
{ 0x87, ENTRY_CopyBytes2Mod }, // XCHG /r @todo
657
{ 0x88, ENTRY_CopyBytes2Mod }, // MOV /r
658
{ 0x89, ENTRY_CopyBytes2Mod }, // MOV /r
659
{ 0x8A, ENTRY_CopyBytes2Mod }, // MOV /r
660
{ 0x8B, ENTRY_CopyBytes2Mod }, // MOV /r
661
{ 0x8C, ENTRY_CopyBytes2Mod }, // MOV /r
662
{ 0x8D, ENTRY_CopyBytes2Mod }, // LEA /r
663
{ 0x8E, ENTRY_CopyBytes2Mod }, // MOV /r
664
{ 0x8F, ENTRY_CopyBytes2Mod }, // POP /0
665
{ 0x90, ENTRY_CopyBytes1 }, // NOP
666
{ 0x91, ENTRY_CopyBytes1 }, // XCHG
667
{ 0x92, ENTRY_CopyBytes1 }, // XCHG
668
{ 0x93, ENTRY_CopyBytes1 }, // XCHG
669
{ 0x94, ENTRY_CopyBytes1 }, // XCHG
670
{ 0x95, ENTRY_CopyBytes1 }, // XCHG
671
{ 0x96, ENTRY_CopyBytes1 }, // XCHG
672
{ 0x97, ENTRY_CopyBytes1 }, // XCHG
673
{ 0x98, ENTRY_CopyBytes1 }, // CWDE
674
{ 0x99, ENTRY_CopyBytes1 }, // CDQ
675
{ 0x9A, ENTRY_CopyBytes5Or7Dynamic }, // CALL cp
676
{ 0x9B, ENTRY_CopyBytes1 }, // WAIT/FWAIT
677
{ 0x9C, ENTRY_CopyBytes1 }, // PUSHFD
678
{ 0x9D, ENTRY_CopyBytes1 }, // POPFD
679
{ 0x9E, ENTRY_CopyBytes1 }, // SAHF
680
{ 0x9F, ENTRY_CopyBytes1 }, // LAHF
681
{ 0xA0, ENTRY_CopyBytes3Or5Address }, // MOV
682
{ 0xA1, ENTRY_CopyBytes3Or5Address }, // MOV
683
{ 0xA2, ENTRY_CopyBytes3Or5Address }, // MOV
684
{ 0xA3, ENTRY_CopyBytes3Or5Address }, // MOV
685
{ 0xA4, ENTRY_CopyBytes1 }, // MOVS
686
{ 0xA5, ENTRY_CopyBytes1 }, // MOVS/MOVSD
687
{ 0xA6, ENTRY_CopyBytes1 }, // CMPS/CMPSB
688
{ 0xA7, ENTRY_CopyBytes1 }, // CMPS/CMPSW
689
{ 0xA8, ENTRY_CopyBytes2 }, // TEST
690
{ 0xA9, ENTRY_CopyBytes3Or5 }, // TEST
691
{ 0xAA, ENTRY_CopyBytes1 }, // STOS/STOSB
692
{ 0xAB, ENTRY_CopyBytes1 }, // STOS/STOSW
693
{ 0xAC, ENTRY_CopyBytes1 }, // LODS/LODSB
694
{ 0xAD, ENTRY_CopyBytes1 }, // LODS/LODSW
695
{ 0xAE, ENTRY_CopyBytes1 }, // SCAS/SCASB
696
{ 0xAF, ENTRY_CopyBytes1 }, // SCAS/SCASD
697
{ 0xB0, ENTRY_CopyBytes2 }, // MOV B0+rb
698
{ 0xB1, ENTRY_CopyBytes2 }, // MOV B0+rb
699
{ 0xB2, ENTRY_CopyBytes2 }, // MOV B0+rb
700
{ 0xB3, ENTRY_CopyBytes2 }, // MOV B0+rb
701
{ 0xB4, ENTRY_CopyBytes2 }, // MOV B0+rb
702
{ 0xB5, ENTRY_CopyBytes2 }, // MOV B0+rb
703
{ 0xB6, ENTRY_CopyBytes2 }, // MOV B0+rb
704
{ 0xB7, ENTRY_CopyBytes2 }, // MOV B0+rb
705
{ 0xB8, ENTRY_CopyBytes3Or5Rax }, // MOV B8+rb
706
{ 0xB9, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
707
{ 0xBA, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
708
{ 0xBB, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
709
{ 0xBC, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
710
{ 0xBD, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
711
{ 0xBE, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
712
{ 0xBF, ENTRY_CopyBytes3Or5 }, // MOV B8+rb
713
{ 0xC0, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc.
714
{ 0xC1, ENTRY_CopyBytes2Mod1 }, // RCL/2 ib, etc.
715
{ 0xC2, ENTRY_CopyBytes3 }, // RET
716
{ 0xC3, ENTRY_CopyBytes1 }, // RET
717
{ 0xC4, ENTRY_CopyBytes2Mod }, // LES
718
{ 0xC5, ENTRY_CopyBytes2Mod }, // LDS
719
{ 0xC6, ENTRY_CopyBytes2Mod1 }, // MOV
720
{ 0xC7, ENTRY_CopyBytes2ModOperand }, // MOV
721
{ 0xC8, ENTRY_CopyBytes4 }, // ENTER
722
{ 0xC9, ENTRY_CopyBytes1 }, // LEAVE
723
{ 0xCA, ENTRY_CopyBytes3Dynamic }, // RET
724
{ 0xCB, ENTRY_CopyBytes1Dynamic }, // RET
725
{ 0xCC, ENTRY_CopyBytes1Dynamic }, // INT 3
726
{ 0xCD, ENTRY_CopyBytes2Dynamic }, // INT ib
727
{ 0xCE, ENTRY_CopyBytes1Dynamic }, // INTO
728
{ 0xCF, ENTRY_CopyBytes1Dynamic }, // IRET
729
{ 0xD0, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
730
{ 0xD1, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
731
{ 0xD2, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
732
{ 0xD3, ENTRY_CopyBytes2Mod }, // RCL/2, etc.
733
{ 0xD4, ENTRY_CopyBytes2 }, // AAM
734
{ 0xD5, ENTRY_CopyBytes2 }, // AAD
735
{ 0xD6, ENTRY_Invalid }, //
736
{ 0xD7, ENTRY_CopyBytes1 }, // XLAT/XLATB
737
{ 0xD8, ENTRY_CopyBytes2Mod }, // FADD, etc.
738
{ 0xD9, ENTRY_CopyBytes2Mod }, // F2XM1, etc.
739
{ 0xDA, ENTRY_CopyBytes2Mod }, // FLADD, etc.
740
{ 0xDB, ENTRY_CopyBytes2Mod }, // FCLEX, etc.
741
{ 0xDC, ENTRY_CopyBytes2Mod }, // FADD/0, etc.
742
{ 0xDD, ENTRY_CopyBytes2Mod }, // FFREE, etc.
743
{ 0xDE, ENTRY_CopyBytes2Mod }, // FADDP, etc.
744
{ 0xDF, ENTRY_CopyBytes2Mod }, // FBLD/4, etc.
745
{ 0xE0, ENTRY_CopyBytes2CantJump }, // LOOPNE cb
746
{ 0xE1, ENTRY_CopyBytes2CantJump }, // LOOPE cb
747
{ 0xE2, ENTRY_CopyBytes2CantJump }, // LOOP cb
748
{ 0xE3, ENTRY_CopyBytes2Jump }, // JCXZ/JECXZ
749
{ 0xE4, ENTRY_CopyBytes2 }, // IN ib
750
{ 0xE5, ENTRY_CopyBytes2 }, // IN id
751
{ 0xE6, ENTRY_CopyBytes2 }, // OUT ib
752
{ 0xE7, ENTRY_CopyBytes2 }, // OUT ib
753
{ 0xE8, ENTRY_CopyBytes3Or5Target }, // CALL cd
754
{ 0xE9, ENTRY_CopyBytes3Or5Target }, // JMP cd
755
{ 0xEA, ENTRY_CopyBytes5Or7Dynamic }, // JMP cp
756
{ 0xEB, ENTRY_CopyBytes2Jump }, // JMP cb
757
{ 0xEC, ENTRY_CopyBytes1 }, // IN ib
758
{ 0xED, ENTRY_CopyBytes1 }, // IN id
759
{ 0xEE, ENTRY_CopyBytes1 }, // OUT
760
{ 0xEF, ENTRY_CopyBytes1 }, // OUT
761
{ 0xF0, ENTRY_CopyBytesPrefix }, // LOCK prefix
762
{ 0xF1, ENTRY_Invalid }, //
763
{ 0xF2, ENTRY_CopyBytesPrefix }, // REPNE prefix
764
{ 0xF3, ENTRY_CopyBytesPrefix }, // REPE prefix
765
{ 0xF4, ENTRY_CopyBytes1 }, // HLT
766
{ 0xF5, ENTRY_CopyBytes1 }, // CMC
767
{ 0xF6, ENTRY_CopyF6 }, // TEST/0, DIV/6
768
{ 0xF7, ENTRY_CopyF7 }, // TEST/0, DIV/6
769
{ 0xF8, ENTRY_CopyBytes1 }, // CLC
770
{ 0xF9, ENTRY_CopyBytes1 }, // STC
771
{ 0xFA, ENTRY_CopyBytes1 }, // CLI
772
{ 0xFB, ENTRY_CopyBytes1 }, // STI
773
{ 0xFC, ENTRY_CopyBytes1 }, // CLD
774
{ 0xFD, ENTRY_CopyBytes1 }, // STD
775
{ 0xFE, ENTRY_CopyBytes2Mod }, // DEC/1,INC/0
776
{ 0xFF, ENTRY_CopyFF }, // CALL/2
777
{ 0, ENTRY_End },
778
};
779
780
const CDetourDis::COPYENTRY CDetourDis::s_rceCopyTable0F[257] =
781
{
782
{ 0x00, ENTRY_CopyBytes2Mod }, // LLDT/2, etc.
783
{ 0x01, ENTRY_CopyBytes2Mod }, // INVLPG/7, etc.
784
{ 0x02, ENTRY_CopyBytes2Mod }, // LAR/r
785
{ 0x03, ENTRY_CopyBytes2Mod }, // LSL/r
786
{ 0x04, ENTRY_Invalid }, // _04
787
{ 0x05, ENTRY_Invalid }, // _05
788
{ 0x06, ENTRY_CopyBytes2 }, // CLTS
789
{ 0x07, ENTRY_Invalid }, // _07
790
{ 0x08, ENTRY_CopyBytes2 }, // INVD
791
{ 0x09, ENTRY_CopyBytes2 }, // WBINVD
792
{ 0x0A, ENTRY_Invalid }, // _0A
793
{ 0x0B, ENTRY_CopyBytes2 }, // UD2
794
{ 0x0C, ENTRY_Invalid }, // _0C
795
{ 0x0D, ENTRY_CopyBytes2Mod }, // PREFETCH
796
{ 0x0E, ENTRY_CopyBytes2 }, // FEMMS
797
{ 0x0F, ENTRY_CopyBytes3Mod }, // 3DNow Opcodes
798
{ 0x10, ENTRY_CopyBytes2Mod }, // MOVSS MOVUPD MOVSD
799
{ 0x11, ENTRY_CopyBytes2Mod }, // MOVSS MOVUPD MOVSD
800
{ 0x12, ENTRY_CopyBytes2Mod }, // MOVLPD
801
{ 0x13, ENTRY_CopyBytes2Mod }, // MOVLPD
802
{ 0x14, ENTRY_CopyBytes2Mod }, // UNPCKLPD
803
{ 0x15, ENTRY_CopyBytes2Mod }, // UNPCKHPD
804
{ 0x16, ENTRY_CopyBytes2Mod }, // MOVHPD
805
{ 0x17, ENTRY_CopyBytes2Mod }, // MOVHPD
806
{ 0x18, ENTRY_CopyBytes2Mod }, // PREFETCHINTA...
807
{ 0x19, ENTRY_Invalid }, // _19
808
{ 0x1A, ENTRY_Invalid }, // _1A
809
{ 0x1B, ENTRY_Invalid }, // _1B
810
{ 0x1C, ENTRY_Invalid }, // _1C
811
{ 0x1D, ENTRY_Invalid }, // _1D
812
{ 0x1E, ENTRY_Invalid }, // _1E
813
{ 0x1F, ENTRY_Invalid }, // _1F
814
{ 0x20, ENTRY_CopyBytes2Mod }, // MOV/r
815
{ 0x21, ENTRY_CopyBytes2Mod }, // MOV/r
816
{ 0x22, ENTRY_CopyBytes2Mod }, // MOV/r
817
{ 0x23, ENTRY_CopyBytes2Mod }, // MOV/r
818
{ 0x24, ENTRY_Invalid }, // _24
819
{ 0x25, ENTRY_Invalid }, // _25
820
{ 0x26, ENTRY_Invalid }, // _26
821
{ 0x27, ENTRY_Invalid }, // _27
822
{ 0x28, ENTRY_CopyBytes2Mod }, // MOVAPS MOVAPD
823
{ 0x29, ENTRY_CopyBytes2Mod }, // MOVAPS MOVAPD
824
{ 0x2A, ENTRY_CopyBytes2Mod }, // CVPI2PS &
825
{ 0x2B, ENTRY_CopyBytes2Mod }, // MOVNTPS MOVNTPD
826
{ 0x2C, ENTRY_CopyBytes2Mod }, // CVTTPS2PI &
827
{ 0x2D, ENTRY_CopyBytes2Mod }, // CVTPS2PI &
828
{ 0x2E, ENTRY_CopyBytes2Mod }, // UCOMISS UCOMISD
829
{ 0x2F, ENTRY_CopyBytes2Mod }, // COMISS COMISD
830
{ 0x30, ENTRY_CopyBytes2 }, // WRMSR
831
{ 0x31, ENTRY_CopyBytes2 }, // RDTSC
832
{ 0x32, ENTRY_CopyBytes2 }, // RDMSR
833
{ 0x33, ENTRY_CopyBytes2 }, // RDPMC
834
{ 0x34, ENTRY_CopyBytes2 }, // SYSENTER
835
{ 0x35, ENTRY_CopyBytes2 }, // SYSEXIT
836
{ 0x36, ENTRY_Invalid }, // _36
837
{ 0x37, ENTRY_Invalid }, // _37
838
{ 0x38, ENTRY_Invalid }, // _38
839
{ 0x39, ENTRY_Invalid }, // _39
840
{ 0x3A, ENTRY_Invalid }, // _3A
841
{ 0x3B, ENTRY_Invalid }, // _3B
842
{ 0x3C, ENTRY_Invalid }, // _3C
843
{ 0x3D, ENTRY_Invalid }, // _3D
844
{ 0x3E, ENTRY_Invalid }, // _3E
845
{ 0x3F, ENTRY_Invalid }, // _3F
846
{ 0x40, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40)
847
{ 0x41, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41)
848
{ 0x42, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVNE (0F 42)
849
{ 0x43, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB (0F 43)
850
{ 0x44, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44)
851
{ 0x45, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45)
852
{ 0x46, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46)
853
{ 0x47, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47)
854
{ 0x48, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48)
855
{ 0x49, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49)
856
{ 0x4A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A)
857
{ 0x4B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B)
858
{ 0x4C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C)
859
{ 0x4D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D)
860
{ 0x4E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E)
861
{ 0x4F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F)
862
{ 0x50, ENTRY_CopyBytes2Mod }, // MOVMSKPD MOVMSKPD
863
{ 0x51, ENTRY_CopyBytes2Mod }, // SQRTPS &
864
{ 0x52, ENTRY_CopyBytes2Mod }, // RSQRTTS RSQRTPS
865
{ 0x53, ENTRY_CopyBytes2Mod }, // RCPPS RCPSS
866
{ 0x54, ENTRY_CopyBytes2Mod }, // ANDPS ANDPD
867
{ 0x55, ENTRY_CopyBytes2Mod }, // ANDNPS ANDNPD
868
{ 0x56, ENTRY_CopyBytes2Mod }, // ORPS ORPD
869
{ 0x57, ENTRY_CopyBytes2Mod }, // XORPS XORPD
870
{ 0x58, ENTRY_CopyBytes2Mod }, // ADDPS &
871
{ 0x59, ENTRY_CopyBytes2Mod }, // MULPS &
872
{ 0x5A, ENTRY_CopyBytes2Mod }, // CVTPS2PD &
873
{ 0x5B, ENTRY_CopyBytes2Mod }, // CVTDQ2PS &
874
{ 0x5C, ENTRY_CopyBytes2Mod }, // SUBPS &
875
{ 0x5D, ENTRY_CopyBytes2Mod }, // MINPS &
876
{ 0x5E, ENTRY_CopyBytes2Mod }, // DIVPS &
877
{ 0x5F, ENTRY_CopyBytes2Mod }, // MASPS &
878
{ 0x60, ENTRY_CopyBytes2Mod }, // PUNPCKLBW/r
879
{ 0x61, ENTRY_CopyBytes2Mod }, // PUNPCKLWD/r
880
{ 0x62, ENTRY_CopyBytes2Mod }, // PUNPCKLWD/r
881
{ 0x63, ENTRY_CopyBytes2Mod }, // PACKSSWB/r
882
{ 0x64, ENTRY_CopyBytes2Mod }, // PCMPGTB/r
883
{ 0x65, ENTRY_CopyBytes2Mod }, // PCMPGTW/r
884
{ 0x66, ENTRY_CopyBytes2Mod }, // PCMPGTD/r
885
{ 0x67, ENTRY_CopyBytes2Mod }, // PACKUSWB/r
886
{ 0x68, ENTRY_CopyBytes2Mod }, // PUNPCKHBW/r
887
{ 0x69, ENTRY_CopyBytes2Mod }, // PUNPCKHWD/r
888
{ 0x6A, ENTRY_CopyBytes2Mod }, // PUNPCKHDQ/r
889
{ 0x6B, ENTRY_CopyBytes2Mod }, // PACKSSDW/r
890
{ 0x6C, ENTRY_CopyBytes2Mod }, // PUNPCKLQDQ
891
{ 0x6D, ENTRY_CopyBytes2Mod }, // PUNPCKHQDQ
892
{ 0x6E, ENTRY_CopyBytes2Mod }, // MOVD/r
893
{ 0x6F, ENTRY_CopyBytes2Mod }, // MOV/r
894
{ 0x70, ENTRY_CopyBytes2Mod1 }, // PSHUFW/r ib
895
{ 0x71, ENTRY_CopyBytes2Mod1 }, // PSLLW/6 ib,PSRAW/4 ib,PSRLW/2 ib
896
{ 0x72, ENTRY_CopyBytes2Mod1 }, // PSLLD/6 ib,PSRAD/4 ib,PSRLD/2 ib
897
{ 0x73, ENTRY_CopyBytes2Mod1 }, // PSLLQ/6 ib,PSRLQ/2 ib
898
{ 0x74, ENTRY_CopyBytes2Mod }, // PCMPEQB/r
899
{ 0x75, ENTRY_CopyBytes2Mod }, // PCMPEQW/r
900
{ 0x76, ENTRY_CopyBytes2Mod }, // PCMPEQD/r
901
{ 0x77, ENTRY_CopyBytes2 }, // EMMS
902
{ 0x78, ENTRY_Invalid }, // _78
903
{ 0x79, ENTRY_Invalid }, // _79
904
{ 0x7A, ENTRY_Invalid }, // _7A
905
{ 0x7B, ENTRY_Invalid }, // _7B
906
{ 0x7C, ENTRY_Invalid }, // _7C
907
{ 0x7D, ENTRY_Invalid }, // _7D
908
{ 0x7E, ENTRY_CopyBytes2Mod }, // MOVD/r
909
{ 0x7F, ENTRY_CopyBytes2Mod }, // MOV/r
910
{ 0x80, ENTRY_CopyBytes3Or5Target }, // JO
911
{ 0x81, ENTRY_CopyBytes3Or5Target }, // JNO
912
{ 0x82, ENTRY_CopyBytes3Or5Target }, // JB,JC,JNAE
913
{ 0x83, ENTRY_CopyBytes3Or5Target }, // JAE,JNB,JNC
914
{ 0x84, ENTRY_CopyBytes3Or5Target }, // JE,JZ,JZ
915
{ 0x85, ENTRY_CopyBytes3Or5Target }, // JNE,JNZ
916
{ 0x86, ENTRY_CopyBytes3Or5Target }, // JBE,JNA
917
{ 0x87, ENTRY_CopyBytes3Or5Target }, // JA,JNBE
918
{ 0x88, ENTRY_CopyBytes3Or5Target }, // JS
919
{ 0x89, ENTRY_CopyBytes3Or5Target }, // JNS
920
{ 0x8A, ENTRY_CopyBytes3Or5Target }, // JP,JPE
921
{ 0x8B, ENTRY_CopyBytes3Or5Target }, // JNP,JPO
922
{ 0x8C, ENTRY_CopyBytes3Or5Target }, // JL,NGE
923
{ 0x8D, ENTRY_CopyBytes3Or5Target }, // JGE,JNL
924
{ 0x8E, ENTRY_CopyBytes3Or5Target }, // JLE,JNG
925
{ 0x8F, ENTRY_CopyBytes3Or5Target }, // JG,JNLE
926
{ 0x90, ENTRY_CopyBytes2Mod }, // CMOVO (0F 40)
927
{ 0x91, ENTRY_CopyBytes2Mod }, // CMOVNO (0F 41)
928
{ 0x92, ENTRY_CopyBytes2Mod }, // CMOVB & CMOVC & CMOVNAE (0F 42)
929
{ 0x93, ENTRY_CopyBytes2Mod }, // CMOVAE & CMOVNB & CMOVNC (0F 43)
930
{ 0x94, ENTRY_CopyBytes2Mod }, // CMOVE & CMOVZ (0F 44)
931
{ 0x95, ENTRY_CopyBytes2Mod }, // CMOVNE & CMOVNZ (0F 45)
932
{ 0x96, ENTRY_CopyBytes2Mod }, // CMOVBE & CMOVNA (0F 46)
933
{ 0x97, ENTRY_CopyBytes2Mod }, // CMOVA & CMOVNBE (0F 47)
934
{ 0x98, ENTRY_CopyBytes2Mod }, // CMOVS (0F 48)
935
{ 0x99, ENTRY_CopyBytes2Mod }, // CMOVNS (0F 49)
936
{ 0x9A, ENTRY_CopyBytes2Mod }, // CMOVP & CMOVPE (0F 4A)
937
{ 0x9B, ENTRY_CopyBytes2Mod }, // CMOVNP & CMOVPO (0F 4B)
938
{ 0x9C, ENTRY_CopyBytes2Mod }, // CMOVL & CMOVNGE (0F 4C)
939
{ 0x9D, ENTRY_CopyBytes2Mod }, // CMOVGE & CMOVNL (0F 4D)
940
{ 0x9E, ENTRY_CopyBytes2Mod }, // CMOVLE & CMOVNG (0F 4E)
941
{ 0x9F, ENTRY_CopyBytes2Mod }, // CMOVG & CMOVNLE (0F 4F)
942
{ 0xA0, ENTRY_CopyBytes2 }, // PUSH
943
{ 0xA1, ENTRY_CopyBytes2 }, // POP
944
{ 0xA2, ENTRY_CopyBytes2 }, // CPUID
945
{ 0xA3, ENTRY_CopyBytes2Mod }, // BT (0F A3)
946
{ 0xA4, ENTRY_CopyBytes2Mod1 }, // SHLD
947
{ 0xA5, ENTRY_CopyBytes2Mod }, // SHLD
948
{ 0xA6, ENTRY_Invalid }, // _A6
949
{ 0xA7, ENTRY_Invalid }, // _A7
950
{ 0xA8, ENTRY_CopyBytes2 }, // PUSH
951
{ 0xA9, ENTRY_CopyBytes2 }, // POP
952
{ 0xAA, ENTRY_CopyBytes2 }, // RSM
953
{ 0xAB, ENTRY_CopyBytes2Mod }, // BTS (0F AB)
954
{ 0xAC, ENTRY_CopyBytes2Mod1 }, // SHRD
955
{ 0xAD, ENTRY_CopyBytes2Mod }, // SHRD
956
{ 0xAE, ENTRY_CopyBytes2Mod }, // FXRSTOR/1,FXSAVE/0
957
{ 0xAF, ENTRY_CopyBytes2Mod }, // IMUL (0F AF)
958
{ 0xB0, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B0)
959
{ 0xB1, ENTRY_CopyBytes2Mod }, // CMPXCHG (0F B1)
960
{ 0xB2, ENTRY_CopyBytes2Mod }, // LSS/r
961
{ 0xB3, ENTRY_CopyBytes2Mod }, // BTR (0F B3)
962
{ 0xB4, ENTRY_CopyBytes2Mod }, // LFS/r
963
{ 0xB5, ENTRY_CopyBytes2Mod }, // LGS/r
964
{ 0xB6, ENTRY_CopyBytes2Mod }, // MOVZX/r
965
{ 0xB7, ENTRY_CopyBytes2Mod }, // MOVZX/r
966
{ 0xB8, ENTRY_Invalid }, // _B8
967
{ 0xB9, ENTRY_Invalid }, // _B9
968
{ 0xBA, ENTRY_CopyBytes2Mod1 }, // BT & BTC & BTR & BTS (0F BA)
969
{ 0xBB, ENTRY_CopyBytes2Mod }, // BTC (0F BB)
970
{ 0xBC, ENTRY_CopyBytes2Mod }, // BSF (0F BC)
971
{ 0xBD, ENTRY_CopyBytes2Mod }, // BSR (0F BD)
972
{ 0xBE, ENTRY_CopyBytes2Mod }, // MOVSX/r
973
{ 0xBF, ENTRY_CopyBytes2Mod }, // MOVSX/r
974
{ 0xC0, ENTRY_CopyBytes2Mod }, // XADD/r
975
{ 0xC1, ENTRY_CopyBytes2Mod }, // XADD/r
976
{ 0xC2, ENTRY_CopyBytes2Mod }, // CMPPS &
977
{ 0xC3, ENTRY_CopyBytes2Mod }, // MOVNTI
978
{ 0xC4, ENTRY_CopyBytes2Mod1 }, // PINSRW /r ib
979
{ 0xC5, ENTRY_CopyBytes2Mod1 }, // PEXTRW /r ib
980
{ 0xC6, ENTRY_CopyBytes2Mod1 }, // SHUFPS & SHUFPD
981
{ 0xC7, ENTRY_CopyBytes2Mod }, // CMPXCHG8B (0F C7)
982
{ 0xC8, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
983
{ 0xC9, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
984
{ 0xCA, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
985
{ 0xCB, ENTRY_CopyBytes2 }, //CVTPD2PI BSWAP 0F C8 + rd
986
{ 0xCC, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
987
{ 0xCD, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
988
{ 0xCE, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
989
{ 0xCF, ENTRY_CopyBytes2 }, // BSWAP 0F C8 + rd
990
{ 0xD0, ENTRY_Invalid }, // _D0
991
{ 0xD1, ENTRY_CopyBytes2Mod }, // PSRLW/r
992
{ 0xD2, ENTRY_CopyBytes2Mod }, // PSRLD/r
993
{ 0xD3, ENTRY_CopyBytes2Mod }, // PSRLQ/r
994
{ 0xD4, ENTRY_CopyBytes2Mod }, // PADDQ
995
{ 0xD5, ENTRY_CopyBytes2Mod }, // PMULLW/r
996
{ 0xD6, ENTRY_CopyBytes2Mod }, // MOVDQ2Q / MOVQ2DQ
997
{ 0xD7, ENTRY_CopyBytes2Mod }, // PMOVMSKB/r
998
{ 0xD8, ENTRY_CopyBytes2Mod }, // PSUBUSB/r
999
{ 0xD9, ENTRY_CopyBytes2Mod }, // PSUBUSW/r
1000
{ 0xDA, ENTRY_CopyBytes2Mod }, // PMINUB/r
1001
{ 0xDB, ENTRY_CopyBytes2Mod }, // PAND/r
1002
{ 0xDC, ENTRY_CopyBytes2Mod }, // PADDUSB/r
1003
{ 0xDD, ENTRY_CopyBytes2Mod }, // PADDUSW/r
1004
{ 0xDE, ENTRY_CopyBytes2Mod }, // PMAXUB/r
1005
{ 0xDF, ENTRY_CopyBytes2Mod }, // PANDN/r
1006
{ 0xE0, ENTRY_CopyBytes2Mod }, // PAVGB
1007
{ 0xE1, ENTRY_CopyBytes2Mod }, // PSRAW/r
1008
{ 0xE2, ENTRY_CopyBytes2Mod }, // PSRAD/r
1009
{ 0xE3, ENTRY_CopyBytes2Mod }, // PAVGW
1010
{ 0xE4, ENTRY_CopyBytes2Mod }, // PMULHUW/r
1011
{ 0xE5, ENTRY_CopyBytes2Mod }, // PMULHW/r
1012
{ 0xE6, ENTRY_CopyBytes2Mod }, // CTDQ2PD &
1013
{ 0xE7, ENTRY_CopyBytes2Mod }, // MOVNTQ
1014
{ 0xE8, ENTRY_CopyBytes2Mod }, // PSUBB/r
1015
{ 0xE9, ENTRY_CopyBytes2Mod }, // PSUBW/r
1016
{ 0xEA, ENTRY_CopyBytes2Mod }, // PMINSW/r
1017
{ 0xEB, ENTRY_CopyBytes2Mod }, // POR/r
1018
{ 0xEC, ENTRY_CopyBytes2Mod }, // PADDSB/r
1019
{ 0xED, ENTRY_CopyBytes2Mod }, // PADDSW/r
1020
{ 0xEE, ENTRY_CopyBytes2Mod }, // PMAXSW /r
1021
{ 0xEF, ENTRY_CopyBytes2Mod }, // PXOR/r
1022
{ 0xF0, ENTRY_Invalid }, // _F0
1023
{ 0xF1, ENTRY_CopyBytes2Mod }, // PSLLW/r
1024
{ 0xF2, ENTRY_CopyBytes2Mod }, // PSLLD/r
1025
{ 0xF3, ENTRY_CopyBytes2Mod }, // PSLLQ/r
1026
{ 0xF4, ENTRY_CopyBytes2Mod }, // PMULUDQ/r
1027
{ 0xF5, ENTRY_CopyBytes2Mod }, // PMADDWD/r
1028
{ 0xF6, ENTRY_CopyBytes2Mod }, // PSADBW/r
1029
{ 0xF7, ENTRY_CopyBytes2Mod }, // MASKMOVQ
1030
{ 0xF8, ENTRY_CopyBytes2Mod }, // PSUBB/r
1031
{ 0xF9, ENTRY_CopyBytes2Mod }, // PSUBW/r
1032
{ 0xFA, ENTRY_CopyBytes2Mod }, // PSUBD/r
1033
{ 0xFB, ENTRY_CopyBytes2Mod }, // FSUBQ/r
1034
{ 0xFC, ENTRY_CopyBytes2Mod }, // PADDB/r
1035
{ 0xFD, ENTRY_CopyBytes2Mod }, // PADDW/r
1036
{ 0xFE, ENTRY_CopyBytes2Mod }, // PADDD/r
1037
{ 0xFF, ENTRY_Invalid }, // _FF
1038
{ 0, ENTRY_End },
1039
};
1040
1041
BOOL CDetourDis::SanityCheckSystem()
1042
{
1043
ULONG n = 0;
1044
for (; n < 256; n++) {
1045
REFCOPYENTRY pEntry = &s_rceCopyTable[n];
1046
1047
if (n != pEntry->nOpcode) {
1048
ASSERT(n == pEntry->nOpcode);
1049
return FALSE;
1050
}
1051
}
1052
if (s_rceCopyTable[256].pfCopy != NULL) {
1053
ASSERT(!"Missing end marker.");
1054
return FALSE;
1055
}
1056
1057
for (n = 0; n < 256; n++) {
1058
REFCOPYENTRY pEntry = &s_rceCopyTable0F[n];
1059
1060
if (n != pEntry->nOpcode) {
1061
ASSERT(n == pEntry->nOpcode);
1062
return FALSE;
1063
}
1064
}
1065
if (s_rceCopyTable0F[256].pfCopy != NULL) {
1066
ASSERT(!"Missing end marker.");
1067
return FALSE;
1068
}
1069
1070
return TRUE;
1071
}
1072
#endif // defined(DETOURS_X64) || defined(DETOURS_X86)
1073
1074
/////////////////////////////////////////////////////////// IA64 Disassembler.
1075
//
1076
#ifdef DETOURS_IA64
1077
#error Feature not supported in this release.
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
#endif // DETOURS_IA64
1597
1598
//
1599
///////////////////////////////////////////////////////////////// End of File.
1600
1601