diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/processor.c | 5 | ||||
| -rw-r--r-- | src/arch/x86/Makefile.am | 7 | ||||
| -rw-r--r-- | src/arch/x86/instruction.h | 28 | ||||
| -rw-r--r-- | src/arch/x86/op_adc.c | 38 | ||||
| -rw-r--r-- | src/arch/x86/op_add.c | 18 | ||||
| -rw-r--r-- | src/arch/x86/op_and.c | 38 | ||||
| -rw-r--r-- | src/arch/x86/op_cmp.c | 38 | ||||
| -rw-r--r-- | src/arch/x86/op_movzx.c | 68 | ||||
| -rw-r--r-- | src/arch/x86/op_or.c | 38 | ||||
| -rw-r--r-- | src/arch/x86/op_rcl.c | 68 | ||||
| -rw-r--r-- | src/arch/x86/op_rcr.c | 68 | ||||
| -rw-r--r-- | src/arch/x86/op_rol.c | 68 | ||||
| -rw-r--r-- | src/arch/x86/op_ror.c | 68 | ||||
| -rw-r--r-- | src/arch/x86/op_sar.c | 4 | ||||
| -rw-r--r-- | src/arch/x86/op_sbb.c | 38 | ||||
| -rw-r--r-- | src/arch/x86/op_shl.c | 68 | ||||
| -rw-r--r-- | src/arch/x86/op_shr.c | 68 | ||||
| -rw-r--r-- | src/arch/x86/op_sub.c | 38 | ||||
| -rw-r--r-- | src/arch/x86/op_xor.c | 40 | ||||
| -rw-r--r-- | src/arch/x86/opcodes.h | 56 | ||||
| -rw-r--r-- | src/arch/x86/processor.c | 346 | 
21 files changed, 1015 insertions, 193 deletions
| diff --git a/src/arch/processor.c b/src/arch/processor.c index fc9f773..1afb576 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -52,8 +52,11 @@ asm_instr *decode_instruction(const asm_processor *proc, const uint8_t *data, of  {      asm_instr *result;                      /* Représentation à renvoyer   */ +    off_t old_pos;                          /* Sauvegarde de la position   */ +    old_pos = *pos; +      result = proc->fetch_instr(proc, data, pos, len, offset); @@ -63,6 +66,8 @@ asm_instr *decode_instruction(const asm_processor *proc, const uint8_t *data, of      if (result == NULL)      { +        *pos = old_pos; +          printf("err while decoding opcode 0x%0hhx at 0x%08llx\n", data[*pos], offset);          result = create_db_instruction(data, pos, len);      } diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am index 139bcde..58ffaa8 100644 --- a/src/arch/x86/Makefile.am +++ b/src/arch/x86/Makefile.am @@ -17,12 +17,19 @@ libarchx86_a_SOURCES =					\  	op_leave.c							\  	op_nop.c							\  	op_mov.c							\ +	op_movzx.c							\  	op_or.c								\  	op_pop.c							\  	op_push.c							\ +	op_rcl.c							\ +	op_rcr.c							\  	op_ret.c							\ +	op_rol.c							\ +	op_ror.c							\  	op_sar.c							\  	op_sbb.c							\ +	op_shl.c							\ +	op_shr.c							\  	op_sub.c							\  	op_test.c							\  	op_xor.c							\ diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index baf911d..1c97255 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -92,11 +92,17 @@ typedef enum _X86Opcodes      X86_OP_JE_8,                            /* je (0x74)                   */      X86_OP_JNE_8,                           /* jne (0x75)                  */ -    X86_OP_XOR_RM8_IMM8,                    /* xor (0x81 6)                */ +    X86_OP_XOR_RM8_IMM8,                    /* xor (0x80 6)                */      X86_OP_CMP_RM8_IMM8,                    /* cmp (0x80 7)                */ -    X86_OP_ADD_RM1632_IMM1632,             /* add ([0x66] 0x81 0)         */ +    X86_OP_ADD_RM1632_IMM1632,              /* add ([0x66] 0x81 0)         */ +    X86_OP_OR_RM1632_IMM1632,               /* or ([0x66] 0x81 1)          */ +    X86_OP_ADC_RM1632_IMM1632,              /* adc ([0x66] 0x81 2)         */ +    X86_OP_SBB_RM1632_IMM1632,              /* sbb ([0x66] 0x81 3)         */ +    X86_OP_AND_RM1632_IMM1632,              /* and ([0x66] 0x81 4)         */ +    X86_OP_SUB_RM1632_IMM1632,              /* sub ([0x66] 0x81 5)         */      X86_OP_XOR_RM1632_IMM1632,              /* xor ([0x66] 0x81 6)         */ +    X86_OP_CMP_RM1632_IMM1632,              /* xor ([0x66] 0x81 7)         */      X86_OP_ADD_RM1632_IMM8,                 /* add ([0x66] 0x83 0)         */      X86_OP_OR_RM1632_IMM8,                  /* or ([0x66] 0x83 1)          */ @@ -135,6 +141,13 @@ typedef enum _X86Opcodes      X86_OP_MOV_E_SI,                        /* mov ([0x66] 0xbe)           */      X86_OP_MOV_E_DI,                        /* mov ([0x66] 0xbf)           */ +    X86_OP_ROL_RM1632_IMM8,                 /* rol ([0x66 0xc1 0)          */ +    X86_OP_ROR_RM1632_IMM8,                 /* ror ([0x66 0xc1 1)          */ +    X86_OP_RCL_RM1632_IMM8,                 /* rcl ([0x66 0xc1 2)          */ +    X86_OP_RCR_RM1632_IMM8,                 /* rcr ([0x66 0xc1 3)          */ +    X86_OP_SHL_RM1632_IMM8,                 /* shl ([0x66 0xc1 4)          */ +    X86_OP_SHR_RM1632_IMM8,                 /* shr ([0x66 0xc1 5)          */ +    X86_OP_SAL_RM1632_IMM8,                 /* sal ([0x66 0xc1 6)          */      X86_OP_SAR_RM1632_IMM8,                 /* sar ([0x66 0xc1 7)          */      X86_OP_RET,                             /* ret (0xc3)                  */ @@ -157,6 +170,8 @@ typedef enum _X86Opcodes      X86_OP_JMP_RM1632,                      /* jmp ([0x66] 0xff 4)         */      X86_OP_PUSH_RM1632,                     /* push ([0x66] 0xff 6)        */ +    X86_OP_MOVZX_R1632_RM8,                 /* movzx ([0x66] 0x0f 0xb6)    */ +      X86_OP_COUNT  } X86Opcodes; @@ -167,11 +182,16 @@ typedef enum _X86Opcodes  /* Eventuel préfixe rencontré */  typedef enum _X86Prefix  { -    X86_PRE_NONE = 0,                       /* Aucun préfixe               */ +    X86_PRE_NONE        = (0 << 0),         /* Aucun préfixe               */ + + +    /* Groupe 3 */ +    X86_PRE_OPSIZE      = (1 << 1),         /* Basculement des opérandes   */ -    X86_PRE_OPSIZE                          /* Basculement des opérandes   */ +    /* Autres */ +    X86_PRE_ESCAPE      = (1 << 3)          /* Opcode sur deux octets      */  } X86Prefix; diff --git a/src/arch/x86/op_adc.c b/src/arch/x86/op_adc.c index 8927607..7ac80f3 100644 --- a/src/arch/x86/op_adc.c +++ b/src/arch/x86/op_adc.c @@ -66,3 +66,41 @@ asm_x86_instr *x86_read_instr_adc_imm8_to_rm1632(const uint8_t *data, off_t *pos      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 'adc' (16 ou 32 bits).        * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_adc_rm1632_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_add.c b/src/arch/x86/op_add.c index f42c8f9..42e8d3b 100644 --- a/src/arch/x86/op_add.c +++ b/src/arch/x86/op_add.c @@ -76,7 +76,7 @@ asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *data, off_t *pos  *                offset = adresse virtuelle de l'instruction.                 *  *                proc   = architecture ciblée par le désassemblage.           *  *                                                                             * -*  Description : Décode une instruction de type 'add' (16 ou 32 bits).        * +*  Description : Décode une instruction de type 'add' (8 bits).               *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           *  *                                                                             * @@ -84,18 +84,15 @@ asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *data, off_t *pos  *                                                                             *  ******************************************************************************/ -asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_add_rm8_r8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)  {      asm_x86_instr *result;                  /* Instruction à retourner     */ -    AsmOperandSize oprsize;                 /* Taille des opérandes        */      result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); -    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); -      ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; -    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8))      {          free(result);          return NULL; @@ -114,7 +111,7 @@ asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *data, off_t *  *                offset = adresse virtuelle de l'instruction.                 *  *                proc   = architecture ciblée par le désassemblage.           *  *                                                                             * -*  Description : Décode une instruction de type 'add' (8 bits).               * +*  Description : Décode une instruction de type 'add' (16 ou 32 bits).        *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           *  *                                                                             * @@ -122,15 +119,18 @@ asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *data, off_t *  *                                                                             *  ******************************************************************************/ -asm_x86_instr *x86_read_instr_add_rm8_r8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_add_rm1632_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)  {      asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */      result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); +      ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; -    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8)) +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize))      {          free(result);          return NULL; diff --git a/src/arch/x86/op_and.c b/src/arch/x86/op_and.c index 3e3ba26..2d877a6 100644 --- a/src/arch/x86/op_and.c +++ b/src/arch/x86/op_and.c @@ -66,3 +66,41 @@ asm_x86_instr *x86_read_instr_and_rm1632_with_imm8(const uint8_t *data, off_t *p      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 'and' (16 ou 32 bits).        * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_and_rm1632_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_cmp.c b/src/arch/x86/op_cmp.c index 5afd794..95e1347 100644 --- a/src/arch/x86/op_cmp.c +++ b/src/arch/x86/op_cmp.c @@ -119,6 +119,44 @@ asm_x86_instr *x86_read_instr_cmp_rm1632_with_imm8(const uint8_t *data, off_t *p  *                                                                             *  ******************************************************************************/ +asm_x86_instr *x86_read_instr_cmp_rm1632_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) +    { +        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 'cmp' (16 ou 32 bits).        * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +  asm_x86_instr *x86_read_instr_cmp_rm1632_with_r1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)  {      asm_x86_instr *result;                  /* Instruction à retourner     */ diff --git a/src/arch/x86/op_movzx.c b/src/arch/x86/op_movzx.c new file mode 100644 index 0000000..bb781cf --- /dev/null +++ b/src/arch/x86/op_movzx.c @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_movzx.c - décodage des copies d'opérandes avec mise à zéro + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +*                                                                             * +*  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 'movzx' (8 bits).             * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_movzx_r1632_rm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM8, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_or.c b/src/arch/x86/op_or.c index 0dd7cf3..42fcfe5 100644 --- a/src/arch/x86/op_or.c +++ b/src/arch/x86/op_or.c @@ -66,3 +66,41 @@ asm_x86_instr *x86_read_instr_or_rm1632_with_imm8(const uint8_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.               * +*                offset = adresse virtuelle de l'instruction.                 * +*                proc   = architecture ciblée par le désassemblage.           * +*                                                                             * +*  Description : Décode une instruction de type 'or' (16 ou 32 bits).         * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_or_rm1632_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_rcl.c b/src/arch/x86/op_rcl.c new file mode 100644 index 0000000..ab0fd05 --- /dev/null +++ b/src/arch/x86/op_rcl.c @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_rcl.c - décodage des rotations à gauche avec retenue + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +*                                                                             * +*  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 'rcl' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_rcl_rm1632_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_rcr.c b/src/arch/x86/op_rcr.c new file mode 100644 index 0000000..78807f9 --- /dev/null +++ b/src/arch/x86/op_rcr.c @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_rcr.c - décodage des rotations à droite avec retenue + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +*                                                                             * +*  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 'rcr' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_rcr_rm1632_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_rol.c b/src/arch/x86/op_rol.c new file mode 100644 index 0000000..047f7cd --- /dev/null +++ b/src/arch/x86/op_rol.c @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_rol.c - décodage des rotations à gauche sans retenue + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +*                                                                             * +*  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 'rol' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_rol_rm1632_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_ror.c b/src/arch/x86/op_ror.c new file mode 100644 index 0000000..5dca287 --- /dev/null +++ b/src/arch/x86/op_ror.c @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_ror.c - décodage des rotations à droite sans retenue + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +*                                                                             * +*  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 'ror' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_ror_rm1632_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_sar.c b/src/arch/x86/op_sar.c index 70b57c9..5e82cd8 100644 --- a/src/arch/x86/op_sar.c +++ b/src/arch/x86/op_sar.c @@ -1,6 +1,6 @@  /* OpenIDA - Outil d'analyse de fichiers binaires - * op_cmp.c - décodage des comparaisons d'opérandes + * op_sar.c - décodage des décallages arithmetiques à droite   *   * Copyright (C) 2008 Cyrille Bagard   * @@ -46,7 +46,7 @@  *                                                                             *  ******************************************************************************/ -asm_x86_instr *x86_read_instr_sar_rm1632_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_sar_rm1632_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)  {      asm_x86_instr *result;                  /* Instruction à retourner     */      AsmOperandSize oprsize;                 /* Taille des opérandes        */ diff --git a/src/arch/x86/op_sbb.c b/src/arch/x86/op_sbb.c index eba4e04..20619cc 100644 --- a/src/arch/x86/op_sbb.c +++ b/src/arch/x86/op_sbb.c @@ -66,3 +66,41 @@ asm_x86_instr *x86_read_instr_sbb_rm1632_with_imm8(const uint8_t *data, off_t *p      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 'sbb' (16 ou 32 bits).        * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_sbb_rm1632_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_shl.c b/src/arch/x86/op_shl.c new file mode 100644 index 0000000..4e2bbba --- /dev/null +++ b/src/arch/x86/op_shl.c @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_shl.c - décodage des décallages logiques à gauche + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +*                                                                             * +*  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 'shl' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_shl_rm1632_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_shr.c b/src/arch/x86/op_shr.c new file mode 100644 index 0000000..0ba8c4e --- /dev/null +++ b/src/arch/x86/op_shr.c @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_shr.c - décodage des décallages logiques à droite + * + * Copyright (C) 2008 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +*                                                                             * +*  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 'shr' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_shr_rm1632_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_sub.c b/src/arch/x86/op_sub.c index 7c282cc..6978a26 100644 --- a/src/arch/x86/op_sub.c +++ b/src/arch/x86/op_sub.c @@ -104,3 +104,41 @@ asm_x86_instr *x86_read_instr_sub_r1632_from_rm1632(const uint8_t *data, off_t *      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 'sub' (16 ou 32 bits).        * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_sub_rm1632_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/op_xor.c b/src/arch/x86/op_xor.c index 8d44f9c..eabb88e 100644 --- a/src/arch/x86/op_xor.c +++ b/src/arch/x86/op_xor.c @@ -149,7 +149,7 @@ asm_x86_instr *x86_read_instr_xor_rm8_with_imm8(const uint8_t *data, off_t *pos,  *                offset = adresse virtuelle de l'instruction.                 *  *                proc   = architecture ciblée par le désassemblage.           *  *                                                                             * -*  Description : Décode une instruction de type 'xor' (16 ou 32 bits).        * +*  Description : Décode une instruction de type 'xor' (8 bits).               *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           *  *                                                                             * @@ -157,18 +157,15 @@ asm_x86_instr *x86_read_instr_xor_rm8_with_imm8(const uint8_t *data, off_t *pos,  *                                                                             *  ******************************************************************************/ -asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)  {      asm_x86_instr *result;                  /* Instruction à retourner     */ -    AsmOperandSize oprsize;                 /* Taille des opérandes        */      result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); -    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); -      ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; -    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize)) +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R8, X86_OTP_RM8))      {          free(result);          return NULL; @@ -187,7 +184,7 @@ asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *data, off_t  *                offset = adresse virtuelle de l'instruction.                 *  *                proc   = architecture ciblée par le désassemblage.           *  *                                                                             * -*  Description : Décode une instruction de type 'xor' (8 bits).               * +*  Description : Décode une instruction de type 'xor' (16 ou 32 bits).        *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           *  *                                                                             * @@ -195,15 +192,18 @@ asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *data, off_t  *                                                                             *  ******************************************************************************/ -asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_xor_r1632_with_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)  {      asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */      result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); +      ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; -    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R8, X86_OTP_RM8)) +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, oprsize))      {          free(result);          return NULL; @@ -222,7 +222,7 @@ asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *data, off_t *pos, o  *                offset = adresse virtuelle de l'instruction.                 *  *                proc   = architecture ciblée par le désassemblage.           *  *                                                                             * -*  Description : Décode une instruction de type 'xor' (16 ou 32 bits).        * +*  Description : Décode une instruction de type 'xor' (8 bits).               *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           *  *                                                                             * @@ -230,18 +230,15 @@ asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *data, off_t *pos, o  *                                                                             *  ******************************************************************************/ -asm_x86_instr *x86_read_instr_xor_r1632_with_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_xor_rm8_with_r8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)  {      asm_x86_instr *result;                  /* Instruction à retourner     */ -    AsmOperandSize oprsize;                 /* Taille des opérandes        */      result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); -    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); -      ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; -    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, oprsize)) +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8))      {          free(result);          return NULL; @@ -260,7 +257,7 @@ asm_x86_instr *x86_read_instr_xor_r1632_with_rm1632(const uint8_t *data, off_t *  *                offset = adresse virtuelle de l'instruction.                 *  *                proc   = architecture ciblée par le désassemblage.           *  *                                                                             * -*  Description : Décode une instruction de type 'xor' (8 bits).               * +*  Description : Décode une instruction de type 'xor' (16 ou 32 bits).        *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           *  *                                                                             * @@ -268,15 +265,18 @@ asm_x86_instr *x86_read_instr_xor_r1632_with_rm1632(const uint8_t *data, off_t *  *                                                                             *  ******************************************************************************/ -asm_x86_instr *x86_read_instr_xor_rm8_with_r8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)  {      asm_x86_instr *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */      result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); +    oprsize = switch_x86_operand_size_if_needed(proc, data, pos); +      ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; -    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8)) +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize))      {          free(result);          return NULL; @@ -303,7 +303,7 @@ asm_x86_instr *x86_read_instr_xor_rm8_with_r8(const uint8_t *data, off_t *pos, o  *                                                                             *  ******************************************************************************/ -asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *x86_read_instr_xor_rm1632_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)  {      asm_x86_instr *result;                  /* Instruction à retourner     */      AsmOperandSize oprsize;                 /* Taille des opérandes        */ @@ -314,7 +314,7 @@ asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(const uint8_t *data, off_t *p      ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; -    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize)) +    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize))      {          free(result);          return NULL; diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h index 70d41b8..56f5b2f 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -37,11 +37,11 @@  /* Décode une instruction de type 'adc' (16 ou 32 bits). */  asm_x86_instr *x86_read_instr_adc_imm8_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); -/* Décode une instruction de type 'add' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'adc' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_adc_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'add' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'add' (8 bits). */  asm_x86_instr *x86_read_instr_add_rm8_r8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -49,6 +49,12 @@ asm_x86_instr *x86_read_instr_add_rm8_r8(const uint8_t *, off_t *, off_t, uint64  /* Décode une instruction de type 'and' (16 ou 32 bits). */  asm_x86_instr *x86_read_instr_and_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'and' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_and_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'add' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_add_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +  /* Décode une instruction de type 'call'. */  asm_x86_instr *x86_read_instr_call_rel1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -62,6 +68,9 @@ asm_x86_instr *x86_read_instr_cmp_rm8_with_imm8(const uint8_t *, off_t *, off_t,  asm_x86_instr *x86_read_instr_cmp_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'cmp' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_cmp_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'cmp' (16 ou 32 bits). */  asm_x86_instr *x86_read_instr_cmp_rm1632_with_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'dec'. */ @@ -124,12 +133,18 @@ asm_x86_instr *x86_read_instr_mov_r1632_to_rm1632(const uint8_t *, off_t *, off_  /* Décode une instruction de type 'mov' (16 ou 32 bits). */  asm_x86_instr *x86_read_instr_mov_rm1632_to_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'movzx' (8 bits). */ +asm_x86_instr *x86_read_instr_movzx_r1632_rm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +  /* Décode une instruction de type 'nop'. */  asm_x86_instr *x86_read_instr_nop(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'or' (16 ou 32 bits). */  asm_x86_instr *x86_read_instr_or_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'or' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_or_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +  /* Décode une instruction de type 'pop' (16 ou 32 bits). */  asm_x86_instr *x86_read_instr_pop_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -142,21 +157,48 @@ asm_x86_instr *x86_read_instr_push_r1632(const uint8_t *, off_t *, off_t, uint64  /* Décode une instruction de type 'push' (16 ou 32 bits). */  asm_x86_instr *x86_read_instr_push_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'rcl' (8 bits). */ +asm_x86_instr *x86_read_instr_rcl_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'rcr' (8 bits). */ +asm_x86_instr *x86_read_instr_rcr_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +  /* Décode une instruction de type 'ret'. */  asm_x86_instr *x86_read_instr_ret(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'rol' (8 bits). */ +asm_x86_instr *x86_read_instr_rol_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'ror' (8 bits). */ +asm_x86_instr *x86_read_instr_ror_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'sal' (8 bits). */ +#define x86_read_instr_sal_rm1632_imm8 x86_read_instr_shl_rm1632_imm8 +  /* Décode une instruction de type 'sar' (8 bits). */ -asm_x86_instr *x86_read_instr_sar_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +asm_x86_instr *x86_read_instr_sar_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'sbb'. */  asm_x86_instr *x86_read_instr_sbb_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'sbb' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_sbb_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'shl' (8 bits). */ +asm_x86_instr *x86_read_instr_shl_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'shr' (8 bits). */ +asm_x86_instr *x86_read_instr_shr_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +  /* Décode une instruction de type 'sub'. */  asm_x86_instr *x86_read_instr_sub_imm8_from_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'sub' (16 ou 32 bits). */  asm_x86_instr *x86_read_instr_sub_r1632_from_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'sub' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_sub_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +  /* Décode une instruction de type 'test al, ...' (8 bits). */  asm_x86_instr *x86_read_instr_test_al(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -178,9 +220,6 @@ asm_x86_instr *x86_read_instr_xor_e_ax_with_imm1632(const uint8_t *, off_t *, of  /* Décode une instruction de type 'xor' (8 bits). */  asm_x86_instr *x86_read_instr_xor_rm8_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); -/* Décode une instruction de type 'xor' (16 ou 32 bits). */ -asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); -  /* Décode une instruction de type 'xor' (8 bits). */  asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -194,6 +233,9 @@ asm_x86_instr *x86_read_instr_xor_rm8_with_r8(const uint8_t *, off_t *, off_t, u  asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'xor' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_xor_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'xor' (16 ou 32 bits). */  asm_x86_instr *x86_read_instr_xor_rm1632_with_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 14f35bc..3fde754 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -41,11 +41,10 @@ typedef asm_x86_instr * (* read_instr) (const uint8_t *, off_t *, off_t, uint64_  /* Carte d'identité d'un opcode */  typedef struct _x86_opcode  { -    uint8_t prefix;                         /* préfixe eventuel            */ +    X86Prefix prefix;                       /* Préfixe(s) eventuel(s)      */      uint8_t opcode;                         /* Opcode seul                 */      uint8_t op_ext;                         /* Extension de l'opcode       */ -    bool opt_prefix;                        /* Préfixe optionnel ?         */      bool has_op_ext;                        /* Ext. à prendre en compte ?  */      const char *name;                       /* Désignation humaine         */ @@ -57,27 +56,61 @@ typedef struct _x86_opcode  #define EXT_OPCODE_MASK     0x38 -#define register_opcode(target, _prefix, _opcode, _name, _read)                 \ + + + +#define register_opcode(target, _opcode, _name, _read)                          \ +    do {                                                                        \ +        target.prefix = X86_PRE_NONE;                                           \ +        target.opcode = _opcode;                                                \ +        target.has_op_ext = false;                                              \ +        target.name = _name;                                                    \ +        target.read = _read;                                                    \ +    } while (0) + +#define register_opcode_1632(target, _opcode, _name, _read)                     \      do {                                                                        \ -        target.prefix = _prefix;                                                \ +        target.prefix = X86_PRE_OPSIZE;                                         \          target.opcode = _opcode;                                                \ -        target.opt_prefix = (_prefix != 0x00);                                  \          target.has_op_ext = false;                                              \          target.name = _name;                                                    \          target.read = _read;                                                    \      } while (0) -#define register_opcode_with_ext(target, _prefix, _opcode, _ext, _name, _read)  \ +#define register_opcode_with_ext(target, _opcode, _ext, _name, _read)           \      do {                                                                        \ -        target.prefix = _prefix;                                                \ +        target.prefix = X86_PRE_NONE;                                           \          target.opcode = _opcode;                                                \          target.op_ext = _ext << 3;                                              \ -        target.opt_prefix = (_prefix != 0x00);                                  \          target.has_op_ext = true;                                               \          target.name = _name;                                                    \          target.read = _read;                                                    \      } while (0) +#define register_opcode_1632_with_ext(target, _opcode, _ext, _name, _read)      \ +    do {                                                                        \ +        target.prefix = X86_PRE_OPSIZE;                                         \ +        target.opcode = _opcode;                                                \ +        target.op_ext = _ext << 3;                                              \ +        target.has_op_ext = true;                                               \ +        target.name = _name;                                                    \ +        target.read = _read;                                                    \ +    } while (0) + +#define register_2b_opcode_1632(target, _opcode, _name, _read)                  \ +    do {                                                                        \ +        target.prefix = X86_PRE_ESCAPE | X86_PRE_OPSIZE;                        \ +        target.opcode = _opcode;                                                \ +        target.has_op_ext = false;                                              \ +        target.name = _name;                                                    \ +        target.read = _read;                                                    \ +    } while (0) + + + + + + @@ -205,127 +238,140 @@ AsmOperandSize switch_x86_operand_size_if_needed(const asm_x86_processor *proc,  void x86_register_instructions(asm_x86_processor *proc)  { -    register_opcode(proc->opcodes[X86_OP_ADD_RM8_R8], 0x00, 0x00, "add", x86_read_instr_add_rm8_r8); - -    register_opcode(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x66, 0x29, "sub", x86_read_instr_sub_r1632_from_rm1632); - -    register_opcode(proc->opcodes[X86_OP_XOR_RM8_R8], 0x00, 0x30, "xor", x86_read_instr_xor_rm8_with_r8); -    register_opcode(proc->opcodes[X86_OP_XOR_RM1632_R1632], 0x66, 0x31, "xor", x86_read_instr_xor_rm1632_with_r1632); -    register_opcode(proc->opcodes[X86_OP_XOR_R8_RM8], 0x00, 0x32, "xor", x86_read_instr_xor_r8_with_rm8); -    register_opcode(proc->opcodes[X86_OP_XOR_R1632_RM1632], 0x66, 0x33, "xor", x86_read_instr_xor_r1632_with_rm1632); -    register_opcode(proc->opcodes[X86_OP_XOR_AL_IMM8], 0x00, 0x34, "xor", x86_read_instr_xor_al_with_imm8); -    register_opcode(proc->opcodes[X86_OP_XOR_E_AX_IMM1632], 0x66, 0x35, "xor", x86_read_instr_xor_e_ax_with_imm1632); - -    register_opcode(proc->opcodes[X86_OP_CMP_RM1632_R1632], 0x66, 0x39, "cmp", x86_read_instr_cmp_rm1632_with_r1632); - -    register_opcode(proc->opcodes[X86_OP_INC_E_AX], 0x66, 0x40, "inc", x86_read_instr_inc_r1632); -    register_opcode(proc->opcodes[X86_OP_INC_E_CX], 0x66, 0x41, "inc", x86_read_instr_inc_r1632); -    register_opcode(proc->opcodes[X86_OP_INC_E_DX], 0x66, 0x42, "inc", x86_read_instr_inc_r1632); -    register_opcode(proc->opcodes[X86_OP_INC_E_BX], 0x66, 0x43, "inc", x86_read_instr_inc_r1632); -    register_opcode(proc->opcodes[X86_OP_INC_E_SP], 0x66, 0x44, "inc", x86_read_instr_inc_r1632); -    register_opcode(proc->opcodes[X86_OP_INC_E_BP], 0x66, 0x45, "inc", x86_read_instr_inc_r1632); -    register_opcode(proc->opcodes[X86_OP_INC_E_SI], 0x66, 0x46, "inc", x86_read_instr_inc_r1632); -    register_opcode(proc->opcodes[X86_OP_INC_E_DI], 0x66, 0x47, "inc", x86_read_instr_inc_r1632); - -    register_opcode(proc->opcodes[X86_OP_DEC_E_AX], 0x66, 0x48, "dec", x86_read_instr_dec_r1632); -    register_opcode(proc->opcodes[X86_OP_DEC_E_CX], 0x66, 0x49, "dec", x86_read_instr_dec_r1632); -    register_opcode(proc->opcodes[X86_OP_DEC_E_DX], 0x66, 0x4a, "dec", x86_read_instr_dec_r1632); -    register_opcode(proc->opcodes[X86_OP_DEC_E_BX], 0x66, 0x4b, "dec", x86_read_instr_dec_r1632); -    register_opcode(proc->opcodes[X86_OP_DEC_E_SP], 0x66, 0x4c, "dec", x86_read_instr_dec_r1632); -    register_opcode(proc->opcodes[X86_OP_DEC_E_BP], 0x66, 0x4d, "dec", x86_read_instr_dec_r1632); -    register_opcode(proc->opcodes[X86_OP_DEC_E_SI], 0x66, 0x4e, "dec", x86_read_instr_dec_r1632); -    register_opcode(proc->opcodes[X86_OP_DEC_E_DI], 0x66, 0x4f, "dec", x86_read_instr_dec_r1632); - -    register_opcode(proc->opcodes[X86_OP_PUSH_E_AX], 0x66, 0x50, "push", x86_read_instr_push_r1632); -    register_opcode(proc->opcodes[X86_OP_PUSH_E_CX], 0x66, 0x51, "push", x86_read_instr_push_r1632); -    register_opcode(proc->opcodes[X86_OP_PUSH_E_DX], 0x66, 0x52, "push", x86_read_instr_push_r1632); -    register_opcode(proc->opcodes[X86_OP_PUSH_E_BX], 0x66, 0x53, "push", x86_read_instr_push_r1632); -    register_opcode(proc->opcodes[X86_OP_PUSH_E_SP], 0x66, 0x54, "push", x86_read_instr_push_r1632); -    register_opcode(proc->opcodes[X86_OP_PUSH_E_BP], 0x66, 0x55, "push", x86_read_instr_push_r1632); -    register_opcode(proc->opcodes[X86_OP_PUSH_E_SI], 0x66, 0x56, "push", x86_read_instr_push_r1632); -    register_opcode(proc->opcodes[X86_OP_PUSH_E_DI], 0x66, 0x57, "push", x86_read_instr_push_r1632); - -    register_opcode(proc->opcodes[X86_OP_POP_E_AX], 0x66, 0x58, "pop", x86_read_instr_pop_r1632); -    register_opcode(proc->opcodes[X86_OP_POP_E_CX], 0x66, 0x59, "pop", x86_read_instr_pop_r1632); -    register_opcode(proc->opcodes[X86_OP_POP_E_DX], 0x66, 0x5a, "pop", x86_read_instr_pop_r1632); -    register_opcode(proc->opcodes[X86_OP_POP_E_BX], 0x66, 0x5b, "pop", x86_read_instr_pop_r1632); -    register_opcode(proc->opcodes[X86_OP_POP_E_SP], 0x66, 0x5c, "pop", x86_read_instr_pop_r1632); -    register_opcode(proc->opcodes[X86_OP_POP_E_BP], 0x66, 0x5d, "pop", x86_read_instr_pop_r1632); -    register_opcode(proc->opcodes[X86_OP_POP_E_SI], 0x66, 0x5e, "pop", x86_read_instr_pop_r1632); -    register_opcode(proc->opcodes[X86_OP_POP_E_DI], 0x66, 0x5f, "pop", x86_read_instr_pop_r1632); +    register_opcode(proc->opcodes[X86_OP_ADD_RM8_R8], 0x00, "add", x86_read_instr_add_rm8_r8); + +    register_opcode_1632(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x29, "sub", x86_read_instr_sub_r1632_from_rm1632); + +    register_opcode(proc->opcodes[X86_OP_XOR_RM8_R8], 0x30, "xor", x86_read_instr_xor_rm8_with_r8); +    register_opcode_1632(proc->opcodes[X86_OP_XOR_RM1632_R1632], 0x31, "xor", x86_read_instr_xor_rm1632_with_r1632); +    register_opcode(proc->opcodes[X86_OP_XOR_R8_RM8], 0x32, "xor", x86_read_instr_xor_r8_with_rm8); +    register_opcode_1632(proc->opcodes[X86_OP_XOR_R1632_RM1632], 0x33, "xor", x86_read_instr_xor_r1632_with_rm1632); +    register_opcode(proc->opcodes[X86_OP_XOR_AL_IMM8], 0x34, "xor", x86_read_instr_xor_al_with_imm8); +    register_opcode_1632(proc->opcodes[X86_OP_XOR_E_AX_IMM1632], 0x35, "xor", x86_read_instr_xor_e_ax_with_imm1632); + +    register_opcode_1632(proc->opcodes[X86_OP_CMP_RM1632_R1632], 0x39, "cmp", x86_read_instr_cmp_rm1632_with_r1632); + +    register_opcode_1632(proc->opcodes[X86_OP_INC_E_AX], 0x40, "inc", x86_read_instr_inc_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_INC_E_CX], 0x41, "inc", x86_read_instr_inc_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_INC_E_DX], 0x42, "inc", x86_read_instr_inc_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_INC_E_BX], 0x43, "inc", x86_read_instr_inc_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_INC_E_SP], 0x44, "inc", x86_read_instr_inc_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_INC_E_BP], 0x45, "inc", x86_read_instr_inc_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_INC_E_SI], 0x46, "inc", x86_read_instr_inc_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_INC_E_DI], 0x47, "inc", x86_read_instr_inc_r1632); + +    register_opcode_1632(proc->opcodes[X86_OP_DEC_E_AX], 0x48, "dec", x86_read_instr_dec_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_DEC_E_CX], 0x49, "dec", x86_read_instr_dec_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_DEC_E_DX], 0x4a, "dec", x86_read_instr_dec_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_DEC_E_BX], 0x4b, "dec", x86_read_instr_dec_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_DEC_E_SP], 0x4c, "dec", x86_read_instr_dec_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_DEC_E_BP], 0x4d, "dec", x86_read_instr_dec_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_DEC_E_SI], 0x4e, "dec", x86_read_instr_dec_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_DEC_E_DI], 0x4f, "dec", x86_read_instr_dec_r1632); + +    register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_AX], 0x50, "push", x86_read_instr_push_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_CX], 0x51, "push", x86_read_instr_push_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_DX], 0x52, "push", x86_read_instr_push_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_BX], 0x53, "push", x86_read_instr_push_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_SP], 0x54, "push", x86_read_instr_push_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_BP], 0x55, "push", x86_read_instr_push_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_SI], 0x56, "push", x86_read_instr_push_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_DI], 0x57, "push", x86_read_instr_push_r1632); + +    register_opcode_1632(proc->opcodes[X86_OP_POP_E_AX], 0x58, "pop", x86_read_instr_pop_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_POP_E_CX], 0x59, "pop", x86_read_instr_pop_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_POP_E_DX], 0x5a, "pop", x86_read_instr_pop_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_POP_E_BX], 0x5b, "pop", x86_read_instr_pop_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_POP_E_SP], 0x5c, "pop", x86_read_instr_pop_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_POP_E_BP], 0x5d, "pop", x86_read_instr_pop_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_POP_E_SI], 0x5e, "pop", x86_read_instr_pop_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_POP_E_DI], 0x5f, "pop", x86_read_instr_pop_r1632); + +    register_opcode_1632(proc->opcodes[X86_OP_PUSH_IMM1632], 0x68, "push", x86_read_instr_push_imm1632); + +    register_opcode(proc->opcodes[X86_OP_JE_8], 0x74, "je", x86_read_instr_je_8); +    register_opcode(proc->opcodes[X86_OP_JNE_8], 0x75, "jne", x86_read_instr_jne_8); + +    register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM8_IMM8], 0x80, 6, "xor", x86_read_instr_xor_rm8_with_imm8); +    register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM8_IMM8], 0x80, 7, "cmp", x86_read_instr_cmp_rm8_with_imm8); + +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM1632], 0x81, 0, "add", x86_read_instr_add_rm1632_imm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_OR_RM1632_IMM1632], 0x81, 1, "or", x86_read_instr_or_rm1632_imm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_ADC_RM1632_IMM1632], 0x81, 2, "adc", x86_read_instr_adc_rm1632_imm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_SBB_RM1632_IMM1632], 0x81, 3, "sbb", x86_read_instr_sbb_rm1632_imm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_AND_RM1632_IMM1632], 0x81, 4, "and", x86_read_instr_and_rm1632_imm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_SUB_RM1632_IMM1632], 0x81, 5, "sub", x86_read_instr_sub_rm1632_imm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM1632], 0x81, 6, "xor", x86_read_instr_xor_rm1632_imm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_CMP_RM1632_IMM1632], 0x81, 7, "cmp", x86_read_instr_cmp_rm1632_imm1632); + +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM8], 0x83, 0, "add", x86_read_instr_add_imm8_to_rm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_OR_RM1632_IMM8], 0x83, 1, "or", x86_read_instr_or_rm1632_with_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_ADC_RM1632_IMM8], 0x83, 2, "adc", x86_read_instr_adc_imm8_to_rm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_SBB_RM1632_IMM8], 0x83, 3, "sbb", x86_read_instr_sbb_rm1632_with_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_AND_RM1632_IMM8], 0x83, 4, "and", x86_read_instr_and_rm1632_with_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_SUB_RM1632_IMM8], 0x83, 5, "sub", x86_read_instr_sub_imm8_from_rm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM8], 0x83, 6, "xor", x86_read_instr_xor_rm1632_with_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_CMP_RM1632_IMM8], 0x83, 7, "cmp", x86_read_instr_cmp_rm1632_with_imm8); + +    register_opcode(proc->opcodes[X86_OP_TEST_RM8_R8], 0x84, "test", x86_read_instr_test_rm8_with_r8); +    register_opcode_1632(proc->opcodes[X86_OP_TEST_RM1632_R1632], 0x85, "test", x86_read_instr_test_rm1632_with_r1632); + +    register_opcode_1632(proc->opcodes[X86_OP_MOV_RM1632_R1632], 0x89, "mov", x86_read_instr_mov_r1632_to_rm1632); + +    register_opcode_1632(proc->opcodes[X86_OP_MOV_R1632_RM1632], 0x8b, "mov", x86_read_instr_mov_rm1632_to_r1632); + +    register_opcode_1632(proc->opcodes[X86_OP_LEA], 0x8d, "lea", x86_read_instr_lea); + +    register_opcode(proc->opcodes[X86_OP_NOP], 0x90, "nop", x86_read_instr_nop); + +    register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_AL], 0xa0, "mov", x86_read_instr_mov_moffs8_to_al); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_MOFFS_TO_E_AX], 0xa1, "mov", x86_read_instr_mov_moffs1632_to_e_ax); +    register_opcode(proc->opcodes[X86_OP_MOV_AL_TO_MOFFS], 0xa2, "mov", x86_read_instr_mov_al_to_moffs8); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_E_AX_TO_MOFFS], 0xa3, "mov", x86_read_instr_mov_e_ax_to_moffs1632); + +    register_opcode(proc->opcodes[X86_OP_TEST_AL], 0xa8, "test", x86_read_instr_test_al); +    register_opcode_1632(proc->opcodes[X86_OP_TEST_E_AX], 0xa9, "test", x86_read_instr_test_e_ax); + +    register_opcode_1632(proc->opcodes[X86_OP_MOV_E_AX], 0xb8, "mov", x86_read_instr_mov_imm1632_to_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_E_CX], 0xb9, "mov", x86_read_instr_mov_imm1632_to_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_E_DX], 0xba, "mov", x86_read_instr_mov_imm1632_to_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_E_BX], 0xbb, "mov", x86_read_instr_mov_imm1632_to_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_E_SP], 0xbc, "mov", x86_read_instr_mov_imm1632_to_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_E_BP], 0xbd, "mov", x86_read_instr_mov_imm1632_to_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_E_SI], 0xbe, "mov", x86_read_instr_mov_imm1632_to_r1632); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_E_DI], 0xbf, "mov", x86_read_instr_mov_imm1632_to_r1632); + +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_ROL_RM1632_IMM8], 0xc1, 0, "rol", x86_read_instr_rol_rm1632_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_ROR_RM1632_IMM8], 0xc1, 1, "ror", x86_read_instr_ror_rm1632_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_RCL_RM1632_IMM8], 0xc1, 2, "rcl", x86_read_instr_rcl_rm1632_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_RCR_RM1632_IMM8], 0xc1, 3, "rcr", x86_read_instr_rcr_rm1632_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_SHL_RM1632_IMM8], 0xc1, 4, "shl", x86_read_instr_shl_rm1632_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_SHR_RM1632_IMM8], 0xc1, 5, "shr", x86_read_instr_shr_rm1632_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_SAL_RM1632_IMM8], 0xc1, 6, "sal", x86_read_instr_sal_rm1632_imm8); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_SAR_RM1632_IMM8], 0xc1, 7, "sar", x86_read_instr_sar_rm1632_imm8); + +    register_opcode(proc->opcodes[X86_OP_RET], 0xc3, "ret", x86_read_instr_ret); + +    register_opcode(proc->opcodes[X86_OP_MOV_IMM8_TO_RM8], 0xc6, "mov", x86_read_instr_mov_imm8_to_rm8); +    register_opcode_1632(proc->opcodes[X86_OP_MOV_IMM1632_TO_RM1632], 0xc7, "mov", x86_read_instr_mov_imm1632_to_rm1632); + +    register_opcode(proc->opcodes[X86_OP_LEAVE], 0xc9, "leave", x86_read_instr_leave); + +    register_opcode(proc->opcodes[X86_OP_INT], 0xcd, "int", x86_read_instr_int); -    register_opcode(proc->opcodes[X86_OP_PUSH_IMM1632], 0x66, 0x68, "push", x86_read_instr_push_imm1632); -    register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM8_IMM8], 0x00, 0x80, 6, "xor", x86_read_instr_xor_rm8_with_imm8); -    register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM8_IMM8], 0x00, 0x80, 7, "cmp", x86_read_instr_cmp_rm8_with_imm8); +    register_opcode_1632(proc->opcodes[X86_OP_CALL_REL1632], 0xe8, "call", x86_read_instr_call_rel1632); +    register_opcode_1632(proc->opcodes[X86_OP_JMP_REL1632], 0xe9, "jmp", x86_read_instr_jmp_rel1632); -    register_opcode_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM1632], 0x66, 0x81, 0, "add", x86_read_instr_add_imm1632_to_rm1632); +    register_opcode(proc->opcodes[X86_OP_JMP_8], 0xeb, "jmp", x86_read_instr_jmp_8); -    register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM1632], 0x66, 0x81, 6, "xor", x86_read_instr_xor_rm1632_with_imm1632); +    register_opcode(proc->opcodes[X86_OP_HLT], 0xf4, "hlt", x86_read_instr_hlt); -    register_opcode_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM8], 0x66, 0x83, 0, "add", x86_read_instr_add_imm8_to_rm1632); -    register_opcode_with_ext(proc->opcodes[X86_OP_OR_RM1632_IMM8], 0x66, 0x83, 1, "or", x86_read_instr_or_rm1632_with_imm8); -    register_opcode_with_ext(proc->opcodes[X86_OP_ADC_RM1632_IMM8], 0x66, 0x83, 2, "adc", x86_read_instr_adc_imm8_to_rm1632); -    register_opcode_with_ext(proc->opcodes[X86_OP_SBB_RM1632_IMM8], 0x66, 0x83, 3, "sbb", x86_read_instr_sbb_rm1632_with_imm8); -    register_opcode_with_ext(proc->opcodes[X86_OP_AND_RM1632_IMM8], 0x66, 0x83, 4, "and", x86_read_instr_and_rm1632_with_imm8); -    register_opcode_with_ext(proc->opcodes[X86_OP_SUB_RM1632_IMM8], 0x66, 0x83, 5, "sub", x86_read_instr_sub_imm8_from_rm1632); -    register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM8], 0x66, 0x83, 6, "xor", x86_read_instr_xor_rm1632_with_imm8); -    register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM1632_IMM8], 0x66, 0x83, 7, "cmp", x86_read_instr_cmp_rm1632_with_imm8); - -    register_opcode(proc->opcodes[X86_OP_JE_8], 0x00, 0x74, "je", x86_read_instr_je_8); -    register_opcode(proc->opcodes[X86_OP_JNE_8], 0x00, 0x75, "jne", x86_read_instr_jne_8); - -    register_opcode(proc->opcodes[X86_OP_TEST_RM8_R8], 0x00, 0x84, "test", x86_read_instr_test_rm8_with_r8); -    register_opcode(proc->opcodes[X86_OP_TEST_RM1632_R1632], 0x66, 0x85, "test", x86_read_instr_test_rm1632_with_r1632); - -    register_opcode(proc->opcodes[X86_OP_MOV_RM1632_R1632], 0x66, 0x89, "mov", x86_read_instr_mov_r1632_to_rm1632); - -    register_opcode(proc->opcodes[X86_OP_MOV_R1632_RM1632], 0x66, 0x8b, "mov", x86_read_instr_mov_rm1632_to_r1632); - -    register_opcode(proc->opcodes[X86_OP_LEA], 0x66, 0x8d, "lea", x86_read_instr_lea); - -    register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", x86_read_instr_nop); - -    register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_AL], 0x00, 0xa0, "mov", x86_read_instr_mov_moffs8_to_al); -    register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_E_AX], 0x66, 0xa1, "mov", x86_read_instr_mov_moffs1632_to_e_ax); -    register_opcode(proc->opcodes[X86_OP_MOV_AL_TO_MOFFS], 0x00, 0xa2, "mov", x86_read_instr_mov_al_to_moffs8); -    register_opcode(proc->opcodes[X86_OP_MOV_E_AX_TO_MOFFS], 0x66, 0xa3, "mov", x86_read_instr_mov_e_ax_to_moffs1632); - -    register_opcode(proc->opcodes[X86_OP_TEST_AL], 0x00, 0xa8, "test", x86_read_instr_test_al); -    register_opcode(proc->opcodes[X86_OP_TEST_E_AX], 0x66, 0xa9, "test", x86_read_instr_test_e_ax); - -    register_opcode(proc->opcodes[X86_OP_MOV_E_AX], 0x66, 0xb8, "mov", x86_read_instr_mov_imm1632_to_r1632); -    register_opcode(proc->opcodes[X86_OP_MOV_E_CX], 0x66, 0xb9, "mov", x86_read_instr_mov_imm1632_to_r1632); -    register_opcode(proc->opcodes[X86_OP_MOV_E_DX], 0x66, 0xba, "mov", x86_read_instr_mov_imm1632_to_r1632); -    register_opcode(proc->opcodes[X86_OP_MOV_E_BX], 0x66, 0xbb, "mov", x86_read_instr_mov_imm1632_to_r1632); -    register_opcode(proc->opcodes[X86_OP_MOV_E_SP], 0x66, 0xbc, "mov", x86_read_instr_mov_imm1632_to_r1632); -    register_opcode(proc->opcodes[X86_OP_MOV_E_BP], 0x66, 0xbd, "mov", x86_read_instr_mov_imm1632_to_r1632); -    register_opcode(proc->opcodes[X86_OP_MOV_E_SI], 0x66, 0xbe, "mov", x86_read_instr_mov_imm1632_to_r1632); -    register_opcode(proc->opcodes[X86_OP_MOV_E_DI], 0x66, 0xbf, "mov", x86_read_instr_mov_imm1632_to_r1632); - -    register_opcode_with_ext(proc->opcodes[X86_OP_SAR_RM1632_IMM8], 0x66, 0xc1, 7, "sar", x86_read_instr_sar_rm1632_with_imm8); - -    register_opcode(proc->opcodes[X86_OP_RET], 0x00, 0xc3, "ret", x86_read_instr_ret); - -    register_opcode(proc->opcodes[X86_OP_MOV_IMM8_TO_RM8], 0x00, 0xc6, "mov", x86_read_instr_mov_imm8_to_rm8); -    register_opcode(proc->opcodes[X86_OP_MOV_IMM1632_TO_RM1632], 0x66, 0xc7, "mov", x86_read_instr_mov_imm1632_to_rm1632); - -    register_opcode(proc->opcodes[X86_OP_LEAVE], 0x00, 0xc9, "leave", x86_read_instr_leave); - -    register_opcode(proc->opcodes[X86_OP_INT], 0x00, 0xcd, "int", x86_read_instr_int); - - -    register_opcode(proc->opcodes[X86_OP_CALL_REL1632], 0x66, 0xe8, "call", x86_read_instr_call_rel1632); -    register_opcode(proc->opcodes[X86_OP_JMP_REL1632], 0x66, 0xe9, "jmp", x86_read_instr_jmp_rel1632); - -    register_opcode(proc->opcodes[X86_OP_JMP_8], 0x00, 0xeb, "jmp", x86_read_instr_jmp_8); - -    register_opcode(proc->opcodes[X86_OP_HLT], 0x00, 0xf4, "hlt", x86_read_instr_hlt); - -    register_opcode_with_ext(proc->opcodes[X86_OP_CALL_RM1632], 0x66, 0xff, 2, "call", x86_read_instr_call_rm1632); -    register_opcode_with_ext(proc->opcodes[X86_OP_JMP_RM1632], 0x66, 0xff, 4, "jmp", x86_read_instr_jmp_rm1632); -    register_opcode_with_ext(proc->opcodes[X86_OP_PUSH_RM1632], 0x66, 0xff, 6, "push", x86_read_instr_push_rm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_CALL_RM1632], 0xff, 2, "call", x86_read_instr_call_rm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_JMP_RM1632], 0xff, 4, "jmp", x86_read_instr_jmp_rm1632); +    register_opcode_1632_with_ext(proc->opcodes[X86_OP_PUSH_RM1632], 0xff, 6, "push", x86_read_instr_push_rm1632); +    //register_2b_opcode_1632(proc->opcodes[X86_OP_MOVZX_R1632_RM8], 0xb6, "movzx", x86_read_instr_movzx_r1632_rm8);  } @@ -351,48 +397,46 @@ void x86_register_instructions(asm_x86_processor *proc)  asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *data, off_t *pos, off_t len, uint64_t offset)  {      asm_x86_instr *result;                  /* Résultat à faire remonter   */ +    X86Prefix prefix;                       /* Préfixe détecté             */      X86Opcodes i;                           /* Boucle de parcours          */ -    off_t tmp;                              /* Tête de lecture             */ -    off_t old_pos;                          /* Sauvegarde de la position   */      result = NULL; -    for (i = 0; i < X86_OP_COUNT; i++) +    prefix = X86_PRE_NONE; + + consume_prefix: + +    switch (data[*pos])      { -        if (proc->opcodes[i].prefix > 0 && data[*pos] == proc->opcodes[i].prefix && data[*pos + 1] == proc->opcodes[i].opcode) -        { -            tmp = *pos + 2; -            goto find_instr; -        } +        case 0x66: +            prefix |= X86_PRE_OPSIZE; +            (*pos)++; +            break; -        if (proc->opcodes[i].opt_prefix && data[*pos] == proc->opcodes[i].opcode) -        { -            tmp = *pos + 1; -            goto find_instr; -        } +        case 0x0f: +            prefix |= X86_PRE_ESCAPE; +            (*pos)++; +            break; -        if (proc->opcodes[i].prefix == 0x00 && data[*pos] == proc->opcodes[i].opcode) -        { -            tmp = *pos + 1; -            goto find_instr; -        } +        default: +            goto found_instr; +            break; + +    } -        continue; +    goto consume_prefix; - find_instr: + found_instr: -        if (proc->opcodes[i].has_op_ext && (data[tmp] & EXT_OPCODE_MASK) != proc->opcodes[i].op_ext) -            continue; +    for (i = 0; i < X86_OP_COUNT; i++) +    { +        if ((prefix & proc->opcodes[i].prefix) != prefix) continue; -        old_pos = *pos; +        if (data[*pos] != proc->opcodes[i].opcode) continue;          result = proc->opcodes[i].read(data, pos, len, offset, proc);          if (result != NULL) result->type = i; -        else -        { -            *pos = old_pos; -            printf("err while x86 decoding at 0x%08llx :: [0x%02hhx] 0x%02hhx\n", offset, proc->opcodes[i].prefix, proc->opcodes[i].opcode); -        } +          break;      } | 
