Get a function of an instruction (OPCode and Opdata) length (transfer)

xiaoxiao2021-03-05  20

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

转载请注明原文地址:https://www.9cbs.com/read-39310.html

New Post(0)