Eyas is in
In the XHOOK, it is a very meaningful thing to get the command length when Hook is mentioned.
Below is a function of acquiring command length written by WJL @ smth:
/ *
Use the following functions to "disassemble" one instruction,
You can get opcode and opdata, as well as the length of the full instruction
After the function returns 1, Disasm_len is the length of the instruction.
* /
#define c_66 0x00000001 // 66-Prefix
#define c_67 0x00000002 // 67-prefix
#define c_lock 0x00000004 // Lock
#define c_rep 0x00000008 // REPZ / RepNZ
#define c_seg 0x00000010 // seg-prefix
#define c_opcode2 0x00000020 // 2nd opcode present (1st == 0F)
#define c_modrm 0x00000040 // ModRM Present
#define c_sib 0x00000080 // SIB Present
#define c_anyprefix (C_66 | C_67 | C_LOCK | C_REP | C_SEG)
DWORD Disasm_len; // 0 if Error
DWORD DISASM_FLAG; // c_xxx
DWORD DISASM_MEMSIZE; // Value = DISASM_MEM
DWORD DISASM_DATASIZE; // Value = DISASM_DATA
DWORD DISASM_DEFDATA; / / == C_66? 2: 4
DWORD DISASM_DEFMEM; / / == C_67? 2: 4
BYTE DISASM_SEG; // CS DS ES SS FS GS
BYTE DISASM_REP; // REPZ / REPNZ
Byte disasm_opcode; // opcode
Byte disasm_opcode2; // used when opcode == 0f
BYTE DISASM_MODRM; // MODXXXRM
BYTE DISASM_SIB; // Scale-Index-Base
BYTE DISASM_MEM [8]; // Mem Addr Value
Byte Disasm_Data [8]; // Data Value
INT LEN_DISASM (Byte * OpCode0)
{
BYTE * OPCODE = OPCODE0;
DISASM_LEN = 0;
DISASM_FLAG = 0;
Disasm_datasize = 0;
DISASM_MEMSIZE = 0;
DISASM_DEFDATA = 4;
DISASM_DEFMEM = 4; RETRY:
Disasm_opcode = * OPCODE ;
Switch (Disasm_opcode)
{
Case 0x00: Case 0x01: Case 0x02: Case 0x03:
Case 0x08: Case 0x09: Case 0x0a: Case 0x0b:
Case 0x10: Case 0x11: Case 0x12: Case 0x13:
Case 0x19: Case 0x1a: Case 0x1b:
Case 0x20: Case 0x21: Case 0x22: Case 0x23:
Case 0x28: Case 0x29: Case 0x2a: Case 0x2b:
Case 0x30: Case 0x31: Case 0x32: Case 0x33:
Case 0x38: Case 0x39: Case 0x3a: Case 0x3b:
Case 0x62: Case 0x63:
Case 0x84: Case 0x85: Case 0x86: Case 0x87:
Case 0x88: Case 0x89: Case 0x8a: Case 0x8b:
Case 0x8c: Case 0x8d: Case 0x8e: Case 0x8f:
Case 0xc4: Case 0xc5:
Case 0xd0: Case 0xd1: Case 0xD2: Case 0xD3:
Case 0xD8: Case 0xD9: Case 0xDa: Case 0xDB:
Case 0xDC: Case 0xDD: Case 0xde: Case 0xDF:
Case 0xfe: Case 0xFF:
DISASM_FLAG | = C_MODRM;
Break;
Case 0xcd: disasm_datasize = * opcode == 0x20? 1 4: 1;
Break;
Case 0xF6:
Case 0xf7: disasm_flag | = c_modrm;
IF (* opcode & 0x38) BREAK;
// Continue IF
Case 0x04: Case 0x0c: Case 0x0d:
Case 0x14: Case 0x1c: Case 0x1d:
Case 0x24: Case 0x25: Case 0x2c: Case 0x2d:
Case 0x34: Case 0x35: Case 0x3c: Case 0x3d:
IF (Disasm_opcode & 1)
Disasm_DataSize = disasm_defdata;
Else
Disasm_DataSize ;
Break;
Case 0x6a:
Case 0xA8:
Case 0xB0: Case 0xB1: Case 0xB2: Case 0xB3:
Case 0xB4: Case 0xB5: Case 0xB6: Case 0xB7:
Case 0xD4: Case 0xD5:
Case 0xE4: Case 0xE5: Case 0xe6: Case 0xe7:
Case 0x70: Case 0x71: Case 0x72: Case 0x73:
Case 0x74: Case 0x75: Case 0x76: Case 0x77:
Case 0x78: Case 0x79: Case 0x7a: Case 0x7b:
Case 0x7c: Case 0x7d: Case 0x7e: Case 0x7f:
Case 0xeb:
Case 0xE0: Case 0xE1: Case 0xE2: Case 0xE3:
Disasm_DataSize ;
Break;
Case 0x26: Case 0x2e: Case 0x36: Case 0x3e:
Case 0x64: Case 0x65:
IF (disasm_flag & c_seg) Return 0;
DISASM_FLAG | = C_SEG;
DISASM_SEG = Disasm_opcode;
Goto Retry;
Case 0xF0:
IF (Disasm_Flag & C_Lock) Return 0;
DISASM_FLAG | = C_LOCK;
Goto Retry;
Case 0xF2: Case 0xF3:
IF (Disasm_Flag & C_rep) Return 0;
DISASM_FLAG | = C_REP;
DISASM_REP = Disasm_opcode;
Goto Retry;
Case 0x66:
IF (Disasm_Flag & C_66) Return 0;
DISASM_FLAG | = C_66;
DISASM_DEFDATA = 2;
Goto Retry;
Case 0x67:
IF (Disasm_Flag & C_67) Return 0;
DISASM_FLAG | = C_67;
DISASM_DEFMEM = 2;
Goto Retry;
Case 0x6b:
Case 0x80:
Case 0x82:
Case 0x83:
Case 0xc0:
Case 0xc1:
Case 0xc6: DISASM_DATASIZE ;
DISASM_FLAG | = C_MODRM;
Break;
Case 0x69:
Case 0x81:
Case 0xc7:
Disasm_DataSize = disasm_defdata;
DISASM_FLAG | = C_MODRM;
Break;
Case 0x9a:
Case 0xea: Disasm_DataSize = 2 DISASM_DEFDATA;
Break;
Case 0xa0:
Case 0xa1:
Case 0xa2:
Case 0xA3: DISASM_MEMSIZE = DISASM_DEFMEM;
Break;
Case 0x68:
Case 0xA9:
Case 0xB8: Case 0xB9: Case 0XBA: Case 0xBB:
Case 0xBC: Case 0xBD: Case 0xbe: Case 0xBF:
Case 0xe8:
Case 0xE9:
Disasm_DataSize = disasm_defdata;
Break;
Case 0xc2:
Case 0xca: disasm_datasize = 2;
Break;
Case 0xc8:
Disasm_DataSize = 3;
Break;
Case 0xf1:
Return 0;
Case 0x0f:
DISASM_FLAG | = C_OPCODE2;
Disasm_opcode2 = * OPCode ;
Switch (disasm_opcode2)
{
Case 0x00: Case 0x01: Case 0x02: Case 0x03:
Case 0x90: Case 0x91: Case 0x92: Case 0x93:
Case 0x94: Case 0x95: Case 0x96: Case 0x97:
Case 0x98: Case 0x99: Case 0x9a: Case 0x9b:
Case 0x9c: Case 0x9d: Case 0x9E: Case 0x9f: Case 0xA3:
Case 0xa5:
Case 0xAb:
Case 0xAD:
Case 0xAF:
Case 0xB0: Case 0xB1: Case 0xB2: Case 0xB3:
Case 0xB4: Case 0xB5: Case 0xB6: Case 0xB7:
Case 0xBB:
Case 0xBC: Case 0xBD: Case 0xbe: Case 0xBF:
Case 0xc0:
Case 0xc1:
DISASM_FLAG | = C_MODRM;
Break;
Case 0x06:
Case 0x08: Case 0x09: Case 0x0a: Case 0x0b:
Case 0xA0: Case 0xa1: Case 0xA2: Case 0xA8:
Case 0xA9:
Case 0xAA:
Case 0xc8: Case 0xc9: Case 0xca: Case 0xcb:
Case 0xcc: case 0xcd: case 0xce: Case 0xcf:
Break;
Case 0x80: Case 0x81: Case 0x82: Case 0x83:
Case 0x84: Case 0x85: Case 0x86: Case 0x87:
Case 0x88: Case 0x89: Case 0x8a: Case 0x8b:
Case 0x8c: Case 0x8d: Case 0x8e: Case 0x8f:
Disasm_DataSize = disasm_defdata;
Break;
Case 0xA4:
Case 0xac:
Case 0xBA:
Disasm_DataSize ;
DISASM_FLAG | = C_MODRM;
Break;
DEFAULT:
Return 0;
} // 0f-switch
Break;
} // switch
IF (Disasm_Flag & C_ModRM)
{
Disasm_modrm = * opcode ;
BYTE MOD = Disasm_ModRM & 0xC0;
BYTE RM = DISASM_MODRM & 0x07;
IF (MOD! = 0xc0)
{
IF (MOD == 0x40) DISASM_MEMSIZE ;
IF (MOD == 0x80) DISASM_MEMSIZE = DISASM_DEFMEM;
IF (disasm_defmem == 2) // modRM16
{
IF ((MOD == 0x00) && (RM == 0x06)) DISASM_MEMSIZE = 2;
}
ELSE // modRM32
{
IF (rm == 0x04)
{
DISASM_FLAG | = C_SIB;
Disasm_sib = * OPCode ;
RM = disasm_sib & 0x07;
}
IF ((RM == 0x05) && (MOD == 0x00)) DISASM_MEMSIZE = 4;
}
}
} // c_modrm
Disasm_mem [i] = * opcode ;
For (i = 0; i Disasm_data [i] = * opcode ; disasm_len = opcode - opcode0; Return 1; } // disasm