diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/artificial.c | 2 | ||||
| -rw-r--r-- | src/arch/instruction.c | 48 | ||||
| -rw-r--r-- | src/arch/instruction.h | 6 | ||||
| -rw-r--r-- | src/arch/jvm/operand.c | 2 | ||||
| -rw-r--r-- | src/arch/x86/instruction.c | 392 | ||||
| -rw-r--r-- | src/arch/x86/instruction.h | 13 | ||||
| -rw-r--r-- | src/arch/x86/op_and.c | 110 | ||||
| -rw-r--r-- | src/arch/x86/op_cmp.c | 36 | ||||
| -rw-r--r-- | src/arch/x86/op_int.c | 2 | ||||
| -rw-r--r-- | src/arch/x86/op_jump.c | 72 | ||||
| -rw-r--r-- | src/arch/x86/op_mul.c | 36 | ||||
| -rw-r--r-- | src/arch/x86/opcodes.h | 21 | ||||
| -rw-r--r-- | src/arch/x86/operand.c | 381 | ||||
| -rw-r--r-- | src/arch/x86/operand.h | 13 | ||||
| -rw-r--r-- | src/arch/x86/processor.c | 35 | 
15 files changed, 658 insertions, 511 deletions
| diff --git a/src/arch/artificial.c b/src/arch/artificial.c index a1fa56e..16e95bc 100644 --- a/src/arch/artificial.c +++ b/src/arch/artificial.c @@ -139,7 +139,7 @@ GArchInstruction *g_db_instruction_new_from_data(const bin_t *data, off_t *pos,                                            g_arch_processor_get_endianness(proc));      if (operand == NULL) goto gdinfd_error; -    g_arch_instruction_attach_one_operand(result, operand); +    g_arch_instruction_attach_extra_operand(result, operand);      return result; diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 8bc317b..16e5c81 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -196,54 +196,6 @@ void g_arch_instruction_get_location(GArchInstruction *instr, off_t *offset, off  *  Paramètres  : instr     = instance à mettre à jour.                        *  *                opererand = instruction à venir associer.                    *  *                                                                             * -*  Description : Attache un seul opérande à un instruction.                   * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_arch_instruction_attach_one_operand(GArchInstruction *instr, GArchOperand *operand) -{ -    instr->operands = (GArchOperand **)calloc(1, sizeof(GArchOperand *)); -    instr->operands_count = 1; - -    instr->operands[0] = operand; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr    = instance à mettre à jour.                         * -*                operand1 = première instruction à venir associer.            * -*                operand2 = seconde instruction à venir associer.             * -*                                                                             * -*  Description : Attache deux opérandes à un instruction.                     * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_arch_instruction_attach_two_operands(GArchInstruction *instr, GArchOperand *operand1, GArchOperand *operand2) -{ -    instr->operands = (GArchOperand **)calloc(2, sizeof(GArchOperand *)); -    instr->operands_count = 2; - -    instr->operands[0] = operand1; -    instr->operands[1] = operand2; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr     = instance à mettre à jour.                        * -*                opererand = instruction à venir associer.                    * -*                                                                             *  *  Description : Attache un opérande supplémentaire à une instruction.        *  *                                                                             *  *  Retour      : -                                                            * diff --git a/src/arch/instruction.h b/src/arch/instruction.h index accaed6..0c51b93 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -70,12 +70,6 @@ void g_arch_instruction_set_location(GArchInstruction *, off_t, off_t, vmpa_t);  /* Fournit la localisation d'une instruction. */  void g_arch_instruction_get_location(GArchInstruction *, off_t *, off_t *, vmpa_t *); -/* Attache un seul opérande à une instruction. */ -void g_arch_instruction_attach_one_operand(GArchInstruction *, GArchOperand *); - -/* Attache deux opérandes à une instruction. */ -void g_arch_instruction_attach_two_operands(GArchInstruction *, GArchOperand *, GArchOperand *); -  /* Attache un opérande supplémentaire à une instruction. */  void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *); diff --git a/src/arch/jvm/operand.c b/src/arch/jvm/operand.c index 429516a..a485a2b 100644 --- a/src/arch/jvm/operand.c +++ b/src/arch/jvm/operand.c @@ -324,7 +324,7 @@ bool jvm_read_one_operand(GArchInstruction *instr, const bin_t *data, off_t *pos      if (op == NULL) return false; -    g_arch_instruction_attach_one_operand(instr, op); +    g_arch_instruction_attach_extra_operand(instr, op);      return true; diff --git a/src/arch/x86/instruction.c b/src/arch/x86/instruction.c index c8d31a0..72143ee 100644 --- a/src/arch/x86/instruction.c +++ b/src/arch/x86/instruction.c @@ -80,262 +80,274 @@ typedef struct _x86_instruction  static x86_instruction _instructions[XOP_COUNT] = { -    [XOP_ADD_RM8_R8]            = { false, 0x00, IDX_TO_EXT(-1), "add", XPX_NONE }, -    [XOP_ADD_RM1632_R1632]      = { false, 0x01, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_ADD_R8_RM8]            = { false, 0x02, IDX_TO_EXT(-1), "add", XPX_NONE }, -    [XOP_ADD_R1632_RM1632]      = { false, 0x03, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_ADD_AL_IMM8]           = { false, 0x04, IDX_TO_EXT(-1), "add", XPX_NONE }, -    [XOP_ADD_E_AX_IMM1632]      = { false, 0x05, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_ADD_RM8_R8]                = { false, 0x00, IDX_TO_EXT(-1), "add", XPX_NONE }, +    [XOP_ADD_RM1632_R1632]          = { false, 0x01, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_ADD_R8_RM8]                = { false, 0x02, IDX_TO_EXT(-1), "add", XPX_NONE }, +    [XOP_ADD_R1632_RM1632]          = { false, 0x03, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_ADD_AL_IMM8]               = { false, 0x04, IDX_TO_EXT(-1), "add", XPX_NONE }, +    [XOP_ADD_E_AX_IMM1632]          = { false, 0x05, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_OR_R8_RM8]             = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE }, +    [XOP_OR_R8_RM8]                 = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE }, -    [XOP_OR_RM8_R8]             = { false, 0x08, IDX_TO_EXT(-1), "or", XPX_NONE }, -    [XOP_OR_RM1632_R1632]       = { false, 0x09, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_OR_R8_RM8]             = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE }, -    [XOP_OR_R1632_RM1632]       = { false, 0x0b, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_OR_AL_IMM8]            = { false, 0x0c, IDX_TO_EXT(-1), "or", XPX_NONE }, +    [XOP_OR_RM8_R8]                 = { false, 0x08, IDX_TO_EXT(-1), "or", XPX_NONE }, +    [XOP_OR_RM1632_R1632]           = { false, 0x09, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_OR_R8_RM8]                 = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE }, +    [XOP_OR_R1632_RM1632]           = { false, 0x0b, IDX_TO_EXT(-1), "or", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_OR_AL_IMM8]                = { false, 0x0c, IDX_TO_EXT(-1), "or", XPX_NONE }, -    [XOP_JE_REL1632]            = { false, 0x84, IDX_TO_EXT(-1), "je", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_JNE_REL1632]           = { false, 0x85, IDX_TO_EXT(-1), "jne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JE_REL1632]                = { false, 0x84, IDX_TO_EXT(-1), "je", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JNE_REL1632]               = { false, 0x85, IDX_TO_EXT(-1), "jne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JBE_REL1632]               = { false, 0x86, IDX_TO_EXT(-1), "jbe", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JA_REL1632]                = { false, 0x87, IDX_TO_EXT(-1), "ja", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_JA_REL1632]            = { false, 0x87, IDX_TO_EXT(-1), "ja", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - -    [XOP_JGE_REL1632]           = { false, 0x8d, IDX_TO_EXT(-1), "jge", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_JLE_REL1632]           = { false, 0x8e, IDX_TO_EXT(-1), "jle", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - - -    [XOP_SETE_RM8]              = { false, 0x94, IDX_TO_EXT(-1), "sete", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SETNE_RM8]             = { false, 0x95, IDX_TO_EXT(-1), "setne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, - - -    [XOP_MOVZX_R1632_RM8]       = { false, 0xb6, IDX_TO_EXT(-1), "movzx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOVSX_R1632_RM8]       = { false, 0xbe, IDX_TO_EXT(-1), "movsx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JGE_REL1632]               = { false, 0x8d, IDX_TO_EXT(-1), "jge", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JLE_REL1632]               = { false, 0x8e, IDX_TO_EXT(-1), "jle", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JG_REL1632]                = { false, 0x8f, IDX_TO_EXT(-1), "jg", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_ADC_RM8_R8]            = { false, 0x10, IDX_TO_EXT(-1), "adc", XPX_NONE }, - -    [XOP_AND_RM8_R8]            = { false, 0x20, IDX_TO_EXT(-1), "and", XPX_NONE }, - -    [XOP_SUB_RM1632_R1632]      = { false, 0x29, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, - -    [XOP_SUB_R8_RM8]            = { false, 0x2a, IDX_TO_EXT(-1), "sub", XPX_NONE }, -    [XOP_SUB_AL_IMM8]           = { false, 0x2c, IDX_TO_EXT(-1), "sub", XPX_NONE }, - -    [XOP_SUB_E_AX_IMM1632]      = { false, 0x2d, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, - +    [XOP_SETE_RM8]                  = { false, 0x94, IDX_TO_EXT(-1), "sete", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SETNE_RM8]                 = { false, 0x95, IDX_TO_EXT(-1), "setne", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XOR_RM8_R8]            = { false, 0x30, IDX_TO_EXT(-1), "xor", XPX_NONE}, -    [XOP_XOR_RM1632_R1632]      = { false, 0x31, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XOR_R8_RM8]            = { false, 0x32, IDX_TO_EXT(-1), "xor", XPX_NONE}, -    [XOP_XOR_R1632_RM1632]      = { false, 0x33, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XOR_AL_IMM8]           = { false, 0x34, IDX_TO_EXT(-1), "xor", XPX_NONE }, -    [XOP_XOR_E_AX_IMM1632]      = { false, 0x35, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOVZX_R1632_RM8]           = { false, 0xb6, IDX_TO_EXT(-1), "movzx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOVSX_R1632_RM8]           = { false, 0xbe, IDX_TO_EXT(-1), "movsx", XPX_TWO_BYTES | XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_ADC_RM8_R8]                = { false, 0x10, IDX_TO_EXT(-1), "adc", XPX_NONE }, +    [XOP_AND_RM8_R8]                = { false, 0x20, IDX_TO_EXT(-1), "and", XPX_NONE }, +    [XOP_AND_RM1632_R1632]          = { false, 0x21, IDX_TO_EXT(-1), "and", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_CMP_RM1632_R1632]      = { false, 0x39, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_INC_E_AX]              = { true, 0x40, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_INC_E_CX]              = { true, 0x41, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_INC_E_DX]              = { true, 0x42, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_INC_E_BX]              = { true, 0x43, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_INC_E_SP]              = { true, 0x44, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_INC_E_BP]              = { true, 0x45, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_INC_E_SI]              = { true, 0x46, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_INC_E_DI]              = { true, 0x47, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_DEC_E_AX]              = { true, 0x48, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_DEC_E_CX]              = { true, 0x49, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_DEC_E_DX]              = { true, 0x4a, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_DEC_E_BX]              = { true, 0x4b, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_DEC_E_SP]              = { true, 0x4c, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_DEC_E_BP]              = { true, 0x4d, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_DEC_E_SI]              = { true, 0x4e, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_DEC_E_DI]              = { true, 0x4f, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_E_AX]             = { true, 0x50, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_E_CX]             = { true, 0x51, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_E_DX]             = { true, 0x52, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_E_BX]             = { true, 0x53, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_E_SP]             = { true, 0x54, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_E_BP]             = { true, 0x55, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_E_SI]             = { true, 0x56, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_E_DI]             = { true, 0x57, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_POP_E_AX]              = { true, 0x58, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_POP_E_CX]              = { true, 0x59, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_POP_E_DX]              = { true, 0x5a, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_POP_E_BX]              = { true, 0x5b, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_POP_E_SP]              = { true, 0x5c, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_POP_E_BP]              = { true, 0x5d, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_POP_E_SI]              = { true, 0x5e, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_POP_E_DI]              = { true, 0x5f, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_AND_AL_IMM8]               = { false, 0x24, IDX_TO_EXT(-1), "and", XPX_NONE }, +    [XOP_AND_E_AX_IMM1632]          = { false, 0x25, IDX_TO_EXT(-1), "and", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_IMM1632]          = { false, 0x68, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SUB_RM1632_R1632]          = { false, 0x29, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SUB_R8_RM8]                = { false, 0x2a, IDX_TO_EXT(-1), "sub", XPX_NONE }, +    [XOP_SUB_AL_IMM8]               = { false, 0x2c, IDX_TO_EXT(-1), "sub", XPX_NONE }, -    [XOP_IMUL_RM1632_IMM8]      = { false, 0x6b, IDX_TO_EXT(-1), "imul", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SUB_E_AX_IMM1632]          = { false, 0x2d, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_JO_REL8]               = { false, 0x70, IDX_TO_EXT(-1), "jo", XPX_NONE }, -    [XOP_JNO_REL8]              = { false, 0x71, IDX_TO_EXT(-1), "jno", XPX_NONE }, -    [XOP_JB_REL8]               = { false, 0x72, IDX_TO_EXT(-1), "jb", XPX_NONE }, -    [XOP_JNB_REL8]              = { false, 0x73, IDX_TO_EXT(-1), "jnb", XPX_NONE }, -    [XOP_JE_REL8]               = { false, 0x74, IDX_TO_EXT(-1), "je", XPX_NONE }, -    [XOP_JNE_REL8]              = { false, 0x75, IDX_TO_EXT(-1), "jne", XPX_NONE }, -    [XOP_JNA_REL8]              = { false, 0x76, IDX_TO_EXT(-1), "jna", XPX_NONE }, -    [XOP_JA_REL8]               = { false, 0x77, IDX_TO_EXT(-1), "ja", XPX_NONE }, -    [XOP_JS_REL8]               = { false, 0x78, IDX_TO_EXT(-1), "js", XPX_NONE }, -    [XOP_JNS_REL8]              = { false, 0x79, IDX_TO_EXT(-1), "jns", XPX_NONE }, -    [XOP_JP_REL8]               = { false, 0x7a, IDX_TO_EXT(-1), "jp", XPX_NONE }, -    [XOP_JNP_REL8]              = { false, 0x7b, IDX_TO_EXT(-1), "jnp", XPX_NONE }, -    [XOP_JL_REL8]               = { false, 0x7c, IDX_TO_EXT(-1), "jl", XPX_NONE }, -    [XOP_JNL_REL8]              = { false, 0x7d, IDX_TO_EXT(-1), "jnl", XPX_NONE }, -    [XOP_JNG_REL8]              = { false, 0x7e, IDX_TO_EXT(-1), "jng", XPX_NONE }, -    [XOP_JG_REL8]               = { false, 0x7f, IDX_TO_EXT(-1), "jg", XPX_NONE }, -    [XOP_ADD_RM8_IMM8]          = { false, 0x80, IDX_TO_EXT(0), "add", XPX_NONE }, -    [XOP_OR_RM8_IMM8]           = { false, 0x80, IDX_TO_EXT(1), "or", XPX_NONE }, -    [XOP_ADC_RM8_IMM8]          = { false, 0x80, IDX_TO_EXT(2), "adc", XPX_NONE }, -    [XOP_SBB_RM8_IMM8]          = { false, 0x80, IDX_TO_EXT(3), "sbb", XPX_NONE }, -    [XOP_AND_RM8_IMM8]          = { false, 0x80, IDX_TO_EXT(4), "and", XPX_NONE }, -    [XOP_SUB_RM8_IMM8]          = { false, 0x80, IDX_TO_EXT(5), "sub", XPX_NONE }, -    [XOP_XOR_RM8_IMM8]          = { false, 0x80, IDX_TO_EXT(6), "xor", XPX_NONE }, -    [XOP_CMP_RM8_IMM8]          = { false, 0x80, IDX_TO_EXT(7), "cmp", XPX_NONE }, -    [XOP_ADD_RM1632_IMM1632]    = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_OR_RM1632_IMM1632]     = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_ADC_RM1632_IMM1632]    = { false, 0x81, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SBB_RM1632_IMM1632]    = { false, 0x81, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_AND_RM1632_IMM1632]    = { false, 0x81, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SUB_RM1632_IMM1632]    = { false, 0x81, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XOR_RM1632_IMM1632]    = { false, 0x81, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_CMP_RM1632_IMM1632]    = { false, 0x81, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XOR_RM8_R8]                = { false, 0x30, IDX_TO_EXT(-1), "xor", XPX_NONE}, +    [XOP_XOR_RM1632_R1632]          = { false, 0x31, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XOR_R8_RM8]                = { false, 0x32, IDX_TO_EXT(-1), "xor", XPX_NONE}, +    [XOP_XOR_R1632_RM1632]          = { false, 0x33, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XOR_AL_IMM8]               = { false, 0x34, IDX_TO_EXT(-1), "xor", XPX_NONE }, +    [XOP_XOR_E_AX_IMM1632]          = { false, 0x35, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_ADD_RM1632_IMM8]       = { false, 0x83, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_OR_RM1632_IMM8]        = { false, 0x83, IDX_TO_EXT(1), "or", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_ADC_RM1632_IMM8]       = { false, 0x83, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SBB_RM1632_IMM8]       = { false, 0x83, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_AND_RM1632_IMM8]       = { false, 0x83, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SUB_RM1632_IMM8]       = { false, 0x83, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XOR_RM1632_IMM8]       = { false, 0x83, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_CMP_RM1632_IMM8]       = { false, 0x83, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_TEST_RM8_R8]           = { false, 0x84, IDX_TO_EXT(-1), "test", XPX_NONE }, -    [XOP_TEST_RM1632_R1632]     = { false, 0x85, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_RM8_R8]            = { false, 0x88, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_RM1632_R1632]      = { false, 0x89, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_CMP_RM1632_R1632]          = { false, 0x39, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_CMP_R1632_RM1632]          = { false, 0x3b, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_R1632_RM1632]      = { false, 0x8b, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_INC_E_AX]                  = { true, 0x40, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_INC_E_CX]                  = { true, 0x41, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_INC_E_DX]                  = { true, 0x42, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_INC_E_BX]                  = { true, 0x43, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_INC_E_SP]                  = { true, 0x44, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_INC_E_BP]                  = { true, 0x45, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_INC_E_SI]                  = { true, 0x46, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_INC_E_DI]                  = { true, 0x47, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_DEC_E_AX]                  = { true, 0x48, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_DEC_E_CX]                  = { true, 0x49, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_DEC_E_DX]                  = { true, 0x4a, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_DEC_E_BX]                  = { true, 0x4b, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_DEC_E_SP]                  = { true, 0x4c, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_DEC_E_BP]                  = { true, 0x4d, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_DEC_E_SI]                  = { true, 0x4e, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_DEC_E_DI]                  = { true, 0x4f, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_E_AX]                 = { true, 0x50, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_E_CX]                 = { true, 0x51, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_E_DX]                 = { true, 0x52, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_E_BX]                 = { true, 0x53, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_E_SP]                 = { true, 0x54, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_E_BP]                 = { true, 0x55, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_E_SI]                 = { true, 0x56, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_E_DI]                 = { true, 0x57, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_POP_E_AX]                  = { true, 0x58, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_POP_E_CX]                  = { true, 0x59, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_POP_E_DX]                  = { true, 0x5a, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_POP_E_BX]                  = { true, 0x5b, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_POP_E_SP]                  = { true, 0x5c, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_POP_E_BP]                  = { true, 0x5d, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_POP_E_SI]                  = { true, 0x5e, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_POP_E_DI]                  = { true, 0x5f, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_LEA_R1632_M]           = { false, 0x8d, IDX_TO_EXT(-1), "lea", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_IMM1632]              = { false, 0x68, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_IMUL_R1632_RM1632_IMM1632] = { false, 0x69, IDX_TO_EXT(-1), "imul", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_NOP]                   = { false, 0x90, IDX_TO_EXT(-1), "nop", XPX_NONE }, -    [XOP_XCHG_R1632_E_AX]       = { true, 0x90, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XCHG_R1632_E_CX]       = { true, 0x91, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XCHG_R1632_E_DX]       = { true, 0x92, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XCHG_R1632_E_BX]       = { true, 0x93, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XCHG_R1632_E_SP]       = { true, 0x94, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XCHG_R1632_E_BP]       = { true, 0x95, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XCHG_R1632_E_SI]       = { true, 0x96, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_XCHG_R1632_E_DI]       = { true, 0x97, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_IMUL_RM1632_IMM8]          = { false, 0x6b, IDX_TO_EXT(-1), "imul", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_AL_MOFFS8]         = { false, 0xa0, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_E_AX_MOFFS1632]    = { false, 0xa1, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_MOFFS8_AL]         = { false, 0xa2, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_MOFFS1632_E_AX]    = { false, 0xa3, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JO_REL8]                   = { false, 0x70, IDX_TO_EXT(-1), "jo", XPX_NONE }, +    [XOP_JNO_REL8]                  = { false, 0x71, IDX_TO_EXT(-1), "jno", XPX_NONE }, +    [XOP_JB_REL8]                   = { false, 0x72, IDX_TO_EXT(-1), "jb", XPX_NONE }, +    [XOP_JNB_REL8]                  = { false, 0x73, IDX_TO_EXT(-1), "jnb", XPX_NONE }, +    [XOP_JE_REL8]                   = { false, 0x74, IDX_TO_EXT(-1), "je", XPX_NONE }, +    [XOP_JNE_REL8]                  = { false, 0x75, IDX_TO_EXT(-1), "jne", XPX_NONE }, +    [XOP_JNA_REL8]                  = { false, 0x76, IDX_TO_EXT(-1), "jna", XPX_NONE }, +    [XOP_JA_REL8]                   = { false, 0x77, IDX_TO_EXT(-1), "ja", XPX_NONE }, +    [XOP_JS_REL8]                   = { false, 0x78, IDX_TO_EXT(-1), "js", XPX_NONE }, +    [XOP_JNS_REL8]                  = { false, 0x79, IDX_TO_EXT(-1), "jns", XPX_NONE }, +    [XOP_JP_REL8]                   = { false, 0x7a, IDX_TO_EXT(-1), "jp", XPX_NONE }, +    [XOP_JNP_REL8]                  = { false, 0x7b, IDX_TO_EXT(-1), "jnp", XPX_NONE }, +    [XOP_JL_REL8]                   = { false, 0x7c, IDX_TO_EXT(-1), "jl", XPX_NONE }, +    [XOP_JNL_REL8]                  = { false, 0x7d, IDX_TO_EXT(-1), "jnl", XPX_NONE }, +    [XOP_JNG_REL8]                  = { false, 0x7e, IDX_TO_EXT(-1), "jng", XPX_NONE }, +    [XOP_JG_REL8]                   = { false, 0x7f, IDX_TO_EXT(-1), "jg", XPX_NONE }, +    [XOP_ADD_RM8_IMM8]              = { false, 0x80, IDX_TO_EXT(0), "add", XPX_NONE }, +    [XOP_OR_RM8_IMM8]               = { false, 0x80, IDX_TO_EXT(1), "or", XPX_NONE }, +    [XOP_ADC_RM8_IMM8]              = { false, 0x80, IDX_TO_EXT(2), "adc", XPX_NONE }, +    [XOP_SBB_RM8_IMM8]              = { false, 0x80, IDX_TO_EXT(3), "sbb", XPX_NONE }, +    [XOP_AND_RM8_IMM8]              = { false, 0x80, IDX_TO_EXT(4), "and", XPX_NONE }, +    [XOP_SUB_RM8_IMM8]              = { false, 0x80, IDX_TO_EXT(5), "sub", XPX_NONE }, +    [XOP_XOR_RM8_IMM8]              = { false, 0x80, IDX_TO_EXT(6), "xor", XPX_NONE }, +    [XOP_CMP_RM8_IMM8]              = { false, 0x80, IDX_TO_EXT(7), "cmp", XPX_NONE }, +    [XOP_ADD_RM1632_IMM1632]        = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_OR_RM1632_IMM1632]         = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_ADC_RM1632_IMM1632]        = { false, 0x81, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SBB_RM1632_IMM1632]        = { false, 0x81, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_AND_RM1632_IMM1632]        = { false, 0x81, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SUB_RM1632_IMM1632]        = { false, 0x81, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XOR_RM1632_IMM1632]        = { false, 0x81, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_CMP_RM1632_IMM1632]        = { false, 0x81, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_TEST_AL_IMM8]          = { false, 0xa8, IDX_TO_EXT(-1), "test", XPX_NONE }, -    [XOP_TEST_E_AX_IMM1632]     = { false, 0xa9, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_ADD_RM1632_IMM8]           = { false, 0x83, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_OR_RM1632_IMM8]            = { false, 0x83, IDX_TO_EXT(1), "or", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_ADC_RM1632_IMM8]           = { false, 0x83, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SBB_RM1632_IMM8]           = { false, 0x83, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_AND_RM1632_IMM8]           = { false, 0x83, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SUB_RM1632_IMM8]           = { false, 0x83, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XOR_RM1632_IMM8]           = { false, 0x83, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_CMP_RM1632_IMM8]           = { false, 0x83, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SCAS_AL_M8]            = { false, 0xae, IDX_TO_EXT(-1), "scas", XPX_NONE }, +    [XOP_TEST_RM8_R8]               = { false, 0x84, IDX_TO_EXT(-1), "test", XPX_NONE }, +    [XOP_TEST_RM1632_R1632]         = { false, 0x85, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_AL_IMM8]           = { true, 0xb0, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_CL_IMM8]           = { true, 0xb1, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_DL_IMM8]           = { true, 0xb2, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_BL_IMM8]           = { true, 0xb3, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_AH_IMM8]           = { true, 0xb4, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_CH_IMM8]           = { true, 0xb5, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_DH_IMM8]           = { true, 0xb6, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_BH_IMM8]           = { true, 0xb7, IDX_TO_EXT(-1), "mov", XPX_NONE }, -    [XOP_MOV_E_AX_IMM1632]      = { true, 0xb8, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_E_CX_IMM1632]      = { true, 0xb9, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_E_DX_IMM1632]      = { true, 0xba, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_E_BX_IMM1632]      = { true, 0xbb, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_E_SP_IMM1632]      = { true, 0xbc, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_E_BP_IMM1632]      = { true, 0xbd, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_E_SI_IMM1632]      = { true, 0xbe, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_E_DI_IMM1632]      = { true, 0xbf, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_RM8_R8]                = { false, 0x88, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_RM1632_R1632]          = { false, 0x89, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_R1632_RM1632]          = { false, 0x8b, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_ROL_RM1632_IMM8]       = { false, 0xc1, IDX_TO_EXT(0), "rol", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_ROR_RM1632_IMM8]       = { false, 0xc1, IDX_TO_EXT(1), "ror", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_RCL_RM1632_IMM8]       = { false, 0xc1, IDX_TO_EXT(2), "rcl", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_RCR_RM1632_IMM8]       = { false, 0xc1, IDX_TO_EXT(3), "rcr", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SHL_RM1632_IMM8]       = { false, 0xc1, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SHR_RM1632_IMM8]       = { false, 0xc1, IDX_TO_EXT(5), "shr", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SAL_RM1632_IMM8]       = { false, 0xc1, IDX_TO_EXT(6), "sal", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_SAR_RM1632_IMM8]       = { false, 0xc1, IDX_TO_EXT(7), "sar", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_LEA_R1632_M]               = { false, 0x8d, IDX_TO_EXT(-1), "lea", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_RET]                   = { false, 0xc3, IDX_TO_EXT(-1), "ret", XPX_NONE }, +    [XOP_NOP]                       = { false, 0x90, IDX_TO_EXT(-1), "nop", XPX_NONE }, +    [XOP_XCHG_R1632_E_AX]           = { true, 0x90, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XCHG_R1632_E_CX]           = { true, 0x91, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XCHG_R1632_E_DX]           = { true, 0x92, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XCHG_R1632_E_BX]           = { true, 0x93, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XCHG_R1632_E_SP]           = { true, 0x94, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XCHG_R1632_E_BP]           = { true, 0x95, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XCHG_R1632_E_SI]           = { true, 0x96, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_XCHG_R1632_E_DI]           = { true, 0x97, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_MOV_RM8_IMM8]          = { false, 0xc6, IDX_TO_EXT(0), "mov", XPX_NONE }, -    [XOP_MOV_RM1632_IMM1632]    = { false, 0xc7, IDX_TO_EXT(0), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_AL_MOFFS8]             = { false, 0xa0, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_E_AX_MOFFS1632]        = { false, 0xa1, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_MOFFS8_AL]             = { false, 0xa2, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_MOFFS1632_E_AX]        = { false, 0xa3, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_LEAVE]                 = { false, 0xc9, IDX_TO_EXT(-1), "leave", XPX_NONE }, +    [XOP_TEST_AL_IMM8]              = { false, 0xa8, IDX_TO_EXT(-1), "test", XPX_NONE }, +    [XOP_TEST_E_AX_IMM1632]         = { false, 0xa9, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_INT_3]                 = { false, 0xcc, IDX_TO_EXT(-1), "int", XPX_NONE }, -    [XOP_INT]                   = { false, 0xcd, IDX_TO_EXT(-1), "int", XPX_NONE }, +    [XOP_SCAS_AL_M8]                = { false, 0xae, IDX_TO_EXT(-1), "scas", XPX_NONE }, -    [XOP_SHL_RM1632_CL]         = { false, 0xd3, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_AL_IMM8]               = { true, 0xb0, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_CL_IMM8]               = { true, 0xb1, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_DL_IMM8]               = { true, 0xb2, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_BL_IMM8]               = { true, 0xb3, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_AH_IMM8]               = { true, 0xb4, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_CH_IMM8]               = { true, 0xb5, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_DH_IMM8]               = { true, 0xb6, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_BH_IMM8]               = { true, 0xb7, IDX_TO_EXT(-1), "mov", XPX_NONE }, +    [XOP_MOV_E_AX_IMM1632]          = { true, 0xb8, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_E_CX_IMM1632]          = { true, 0xb9, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_E_DX_IMM1632]          = { true, 0xba, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_E_BX_IMM1632]          = { true, 0xbb, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_E_SP_IMM1632]          = { true, 0xbc, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_E_BP_IMM1632]          = { true, 0xbd, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_E_SI_IMM1632]          = { true, 0xbe, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_E_DI_IMM1632]          = { true, 0xbf, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_CALL_REL1632]          = { false, 0xe8, IDX_TO_EXT(-1), "call", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_JMP_REL1632]           = { false, 0xe9, IDX_TO_EXT(-1), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_JMP_REL8]              = { false, 0xeb, IDX_TO_EXT(-1), "jmp", XPX_NONE }, -    [XOP_HLT]                   = { false, 0xf4, IDX_TO_EXT(-1), "hlt", XPX_NONE }, +    [XOP_ROL_RM1632_IMM8]           = { false, 0xc1, IDX_TO_EXT(0), "rol", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_ROR_RM1632_IMM8]           = { false, 0xc1, IDX_TO_EXT(1), "ror", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_RCL_RM1632_IMM8]           = { false, 0xc1, IDX_TO_EXT(2), "rcl", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_RCR_RM1632_IMM8]           = { false, 0xc1, IDX_TO_EXT(3), "rcr", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SHL_RM1632_IMM8]           = { false, 0xc1, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SHR_RM1632_IMM8]           = { false, 0xc1, IDX_TO_EXT(5), "shr", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SAL_RM1632_IMM8]           = { false, 0xc1, IDX_TO_EXT(6), "sal", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_SAR_RM1632_IMM8]           = { false, 0xc1, IDX_TO_EXT(7), "sar", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_TEST_RM8_IMM8]         = { false, 0xf6, IDX_TO_EXT(0), "test", XPX_NONE }, -    [XOP_TEST_RM8_IMM8_BIS]     = { false, 0xf6, IDX_TO_EXT(1), "test", XPX_NONE }, -    [XOP_NOT_RM8]               = { false, 0xf6, IDX_TO_EXT(2), "not", XPX_NONE }, -    [XOP_TEST_RM1632_IMM1632]   = { false, 0xf7, IDX_TO_EXT(0), "test", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_TEST_RM1632_IMM1632_BIS] = { false, 0xf7, IDX_TO_EXT(1), "test", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_NOT_RM1632]            = { false, 0xf7, IDX_TO_EXT(2), "not", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_RET]                       = { false, 0xc3, IDX_TO_EXT(-1), "ret", XPX_NONE }, -    [XOP_IMUL_RM1632]           = { false, 0xf7, IDX_TO_EXT(5), "imul", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_MOV_RM8_IMM8]              = { false, 0xc6, IDX_TO_EXT(0), "mov", XPX_NONE }, +    [XOP_MOV_RM1632_IMM1632]        = { false, 0xc7, IDX_TO_EXT(0), "mov", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_CLD]                   = { false, 0xfc, IDX_TO_EXT(-1), "cld", XPX_NONE }, -    [XOP_INC_RM8]               = { false, 0xfe, IDX_TO_EXT(0), "inc", XPX_NONE }, -    [XOP_DEC_RM8]               = { false, 0xfe, IDX_TO_EXT(1), "dec", XPX_NONE }, -    [XOP_INC_RM1632]            = { false, 0xff, IDX_TO_EXT(0), "inc", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_DEC_RM1632]            = { false, 0xff, IDX_TO_EXT(1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_CALL_RM1632]           = { false, 0xff, IDX_TO_EXT(2), "call", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_JMP_RM1632]            = { false, 0xff, IDX_TO_EXT(4), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, -    [XOP_PUSH_RM1632]           = { false, 0xff, IDX_TO_EXT(6), "push", XPX_OPERAND_SIZE_OVERRIDE } +    [XOP_LEAVE]                     = { false, 0xc9, IDX_TO_EXT(-1), "leave", XPX_NONE }, + + +    [XOP_INT_3]                     = { false, 0xcc, IDX_TO_EXT(-1), "int", XPX_NONE }, +    [XOP_INT]                       = { false, 0xcd, IDX_TO_EXT(-1), "int", XPX_NONE }, + + +    [XOP_SHL_RM1632_CL]             = { false, 0xd3, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, + + +    [XOP_CALL_REL1632]              = { false, 0xe8, IDX_TO_EXT(-1), "call", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JMP_REL1632]               = { false, 0xe9, IDX_TO_EXT(-1), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, + +    [XOP_JMP_REL8]                  = { false, 0xeb, IDX_TO_EXT(-1), "jmp", XPX_NONE }, + +    [XOP_HLT]                       = { false, 0xf4, IDX_TO_EXT(-1), "hlt", XPX_NONE }, + +    [XOP_TEST_RM8_IMM8]             = { false, 0xf6, IDX_TO_EXT(0), "test", XPX_NONE }, +    [XOP_TEST_RM8_IMM8_BIS]         = { false, 0xf6, IDX_TO_EXT(1), "test", XPX_NONE }, +    [XOP_NOT_RM8]                   = { false, 0xf6, IDX_TO_EXT(2), "not", XPX_NONE }, + +    [XOP_TEST_RM1632_IMM1632]       = { false, 0xf7, IDX_TO_EXT(0), "test", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_TEST_RM1632_IMM1632_BIS]   = { false, 0xf7, IDX_TO_EXT(1), "test", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_NOT_RM1632]                = { false, 0xf7, IDX_TO_EXT(2), "not", XPX_OPERAND_SIZE_OVERRIDE }, + +    [XOP_IMUL_RM1632]               = { false, 0xf7, IDX_TO_EXT(5), "imul", XPX_OPERAND_SIZE_OVERRIDE }, + + +    [XOP_CLD]                       = { false, 0xfc, IDX_TO_EXT(-1), "cld", XPX_NONE }, + + +    [XOP_INC_RM8]                   = { false, 0xfe, IDX_TO_EXT(0), "inc", XPX_NONE }, +    [XOP_DEC_RM8]                   = { false, 0xfe, IDX_TO_EXT(1), "dec", XPX_NONE }, +    [XOP_INC_RM1632]                = { false, 0xff, IDX_TO_EXT(0), "inc", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_DEC_RM1632]                = { false, 0xff, IDX_TO_EXT(1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_CALL_RM1632]               = { false, 0xff, IDX_TO_EXT(2), "call", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_JMP_RM1632]                = { false, 0xff, IDX_TO_EXT(4), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, +    [XOP_PUSH_RM1632]               = { false, 0xff, IDX_TO_EXT(6), "push", XPX_OPERAND_SIZE_OVERRIDE }  }; diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index ad50834..de5f124 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -50,11 +50,12 @@ typedef enum _X86Opcodes      XOP_JE_REL1632,                         /* je ([0x66] 0x0f 0x84)       */      XOP_JNE_REL1632,                        /* jne ([0x66] 0x0f 0x85)      */ - +    XOP_JBE_REL1632,                        /* jbe ([0x66] 0x0f 0x86)      */      XOP_JA_REL1632,                         /* jne ([0x66] 0x0f 0x87)      */      XOP_JGE_REL1632,                        /* jge ([0x66] 0x0f 0x8d)      */      XOP_JLE_REL1632,                        /* jle ([0x66] 0x0f 0x8e)      */ +    XOP_JG_REL1632,                         /* jle ([0x66] 0x0f 0x8f)      */      XOP_SETE_RM8,                           /* sete ([0x66] 0x0f 0x94)     */      XOP_SETNE_RM8,                          /* setne ([0x66] 0x0f 0x95)    */ @@ -65,6 +66,10 @@ typedef enum _X86Opcodes      XOP_ADC_RM8_R8,                         /* adc (0x10)                  */      XOP_AND_RM8_R8,                         /* and (0x20)                  */ +    XOP_AND_RM1632_R1632,                   /* and ([0x66] 0x21)           */ + +    XOP_AND_AL_IMM8,                        /* and (0x24)                  */ +    XOP_AND_E_AX_IMM1632,                   /* and ([0x66] 0x25)           */      XOP_SUB_RM1632_R1632,                   /* sub ([0x66] 0x29)           */ @@ -81,8 +86,11 @@ typedef enum _X86Opcodes      XOP_XOR_AL_IMM8,                        /* xor (0x34)                  */      XOP_XOR_E_AX_IMM1632,                   /* xor ([0x66] 0x35)           */ -      XOP_CMP_RM1632_R1632,                   /* cmp ([0x66] 0x39)           */ + +    XOP_CMP_R1632_RM1632,                   /* cmp ([0x66] 0x3b)           */ + +      XOP_INC_E_AX,                           /* inc ([0x66] 0x40)           */      XOP_INC_E_CX,                           /* inc ([0x66] 0x41)           */      XOP_INC_E_DX,                           /* inc ([0x66] 0x42)           */ @@ -118,6 +126,7 @@ typedef enum _X86Opcodes      XOP_PUSH_IMM1632,                       /* push ([0x66] 0x68)          */ +    XOP_IMUL_R1632_RM1632_IMM1632,          /* imul ([0x66] 0x69)          */      XOP_IMUL_RM1632_IMM8,                   /* imul ([0x66] 0x6b)          */ diff --git a/src/arch/x86/op_and.c b/src/arch/x86/op_and.c index c923441..d59c8f0 100644 --- a/src/arch/x86/op_and.c +++ b/src/arch/x86/op_and.c @@ -38,6 +38,75 @@  *                addr = adresse virtuelle de l'instruction.                   *  *                proc = architecture ciblée par le désassemblage.             *  *                                                                             * +*  Description : Décode une instruction de type 'and al, ...' (8 bits).       * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *x86_read_instr_and_al_imm8(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ + +    result = g_x86_instruction_new(XOP_AND_AL_IMM8); + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_AL, X86_OTP_IMM8)) +    { +        /* TODO free(result);*/ +        return NULL; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                proc = architecture ciblée par le désassemblage.             * +*                                                                             * +*  Description : Décode une instruction de type 'and [e]ax, ...' (16/32 bits).* +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *x86_read_instr_and_e_ax_imm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = g_x86_instruction_new(XOP_AND_E_AX_IMM1632); + +    oprsize = g_x86_processor_get_operand_size(proc, prefix); + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_E_AX, X86_OTP_IMM1632, oprsize)) +    { +        /* TODO free(result);*/ +        return NULL; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                proc = architecture ciblée par le désassemblage.             * +*                                                                             *  *  Description : Décode une instruction de type 'and' (8 bits).               *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           * @@ -65,6 +134,11 @@ GArchInstruction *x86_read_instr_and_rm8_imm8(const bin_t *data, off_t *pos, off  /******************************************************************************  *                                                                             * +*  Paramètres  : data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                proc = architecture ciblée par le désassemblage.             *  *                                                                             *  *  Description : Décode une instruction de type 'and' (8 bits).               *  *                                                                             * @@ -161,3 +235,39 @@ GArchInstruction *x86_read_instr_and_rm1632_imm1632(const bin_t *data, off_t *po      return result;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                proc = architecture ciblée par le désassemblage.             * +*                                                                             * +*  Description : Décode une instruction de type 'and' (16 ou 32 bits).        * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *x86_read_instr_and_rm1632_r1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = g_x86_instruction_new(XOP_AND_RM1632_R1632); + +    oprsize = g_x86_processor_get_operand_size(proc, prefix); + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_R1632, oprsize)) +    { +        /* TODO free(result);*/ +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_cmp.c b/src/arch/x86/op_cmp.c index 709054b..5dfa20d 100644 --- a/src/arch/x86/op_cmp.c +++ b/src/arch/x86/op_cmp.c @@ -38,6 +38,42 @@  *                addr = adresse virtuelle de l'instruction.                   *  *                proc = architecture ciblée par le désassemblage.             *  *                                                                             * +*  Description : Décode une instruction de type 'cmp' (16 ou 32 bits).        * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *x86_read_instr_cmp_r1632_rm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = g_x86_instruction_new(XOP_CMP_R1632_RM1632); + +    oprsize = g_x86_processor_get_operand_size(proc, prefix); + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, oprsize)) +    { +        /* TODO free(result);*/ +        return NULL; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                proc = architecture ciblée par le désassemblage.             * +*                                                                             *  *  Description : Décode une instruction de type 'cmp' (8 bits).               *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           * diff --git a/src/arch/x86/op_int.c b/src/arch/x86/op_int.c index cbeda87..eef2c1c 100644 --- a/src/arch/x86/op_int.c +++ b/src/arch/x86/op_int.c @@ -55,7 +55,7 @@ GArchInstruction *x86_read_instr_int_3(const bin_t *data, off_t *pos, off_t len,      result = g_x86_instruction_new(XOP_INT_3);      three = g_imm_operand_new_from_value(AOS_8_BITS, 3); -    g_arch_instruction_attach_one_operand(result, three); +    g_arch_instruction_attach_extra_operand(result, three);      return result; diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c index 1f7db24..be8d305 100644 --- a/src/arch/x86/op_jump.c +++ b/src/arch/x86/op_jump.c @@ -140,6 +140,42 @@ GArchInstruction *x86_read_instr_jb_rel8(const bin_t *data, off_t *pos, off_t le  *                addr = adresse virtuelle de l'instruction.                   *  *                proc = architecture ciblée par le désassemblage.             *  *                                                                             * +*  Description : Décode une instruction de type 'je' (saut 16/32b si inf.).   * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *x86_read_instr_jbe_rel1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = g_x86_instruction_new(XOP_JBE_REL1632); + +    oprsize = g_x86_processor_get_operand_size(proc, prefix); + +    if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL1632, oprsize, addr)) +    { +        /* TODO free(result);*/ +        return NULL; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                proc = architecture ciblée par le désassemblage.             * +*                                                                             *  *  Description : Décode une instruction de type 'je' (saut 8b si égal).       *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           * @@ -242,6 +278,42 @@ GArchInstruction *x86_read_instr_jg_rel8(const bin_t *data, off_t *pos, off_t le  *                addr = adresse virtuelle de l'instruction.                   *  *                proc = architecture ciblée par le désassemblage.             *  *                                                                             * +*  Description : Décode une instruction de type 'jg' (saut 16/32b si sup.).   * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GArchInstruction *x86_read_instr_jg_rel1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = g_x86_instruction_new(XOP_JG_REL1632); + +    oprsize = g_x86_processor_get_operand_size(proc, prefix); + +    if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL1632, oprsize, addr)) +    { +        /* TODO free(result);*/ +        return NULL; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data = flux de données à analyser.                           * +*                pos  = position courante dans ce flux. [OUT]                 * +*                len  = taille totale des données à analyser.                 * +*                addr = adresse virtuelle de l'instruction.                   * +*                proc = architecture ciblée par le désassemblage.             * +*                                                                             *  *  Description : Décode une instruction de type 'jge' (saut 16/32b si sup.).  *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           * diff --git a/src/arch/x86/op_mul.c b/src/arch/x86/op_mul.c index f1ed641..2f29929 100644 --- a/src/arch/x86/op_mul.c +++ b/src/arch/x86/op_mul.c @@ -46,6 +46,42 @@  *                                                                             *  ******************************************************************************/ +GArchInstruction *x86_read_instr_imul_r1632_rm1632_imm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ +    GArchInstruction *result;               /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = g_x86_instruction_new(XOP_IMUL_R1632_RM1632_IMM1632); + +    oprsize = g_x86_processor_get_operand_size(proc, prefix); + +    if (!x86_read_three_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) +    { +        /* TODO free(result);*/ +        return NULL; +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data   = flux de données à analyser.                         * +*                pos    = position courante dans ce flux. [OUT]               * +*                len    = taille totale des données à analyser.               * +*                offset = adresse virtuelle de l'instruction.                 * +*                proc   = architecture ciblée par le désassemblage.           * +*                                                                             * +*  Description : Décode une instruction de type 'imul' (16 ou 32 bits).       * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +  GArchInstruction *x86_read_instr_imul_rm1632(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)  {      GArchInstruction *result;               /* Instruction à retourner     */ diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h index 5317415..e45b107 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -69,6 +69,12 @@ GArchInstruction *x86_read_instr_add_rm1632_imm1632(const bin_t *, off_t *, off_  /* Décode une instruction de type 'add' (16 ou 32 bits). */  GArchInstruction *x86_read_instr_add_rm1632_r1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'and al, ...' (8 bits). */ +GArchInstruction *x86_read_instr_and_al_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); + +/* Décode une instruction de type 'and [e]ax, ...' (16/32 bits). */ +GArchInstruction *x86_read_instr_and_e_ax_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +  /* Décode une instruction de type 'and' (8 bits). */  GArchInstruction *x86_read_instr_and_rm8_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); @@ -81,6 +87,9 @@ GArchInstruction *x86_read_instr_and_rm1632_imm8(const bin_t *, off_t *, off_t,  /* Décode une instruction de type 'and' (16 ou 32 bits). */  GArchInstruction *x86_read_instr_and_rm1632_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'and' (16 ou 32 bits). */ +GArchInstruction *x86_read_instr_and_rm1632_r1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +  /* Décode une instruction de type 'call'. */  GArchInstruction *x86_read_instr_call_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); @@ -90,6 +99,9 @@ GArchInstruction *x86_read_instr_call_rm1632(const bin_t *, off_t *, off_t, vmpa  /* Décode une instruction de type 'cld'. */  GArchInstruction *x86_read_instr_cld(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'cmp' (16 ou 32 bits). */ +GArchInstruction *x86_read_instr_cmp_r1632_rm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +  /* Décode une instruction de type 'cmp' (8 bits). */  GArchInstruction *x86_read_instr_cmp_rm8_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); @@ -115,6 +127,9 @@ GArchInstruction *x86_read_instr_dec_rm1632(const bin_t *, off_t *, off_t, vmpa_  GArchInstruction *x86_read_instr_hlt(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);  /* Décode une instruction de type 'imul' (16 ou 32 bits). */ +GArchInstruction *x86_read_instr_imul_r1632_rm1632_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); + +/* Décode une instruction de type 'imul' (16 ou 32 bits). */  GArchInstruction *x86_read_instr_imul_rm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);  /* Décode une instruction de type 'imul' (16 ou 32 bits). */ @@ -144,6 +159,9 @@ GArchInstruction *x86_read_instr_ja_rel1632(const bin_t *, off_t *, off_t, vmpa_  /* Décode une instruction de type 'jb' (saut 8b si inférieur). */  GArchInstruction *x86_read_instr_jb_rel8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'je' (saut 16/32b si inf.). */ +GArchInstruction *x86_read_instr_jbe_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +  /* Décode une instruction de type 'je' (saut 8b si égal). */  GArchInstruction *x86_read_instr_je_rel8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); @@ -153,6 +171,9 @@ GArchInstruction *x86_read_instr_je_rel1632(const bin_t *, off_t *, off_t, vmpa_  /* Décode une instruction de type 'jg' (saut 8b si supérieur). */  GArchInstruction *x86_read_instr_jg_rel8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +/* Décode une instruction de type 'jg' (saut 16/32b si sup.). */ +GArchInstruction *x86_read_instr_jg_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); +  /* Décode une instruction de type 'jge' (saut 16/32b si sup.). */  GArchInstruction *x86_read_instr_jge_rel1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *); diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index eb6f5f3..d0e923f 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -512,7 +512,7 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,      if (g_x86_register_is_base_pointer(reg) && mod == 0x00)      {          /* FIXME *///free_x86_register(reg); -        return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE); +        return g_imm_operand_new_from_data(MDS_32_BITS/* FIXME */, data, pos, len, SRE_LITTLE /*FIXME*/);      }      result = g_object_new(G_TYPE_X86_MOD_RM_OPERAND, NULL); @@ -552,19 +552,19 @@ GArchOperand *g_x86_mod_rm_operand_new(const bin_t *data, off_t *pos, off_t len,                  /* FIXME *///free_x86_register(result->base);                  result->base = NULL; -                result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE); +                result->displacement = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */);                  if (result->displacement == NULL) goto gxmron_error;              }              break;          case 0x40: -            result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE); +            result->displacement = g_imm_operand_new_from_data(MDS_8_BITS_SIGNED, data, pos, len, SRE_LITTLE /* FIXME */);              if (result->displacement == NULL) goto gxmron_error;              break;          case 0x80: -            result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE); +            result->displacement = g_imm_operand_new_from_data(MDS_32_BITS_SIGNED/* FIXME ! 16/32 */, data, pos, len, SRE_LITTLE /* FIXME */);              if (result->displacement == NULL) goto gxmron_error;              break; @@ -805,15 +805,15 @@ GArchOperand *g_x86_relative_operand_new(const bin_t *data, off_t *pos, off_t le      switch (size)      {          case AOS_8_BITS_UNSIGNED: -            read_s8(&val8, data, pos, len, SRE_LITTLE); +            read_s8(&val8, data, pos, len, SRE_LITTLE /* FIXME */);              address = base + (*pos - init_pos) + val8;              break;          case AOS_16_BITS_UNSIGNED: -            read_s16(&val16, data, pos, len, SRE_LITTLE); +            read_s16(&val16, data, pos, len, SRE_LITTLE /* FIXME */);              address = base + (*pos - init_pos) + val16;              break;          case AOS_32_BITS_UNSIGNED: -            read_s32(&val32, data, pos, len, SRE_LITTLE); +            read_s32(&val32, data, pos, len, SRE_LITTLE /* FIXME */);              address = base + (*pos - init_pos) + val32;              break;          default: @@ -945,7 +945,7 @@ GArchOperand *g_x86_moffs_operand_new(const bin_t *data, off_t *pos, off_t len,      result = NULL; -    offset = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE); +    offset = g_imm_operand_new_from_data(size/* FIXME : !convert mds/aos */, data, pos, len, SRE_LITTLE /* FIXME */);      if (offset != NULL)      { @@ -997,10 +997,10 @@ static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *operan  *                data  = flux de données à analyser.                          *  *                pos   = position courante dans ce flux. [OUT]                *  *                len   = taille totale des données à analyser.                * -*                type  = type de l'opérande.                                  * +*                count = quantité d'opérandes à lire.                         *  *                ...   = éventuelle(s) information(s) complémentaire(s).      *  *                                                                             * -*  Description : Procède à la lecture d'un opérande donné.                    * +*  Description : Procède à la lecture de trois opérandes donnés.              *  *                                                                             *  *  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   *  *                                                                             * @@ -1008,135 +1008,39 @@ static void g_x86_moffs_operand_add_to_gtk_buffer(const GX86MOffsOperand *operan  *                                                                             *  ******************************************************************************/ -bool x86_read_one_operand(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, X86OperandType type, ...) +bool _x86_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, unsigned int count, ...)  { +    bool result;                            /* Bilan à retourner           */      va_list ap;                             /* Liste des compléments       */ +    X86OperandType types[MAX_OPERANDS];     /* Type des opérandes          */ +    unsigned int i;                         /* Boucle de parcours          */ +    bool op1_first;                         /* Position de l'opérande  #1  */ +    bool op2_first;                         /* Position de l'opérande  #2  */      AsmOperandSize oprsize;                 /* Taille des opérandes        */ +    off_t op_pos[MAX_OPERANDS];             /* Position après lecture      */      vmpa_t offset;                          /* Adresse courante            */      bin_t base;                             /* Indice du premier registre  */      GArchOperand *op;                       /* Opérande unique décodé      */ -    va_start(ap, type); - -    /* Lecture du premier opérande */ - -    switch (type) -    { -        case X86_OTP_IMM8: -            op = g_imm_operand_new_from_data(MDS_8_BITS, data, pos, len, SRE_LITTLE); -            break; - -        case X86_OTP_IMM1632: -            oprsize = va_arg(ap, AsmOperandSize); -            op = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, pos, len, SRE_LITTLE); -            break; - -        case X86_OTP_REL8: -            offset = va_arg(ap, vmpa_t); -            op = g_x86_relative_operand_new(data, pos, len, AOS_8_BITS, offset + 1); -            break; - -        case X86_OTP_REL1632: -            oprsize = va_arg(ap, AsmOperandSize); -            offset = va_arg(ap, vmpa_t); -            op = g_x86_relative_operand_new(data, pos, len, oprsize, offset + 1); -            break; - -        case X86_OTP_R8: -            op = g_x86_register_operand_new_from_mod_rm(data, pos, len, AOS_8_BITS, true); -            break; - -        case X86_OTP_R1632: -            oprsize = va_arg(ap, AsmOperandSize); -            op = g_x86_register_operand_new_from_mod_rm(data, pos, len, oprsize, true); -            break; - -        case X86_OTP_OP_R8: -            base = (bin_t)va_arg(ap, int); -            op = g_x86_register_operand_new_from_opcode(data, pos, len, AOS_8_BITS, base); -            break; - -        case X86_OTP_OP_R1632: -            oprsize = va_arg(ap, AsmOperandSize); -            base = (bin_t)va_arg(ap, int); -            op = g_x86_register_operand_new_from_opcode(data, pos, len, oprsize, base); -            break; - -        case X86_OTP_RM8: -            op = g_x86_mod_rm_operand_new(data, pos, len, AOS_8_BITS); -            break; - -        case X86_OTP_RM1632: -            oprsize = va_arg(ap, AsmOperandSize); -            op = g_x86_mod_rm_operand_new(data, pos, len, oprsize); -            break; - -        case X86_OTP_CL: -            op = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS); -            break; - -        case X86_OTP_AL: -            op = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS); -            break; - -        case X86_OTP_E_AX: -            oprsize = va_arg(ap, AsmOperandSize); -            op = g_x86_register_operand_new_from_index(0x00, oprsize); -            break; - -    } - -    va_end(ap); - -    if (op == NULL) return false; - -    g_arch_instruction_attach_one_operand(instr, op); - -    return true; - -} +    if (count > MAX_OPERANDS) return false; +    result = true; -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr = instruction dont la définition est à compléter. [OUT]* -*                data  = flux de données à analyser.                          * -*                pos   = position courante dans ce flux. [OUT]                * -*                len   = taille totale des données à analyser.                * -*                type1 = type du premier opérande.                            * -*                type2 = type du second opérande.                             * -*                ...   = éventuelle(s) information(s) complémentaire(s).      * -*                                                                             * -*  Description : Procède à la lecture de deux opérandes donnés.               * -*                                                                             * -*  Retour      : Bilan de l'opération : true en cas de succès, false sinon.   * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ +    va_start(ap, count); -bool x86_read_two_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, X86OperandType type1, X86OperandType type2, ...) -{ -    va_list ap;                             /* Liste des compléments       */ -    AsmOperandSize oprsize;                 /* Taille des opérandes        */ -    bool op1_first;                         /* Position de l'opérande  #1  */ -    bool op2_first;                         /* Position de l'opérande  #2  */ -    off_t op1_pos;                          /* Position après lecture #1   */ -    bin_t base;                             /* Indice du premier registre  */ -    GArchOperand *op1;                      /* Premier opérande décodé     */ -    off_t op2_pos;                          /* Position après lecture #2   */ -    GArchOperand *op2;                      /* Second opérande décodé      */ +    /* Types à charger */ -    va_start(ap, type2); +    for (i = 0; i < count; i++) +        types[i] = va_arg(ap, AsmOperandSize); -    oprsize = AOS_UNDEFINED; +    /* Initialisations */ -    if (type1 & X86_OTP_RM_TYPE) +    if (types[0] & X86_OTP_RM_TYPE)      {          op1_first = true;          op2_first = false;      } -    else if (type2 & X86_OTP_RM_TYPE) +    else if (types[1] & X86_OTP_RM_TYPE)      {          op1_first = false;          op2_first = true; @@ -1147,154 +1051,115 @@ bool x86_read_two_operands(GArchInstruction *instr, const bin_t *data, off_t *po          op2_first = false;      } -    /* Lecture du premier opérande */ - -    op1_pos = *pos; - -    switch (type1) -    { -        case X86_OTP_IMM8: -            op1 = g_imm_operand_new_from_data(MDS_8_BITS, data, &op1_pos, len, SRE_LITTLE); -            break; - -        case X86_OTP_IMM1632: -            if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); -            op1 = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op1_pos, len, SRE_LITTLE); -            break; - -        case X86_OTP_MOFFS8: -            op1 = g_x86_moffs_operand_new(data, &op1_pos, len, AOS_8_BITS); -            break; - -        case X86_OTP_MOFFS1632: -            oprsize = va_arg(ap, AsmOperandSize); -            op1 = g_x86_moffs_operand_new(data, &op1_pos, len, oprsize); -            break; - -        case X86_OTP_R8: -            op1 = g_x86_register_operand_new_from_mod_rm(data, &op1_pos, len, AOS_8_BITS, op1_first); -            break; - -        case X86_OTP_R1632: -            oprsize = va_arg(ap, AsmOperandSize); -            op1 = g_x86_register_operand_new_from_mod_rm(data, &op1_pos, len, oprsize, op1_first); -            break; - -        case X86_OTP_OP_R8: -            base = (bin_t)va_arg(ap, int); -            op1 = g_x86_register_operand_new_from_opcode(data, &op1_pos, len, AOS_8_BITS, base); -            break; - -        case X86_OTP_OP_R1632: -            oprsize = va_arg(ap, AsmOperandSize); -            base = (bin_t)va_arg(ap, int); -            op1 = g_x86_register_operand_new_from_opcode(data, &op1_pos, len, oprsize, base); -            break; - -        case X86_OTP_RM8: -            op1 = g_x86_mod_rm_operand_new(data, &op1_pos, len, AOS_8_BITS); -            break; - -        case X86_OTP_RM1632: -            oprsize = va_arg(ap, AsmOperandSize); -            op1 = g_x86_mod_rm_operand_new(data, &op1_pos, len, oprsize); -            break; - -        case X86_OTP_CL: -            op1 = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS); -            break; - -        case X86_OTP_AL: -            op1 = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS); -            break; - -        case X86_OTP_E_AX: -            oprsize = va_arg(ap, AsmOperandSize); -            op1 = g_x86_register_operand_new_from_index(0x00, oprsize); -            break; - -    } - -    if (op1 == NULL) -    { -        va_end(ap); -        return false; -    } - -    /* Lecture du second opérande */ +    oprsize = AOS_UNDEFINED; -    if ((type1 & X86_OTP_REG_TYPE || type1 & X86_OTP_RM_TYPE) && (type2 & X86_OTP_IMM_TYPE)) -        op2_pos = op1_pos; -    else op2_pos = *pos; +    /* Lecture des opérandes */ -    switch (type2) +    for (i = 0; i < count && result; i++)      { -        case X86_OTP_IMM8: -            op2 = g_imm_operand_new_from_data(MDS_8_BITS, data, &op2_pos, len, SRE_LITTLE); -            break; - -        case X86_OTP_IMM1632: -            if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); -            op2 = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op2_pos, len, SRE_LITTLE); -            break; - -        case X86_OTP_MOFFS8: -            op2 = g_x86_moffs_operand_new(data, &op2_pos, len, AOS_8_BITS); -            break; - -        case X86_OTP_MOFFS1632: -            if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); -            op2 = g_x86_moffs_operand_new(data, &op2_pos, len, oprsize); -            break; - -        case X86_OTP_R8: -            op2 = g_x86_register_operand_new_from_mod_rm(data, &op2_pos, len, AOS_8_BITS, op2_first); -            break; - -        case X86_OTP_R1632: -            if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); -            op2 = g_x86_register_operand_new_from_mod_rm(data, &op2_pos, len, oprsize, op2_first); -            break; +        /* Tête de lecture */ +        switch (i) +        { +            case 0: +                op_pos[0] = *pos; +                break; -        case X86_OTP_RM8: -            op2 = g_x86_mod_rm_operand_new(data, &op2_pos, len, AOS_8_BITS); -            break; +            case 1: +                if ((types[0] & X86_OTP_REG_TYPE || types[0] & X86_OTP_RM_TYPE) && (types[1] & X86_OTP_IMM_TYPE)) +                    op_pos[1] = op_pos[0]; +                else op_pos[1] = *pos; +                *pos = op_pos[0]; +                break; -        case X86_OTP_RM1632: -            if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); -            op2 = g_x86_mod_rm_operand_new(data, &op2_pos, len, oprsize); -            break; +            case 2 ... MAX_OPERANDS: +                *pos = MAX(*pos, op_pos[i - 1]); +                op_pos[i] = *pos; -        case X86_OTP_CL: -            op2 = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS); -            break; +        } -        case X86_OTP_AL: -            op2 = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS); -            break; +        /* Lecture */ +        switch (types[i]) +        { +            case X86_OTP_IMM8: +                op = g_imm_operand_new_from_data(MDS_8_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */); +                break; + +            case X86_OTP_IMM1632: +                if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); +                op = g_imm_operand_new_from_data(oprsize == AOS_32_BITS ? MDS_32_BITS : MDS_16_BITS, data, &op_pos[i], len, SRE_LITTLE /* FIXME */); +                break; + +            case X86_OTP_MOFFS8: +                op = g_x86_moffs_operand_new(data, &op_pos[i], len, AOS_8_BITS); +                break; + +            case X86_OTP_MOFFS1632: +                if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); +                op = g_x86_moffs_operand_new(data, &op_pos[i], len, oprsize); +                break; + +            case X86_OTP_REL8: +                offset = va_arg(ap, vmpa_t); +                op = g_x86_relative_operand_new(data, &op_pos[i], len, AOS_8_BITS, offset + 1); +                break; + +            case X86_OTP_REL1632: +                if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); +                offset = va_arg(ap, vmpa_t); +                op = g_x86_relative_operand_new(data, &op_pos[i], len, oprsize, offset + 1); +                break; + +            case X86_OTP_R8: +                op = g_x86_register_operand_new_from_mod_rm(data, &op_pos[i], len, AOS_8_BITS, i == 0 ? op1_first : op2_first); +                break; + +            case X86_OTP_R1632: +                if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); +                op = g_x86_register_operand_new_from_mod_rm(data, &op_pos[i], len, oprsize, i == 0 ? op1_first : op2_first); +                break; + +            case X86_OTP_OP_R8: +                base = (bin_t)va_arg(ap, int); +                op = g_x86_register_operand_new_from_opcode(data, &op_pos[i], len, AOS_8_BITS, base); +                break; + +            case X86_OTP_OP_R1632: +                if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); +                base = (bin_t)va_arg(ap, int); +                op = g_x86_register_operand_new_from_opcode(data, &op_pos[i], len, oprsize, base); +                break; + +            case X86_OTP_RM8: +                op = g_x86_mod_rm_operand_new(data, &op_pos[i], len, AOS_8_BITS); +                break; + +            case X86_OTP_RM1632: +                if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); +                op = g_x86_mod_rm_operand_new(data, &op_pos[i], len, oprsize); +                break; + +            case X86_OTP_CL: +                op = g_x86_register_operand_new_from_index(0x01, AOS_8_BITS); +                break; + +            case X86_OTP_AL: +                op = g_x86_register_operand_new_from_index(0x00, AOS_8_BITS); +                break; + +            case X86_OTP_E_AX: +                if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); +                op = g_x86_register_operand_new_from_index(0x00, oprsize); +                break; -        case X86_OTP_E_AX: -            if (oprsize == AOS_UNDEFINED) oprsize = va_arg(ap, AsmOperandSize); -            op2 = g_x86_register_operand_new_from_index(0x00, oprsize); -            break; +        } -    } +        if (op == NULL) result = false; +        else g_arch_instruction_attach_extra_operand(instr, op); -    if (op2 == NULL) -    { -        free(op1); -        va_end(ap); -        return false;      } -    va_end(ap); - -    /* Assemblage final */ - -    *pos = MAX(op1_pos, op2_pos); - -    g_arch_instruction_attach_two_operands(instr, op1, op2); +    *pos = MAX(*pos, op_pos[i - 1]); -    return true; +    return result;  } diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h index cb04ca8..fc40b38 100644 --- a/src/arch/x86/operand.h +++ b/src/arch/x86/operand.h @@ -207,11 +207,16 @@ typedef enum _X86OperandType  } X86OperandType; -/* Procède à la lecture d'un opérande donné. */ -bool x86_read_one_operand(GArchInstruction *, const bin_t *data, off_t *pos, off_t, X86OperandType, ...); +/* Nombre maximal d'opérande */ +#define MAX_OPERANDS 3 -/* Procède à la lecture de deux opérandes donnés. */ -bool x86_read_two_operands(GArchInstruction *, const bin_t *data, off_t *pos, off_t, X86OperandType, X86OperandType, ...); + +#define x86_read_one_operand(instr, data, pos, len, ...) _x86_read_operands(instr, data, pos, len, 1, __VA_ARGS__) +#define x86_read_two_operands(instr, data, pos, len, ...) _x86_read_operands(instr, data, pos, len, 2, __VA_ARGS__) +#define x86_read_three_operands(instr, data, pos, len, ...) _x86_read_operands(instr, data, pos, len, 3, __VA_ARGS__) + +/* Procède à la lecture de n opérandes donnés. */ +bool _x86_read_operands(GArchInstruction *, const bin_t *, off_t *, off_t, unsigned int, ...); diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 15179e2..3dc5fc2 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -225,6 +225,19 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor              result = x86_read_instr_or_rm1632_r1632(data, pos, len, addr, prefix, proc);              break; + + +        case XOP_AND_AL_IMM8: +            result = x86_read_instr_and_al_imm8(data, pos, len, addr, prefix, proc); +            break; + +        case XOP_AND_E_AX_IMM1632: +            result = x86_read_instr_and_e_ax_imm1632(data, pos, len, addr, prefix, proc); +            break; + + + +          case XOP_OR_R8_RM8:              result = x86_read_instr_or_r8_rm8(data, pos, len, addr, prefix, proc);              break; @@ -246,6 +259,9 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor              result = x86_read_instr_jne_rel1632(data, pos, len, addr, prefix, proc);              break; +        case XOP_JBE_REL1632: +            result = x86_read_instr_jbe_rel1632(data, pos, len, addr, prefix, proc); +            break;          case XOP_JA_REL1632:              result = x86_read_instr_ja_rel1632(data, pos, len, addr, prefix, proc); @@ -270,6 +286,10 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor              result = x86_read_instr_jle_rel1632(data, pos, len, addr, prefix, proc);              break; +        case XOP_JG_REL1632: +            result = x86_read_instr_jg_rel1632(data, pos, len, addr, prefix, proc); +            break; +          case XOP_MOVZX_R1632_RM8:              result = x86_read_instr_movzx_r1632_rm8(data, pos, len, addr, prefix, proc); @@ -291,6 +311,10 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor              result = x86_read_instr_and_rm8_r8(data, pos, len, addr, prefix, proc);              break; +        case XOP_AND_RM1632_R1632: +            result = x86_read_instr_and_rm1632_r1632(data, pos, len, addr, prefix, proc); +            break; +          case XOP_SUB_RM1632_R1632:              result = x86_read_instr_sub_rm1632_r1632(data, pos, len, addr, prefix, proc); @@ -342,6 +366,13 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor              result = x86_read_instr_cmp_rm1632_r1632(data, pos, len, addr, prefix, proc);              break; + +        case XOP_CMP_R1632_RM1632: +            result = x86_read_instr_cmp_r1632_rm1632(data, pos, len, addr, prefix, proc); +            break; + + +          case XOP_INC_E_AX:          case XOP_INC_E_CX:          case XOP_INC_E_DX: @@ -391,6 +422,10 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor              result = x86_read_instr_push_imm1632(data, pos, len, addr, prefix, proc);              break; +        case XOP_IMUL_R1632_RM1632_IMM1632: +            result = x86_read_instr_imul_r1632_rm1632_imm1632(data, pos, len, addr, prefix, proc); +            break; +          case XOP_IMUL_RM1632_IMM8:              result = x86_read_instr_imul_rm1632_imm8(data, pos, len, addr, prefix, proc); | 
