diff options
Diffstat (limited to 'src/arch/x86')
| -rw-r--r-- | src/arch/x86/Makefile.am | 3 | ||||
| -rw-r--r-- | src/arch/x86/instruction.h | 38 | ||||
| -rw-r--r-- | src/arch/x86/op_add.c | 62 | ||||
| -rw-r--r-- | src/arch/x86/op_call.c | 52 | ||||
| -rw-r--r-- | src/arch/x86/op_cmp.c | 210 | ||||
| -rw-r--r-- | src/arch/x86/op_jump.c | 159 | ||||
| -rw-r--r-- | src/arch/x86/op_mov.c | 171 | ||||
| -rw-r--r-- | src/arch/x86/op_sar.c | 92 | ||||
| -rw-r--r-- | src/arch/x86/op_sub.c | 65 | ||||
| -rw-r--r-- | src/arch/x86/op_test.c | 266 | ||||
| -rw-r--r-- | src/arch/x86/opcodes.h | 39 | ||||
| -rw-r--r-- | src/arch/x86/operand.c | 55 | ||||
| -rw-r--r-- | src/arch/x86/operand.h | 8 | ||||
| -rw-r--r-- | src/arch/x86/processor.c | 24 | 
14 files changed, 1229 insertions, 15 deletions
| diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am index b074f69..139bcde 100644 --- a/src/arch/x86/Makefile.am +++ b/src/arch/x86/Makefile.am @@ -7,10 +7,12 @@ libarchx86_a_SOURCES =					\  	op_add.c							\  	op_and.c							\  	op_call.c							\ +	op_cmp.c							\  	op_dec.c							\  	op_hlt.c							\  	op_inc.c							\  	op_int.c							\ +	op_jump.c							\  	op_lea.c							\  	op_leave.c							\  	op_nop.c							\ @@ -19,6 +21,7 @@ libarchx86_a_SOURCES =					\  	op_pop.c							\  	op_push.c							\  	op_ret.c							\ +	op_sar.c							\  	op_sbb.c							\  	op_sub.c							\  	op_test.c							\ diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index af4f7cf..68a5fff 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -38,8 +38,12 @@ typedef struct _asm_x86_instr asm_x86_instr;  /* Enumération de tous les opcodes */  typedef enum _X86Opcodes  { +    X86_OP_SUB_R1632_RM1632,                /* sub ([0x66] 0x29)           */ +      X86_OP_XOR_REG1632,                     /* xor ([0x66] 0x31)           */ +    X86_OP_CMP_RM1632_R1632,                /* cmp ([0x66] 0x39)           */ +      X86_OP_INC_E_AX,                        /* inc ([0x66] 0x40)           */      X86_OP_INC_E_CX,                        /* inc ([0x66] 0x41)           */      X86_OP_INC_E_DX,                        /* inc ([0x66] 0x42)           */ @@ -78,19 +82,27 @@ typedef enum _X86Opcodes      X86_OP_PUSH_IMM1632,                    /* push ([0x66] 0x68)          */ -    X86_OP_MOV_REG1632,                     /* mov ([0x66] 0x89)           */ +    X86_OP_JE_8,                            /* je (0x74)                   */ +    X86_OP_JNE_8,                           /* jne (0x75)                  */ + +    X86_OP_CMP_RM8_IMM8,                    /* cmp (0x80 7)                */ + +    X86_OP_ADD_IMM1632_REG1632,             /* add ([0x66] 0x81 0)         */ -    X86_OP_ADD8_REG1632,                    /* add ([0x66] 0x83)           */ -    X86_OP_OR8_REG1632,                     /* or ([0x66] 0x83)            */ -    X86_OP_ADC8_REG1632,                    /* adc ([0x66] 0x83)           */ -    X86_OP_SBB8_REG1632,                    /* sbb ([0x66] 0x83)           */ -    X86_OP_AND8_REG1632,                    /* and ([0x66] 0x83)           */ -    X86_OP_SUB8_REG1632,                    /* sub ([0x66] 0x83)           */ -    X86_OP_XOR8_REG1632,                    /* xor ([0x66] 0x83)           */ +    X86_OP_ADD8_REG1632,                    /* add ([0x66] 0x83 0)         */ +    X86_OP_OR8_REG1632,                     /* or ([0x66] 0x83 1)          */ +    X86_OP_ADC8_REG1632,                    /* adc ([0x66] 0x83 2)         */ +    X86_OP_SBB8_REG1632,                    /* sbb ([0x66] 0x83 3)         */ +    X86_OP_AND8_REG1632,                    /* and ([0x66] 0x83 4)         */ +    X86_OP_SUB8_REG1632,                    /* sub ([0x66] 0x83 5)         */ +    X86_OP_XOR8_REG1632,                    /* xor ([0x66] 0x83 6)         */ +    X86_OP_CMP_RM1632_IMM8,                 /* cmp ([0x66] 0x08 7)         */      X86_OP_TEST_RM8,                        /* test ([0x66] 0x84)          */      X86_OP_TEST_RM1632,                     /* test ([0x66] 0x85)          */ +    X86_OP_MOV_REG1632,                     /* mov ([0x66] 0x89)           */ +      X86_OP_MOV_FROM_CONTENT1632,            /* mov ([0x66] 0x8b)           */      X86_OP_LEA,                             /* lea ([0x66] 0x8d)           */   /* 66 ? */ @@ -99,6 +111,8 @@ typedef enum _X86Opcodes      X86_OP_MOV_MOFFS_TO_AL,                 /* mov (0xa0)                  */      X86_OP_MOV_MOFFS_TO_E_AX,               /* mov ([0x66] 0xa1)           */ +    X86_OP_MOV_AL_TO_MOFFS,                 /* mov (0xa2)                  */ +    X86_OP_MOV_E_AX_TO_MOFFS,               /* mov ([0x66] 0xa3)           */      X86_OP_TEST_AL,                         /* test (0xa8)                 */      X86_OP_TEST_E_AX,                       /* test ([0x66] 0xa9)          */ @@ -112,8 +126,11 @@ typedef enum _X86Opcodes      X86_OP_MOV_E_SI,                        /* mov ([0x66] 0xbe)           */      X86_OP_MOV_E_DI,                        /* mov ([0x66] 0xbf)           */ +    X86_OP_SAR_RM1632_IMM8,                 /* sar ([0x66 0xc1 7)          */ +      X86_OP_RET,                             /* ret (0xc3)                  */ +    X86_OP_MOV_IMM8_TO_RM8,                 /* mov (0xc6)                  */      X86_OP_MOV_TO_CONTENT1632,              /* mov ([0x66] 0xc7)           */      X86_OP_LEAVE,                           /* leave (0xc9)                */ @@ -122,9 +139,12 @@ typedef enum _X86Opcodes      X86_OP_CALL,                            /* call (0xe8)                 */ +    X86_OP_JMP_8,                           /* jmp (0xeb)                  */ +      X86_OP_HLT,                             /* hlt (0xf4)                  */ -    X86_OP_PUSH_CONTENT,                    /* push ([0x66] 0xff)          */   /* 66 ? */ +    X86_OP_CALL_RM1632,                     /* call ([0x66] 0xff 2)        */ +    X86_OP_PUSH_CONTENT,                    /* push ([0x66] 0xff 6)        */   /* 66 ? */      X86_OP_COUNT diff --git a/src/arch/x86/op_add.c b/src/arch/x86/op_add.c index 99a30fc..bab7f03 100644 --- a/src/arch/x86/op_add.c +++ b/src/arch/x86/op_add.c @@ -96,3 +96,65 @@ asm_x86_instr *read_instr_add8_with_reg1632(const uint8_t *data, off_t *pos, off      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 'add' (16 ou 32 bits).        * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +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 *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ +    asm_x86_operand *reg;                   /* Registre de destination     */ +    asm_x86_operand *value;                 /* Valeur empilée              */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    /* Utilisation des registres 32 bits ? */ +    if (data[*pos] == 0x66) +    { +        oprsize = switch_x86_operand_size(proc); +        (*pos)++; +    } +    else oprsize = get_x86_current_operand_size(proc); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); +    if (reg == NULL) +    { +        free(result); +        return NULL; +    } + +    value = create_new_x86_operand(); +    if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len)) +    { +        free(reg); +        free(value); +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + +    return result; + +} diff --git a/src/arch/x86/op_call.c b/src/arch/x86/op_call.c index 61d9874..f7330ca 100644 --- a/src/arch/x86/op_call.c +++ b/src/arch/x86/op_call.c @@ -81,3 +81,55 @@ asm_x86_instr *read_instr_call(const uint8_t *data, off_t *pos, off_t len, uint6      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 'call' (16 ou 32 bits).       * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_call_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        */ +    asm_x86_operand *reg;                   /* Elément à appeler           */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    /* Utilisation des registres 32 bits ? */ +    if (data[*pos] == 0x66) +    { +        oprsize = switch_x86_operand_size(proc); +        (*pos)++; +        offset++; +    } +    else oprsize = get_x86_current_operand_size(proc); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); +    if (reg == NULL) +    { +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 1; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); + +    return result; + +} diff --git a/src/arch/x86/op_cmp.c b/src/arch/x86/op_cmp.c new file mode 100644 index 0000000..9e5bcc5 --- /dev/null +++ b/src/arch/x86/op_cmp.c @@ -0,0 +1,210 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_cmp.c - décodage des comparaisons d'opérandes + * + * 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 'cmp' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_cmp_rm8_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     */ +    asm_x86_operand *reg;                   /* Registre de destination     */ +    asm_x86_operand *value;                 /* Valeur portée               */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg = x86_create_rm8_operand(data, pos, len, true); +    if (reg == NULL) +    { +        free(result); +        return NULL; +    } + +    value = create_new_x86_operand(); +    if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) +    { +        free(reg); +        free(value); +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + +    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' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_cmp_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        */ +    asm_x86_operand *reg;                   /* Registre de destination     */ +    asm_x86_operand *value;                 /* Valeur portée               */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    /* Utilisation des registres 32 bits ? */ +    if (data[*pos] == 0x66) +    { +        oprsize = switch_x86_operand_size(proc); +        (*pos)++; +    } +    else oprsize = get_x86_current_operand_size(proc); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); +    if (reg == NULL) +    { +        free(result); +        return NULL; +    } + +    value = create_new_x86_operand(); +    if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) +    { +        free(reg); +        free(value); +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + +    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     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ +    off_t reg1_pos;                         /* POsition après lecture #1   */ +    asm_x86_operand *reg1;                  /* Registre de destination     */ +    asm_x86_operand *reg2;                  /* Registre de source          */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    /* Utilisation des registres 32 bits ? */ +    if (data[*pos] == 0x66) +    { +        oprsize = switch_x86_operand_size(proc); +        (*pos)++; +    } +    else oprsize = get_x86_current_operand_size(proc); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg1_pos = *pos; +    reg1 = x86_create_rm1632_operand(data, ®1_pos, len, oprsize == AOS_32_BITS, true); +    if (reg1 == NULL) +    { +        free(result); +        return NULL; +    } + +    reg2 = x86_create_r1632_operand(data[*pos], oprsize == AOS_32_BITS, false); +    if (reg2 == NULL) +    { +        free(result); +        free(reg1); +        return NULL; +    } + +    *pos = reg1_pos; + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); + +    return result; + +} diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c new file mode 100644 index 0000000..bcfcb0f --- /dev/null +++ b/src/arch/x86/op_jump.c @@ -0,0 +1,159 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_jump.c - décodage des sauts conditionnels + * + * 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 'je' (petit saut).            * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_je_8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    asm_x86_operand *address;               /* Adresse visée réelle        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    /* TODO : 64bits */ +    address = x86_create_rel8_operand_in_32b(offset + 1, data, pos, len); +    if (address == NULL) +    { +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 1; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(address); + +    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 'jne' (petit saut).           * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_jne_8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    asm_x86_operand *address;               /* Adresse visée réelle        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    /* TODO : 64bits */ +    address = x86_create_rel8_operand_in_32b(offset + 1, data, pos, len); +    if (address == NULL) +    { +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 1; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(address); + +    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 'jmp' (petit saut).           * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_jmp_8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    asm_x86_operand *address;               /* Adresse visée réelle        */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    /* TODO : 64bits */ +    address = x86_create_rel8_operand_in_32b(offset + 1, data, pos, len); +    if (address == NULL) +    { +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 1; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(address); + +    return result; + +} diff --git a/src/arch/x86/op_mov.c b/src/arch/x86/op_mov.c index 388d67e..f5a8825 100644 --- a/src/arch/x86/op_mov.c +++ b/src/arch/x86/op_mov.c @@ -38,7 +38,7 @@  *                offset = adresse virtuelle de l'instruction.                 *  *                proc   = architecture ciblée par le désassemblage.           *  *                                                                             * -*  Description : Décode une instruction de type 'mov al, ...' (8 bits).        * +*  Description : Décode une instruction de type 'mov ..., al' (8 bits).       *  *                                                                             *  *  Retour      : Instruction mise en place ou NULL.                           *  *                                                                             * @@ -46,10 +46,175 @@  *                                                                             *  ******************************************************************************/ -asm_x86_instr *read_instr_mov_moffs8_to_al(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +asm_x86_instr *read_instr_mov_al_to_moffs8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    asm_x86_operand *value;                 /* Valeur portée               */ +    asm_x86_operand *reg;                   /* Registre de source          */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    value = x86_create_moffs8_operand(data, pos, len); +    if (value == NULL) +    { +        free(result); +        return NULL; +    } + +    reg = x86_create_r8_operand(0x00, true); +    if (reg == NULL) +    { +        free(value); +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(value); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg); + +    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 'mov ..., [e]ax' (16/32 bits).* +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_mov_e_ax_to_moffs1632(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        */ +    asm_x86_operand *value;                 /* Valeur portée               */ +    asm_x86_operand *reg;                   /* Registre de source          */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    /* Utilisation des registres 32 bits ? */ +    if (data[*pos] == 0x66) +    { +        oprsize = switch_x86_operand_size(proc); +        (*pos)++; +    } +    else oprsize = get_x86_current_operand_size(proc); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    value = x86_create_moffs1632_operand(data, pos, len, oprsize == AOS_32_BITS); +    if (value == NULL) +    { +        free(result); +        return NULL; +    } + +    reg = x86_create_r1632_operand(0x00, oprsize == AOS_32_BITS, true); +    if (reg == NULL) +    { +        free(value); +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(value); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg); + +    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 'mov' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_mov_imm8_to_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     */ +    asm_x86_operand *reg;                   /* Registre de destination     */ +    asm_x86_operand *value;                 /* Valeur portée               */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg = x86_create_rm8_operand(data, pos, len, true); +    if (reg == NULL) +    { +        free(result); +        return NULL; +    } + +    value = create_new_x86_operand(); +    if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) +    { +        free(reg); +        free(value); +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + +    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 'mov al, ...' (8 bits).       * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_mov_moffs8_to_al(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */      asm_x86_operand *reg;                   /* Registre de destination     */      asm_x86_operand *value;                 /* Valeur portée               */ @@ -148,6 +313,8 @@ asm_x86_instr *read_instr_mov_moffs1632_to_e_ax(const uint8_t *data, off_t *pos, + +  /******************************************************************************  *                                                                             *  *  Paramètres  : data   = flux de données à analyser.                         * diff --git a/src/arch/x86/op_sar.c b/src/arch/x86/op_sar.c new file mode 100644 index 0000000..187c2bb --- /dev/null +++ b/src/arch/x86/op_sar.c @@ -0,0 +1,92 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_cmp.c - décodage des comparaisons d'opérandes + * + * 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 'sar' (8 bits).               * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +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 *result;                  /* Instruction à retourner     */ +    AsmOperandSize oprsize;                 /* Taille des opérandes        */ +    asm_x86_operand *reg;                   /* Registre de destination     */ +    asm_x86_operand *value;                 /* Valeur portée               */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    /* Utilisation des registres 32 bits ? */ +    if (data[*pos] == 0x66) +    { +        oprsize = switch_x86_operand_size(proc); +        (*pos)++; +    } +    else oprsize = get_x86_current_operand_size(proc); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS, true); +    if (reg == NULL) +    { +        free(result); +        return NULL; +    } + +    value = create_new_x86_operand(); +    if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) +    { +        free(reg); +        free(value); +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + +    return result; + +} diff --git a/src/arch/x86/op_sub.c b/src/arch/x86/op_sub.c index a323aa8..f14e4a9 100644 --- a/src/arch/x86/op_sub.c +++ b/src/arch/x86/op_sub.c @@ -96,3 +96,68 @@ asm_x86_instr *read_instr_sub8_with_reg1632(const uint8_t *data, off_t *pos, off      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_r1632_to_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        */ +    off_t reg1_pos;                         /* POsition après lecture #1   */ +    asm_x86_operand *reg1;                  /* Registre de destination     */ +    asm_x86_operand *reg2;                  /* Registre de source          */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    /* Utilisation des registres 32 bits ? */ +    if (data[*pos] == 0x66) +    { +        oprsize = switch_x86_operand_size(proc); +        (*pos)++; +    } +    else oprsize = get_x86_current_operand_size(proc); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg1_pos = *pos; +    reg1 = x86_create_rm1632_operand(data, ®1_pos, len, oprsize == AOS_32_BITS, true); +    if (reg1 == NULL) +    { +        free(result); +        return NULL; +    } + +    reg2 = x86_create_r1632_operand(data[*pos], oprsize == AOS_32_BITS, false); +    if (reg2 == NULL) +    { +        free(result); +        free(reg1); +        return NULL; +    } + +    *pos = reg1_pos; + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); + +    return result; + +} diff --git a/src/arch/x86/op_test.c b/src/arch/x86/op_test.c new file mode 100644 index 0000000..9231838 --- /dev/null +++ b/src/arch/x86/op_test.c @@ -0,0 +1,266 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_test.c - décodage des comparaisons logiques + * + * 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 'test al, ...' (8 bits).      * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_test_al(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ +    asm_x86_instr *result;                  /* Instruction à retourner     */ +    asm_x86_operand *reg;                   /* Registre de destination     */ +    asm_x86_operand *value;                 /* Valeur portée               */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg = x86_create_r8_operand(0x00, true); +    if (reg == NULL) +    { +        free(result); +        return NULL; +    } + +    value = create_new_x86_operand(); +    if (!fill_imm_operand(ASM_OPERAND(value), AOS_8_BITS, data, pos, len)) +    { +        free(reg); +        free(value); +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + +    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 'test [e]ax, ...' (16/32b).   * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_test_e_ax(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        */ +    asm_x86_operand *reg;                   /* Registre de destination     */ +    asm_x86_operand *value;                 /* Valeur portée               */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    /* Utilisation des registres 32 bits ? */ +    if (data[*pos] == 0x66) +    { +        oprsize = switch_x86_operand_size(proc); +        (*pos)++; +    } +    else oprsize = get_x86_current_operand_size(proc); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg = x86_create_r1632_operand(0x00, oprsize == AOS_32_BITS, true); +    if (reg == NULL) +    { +        free(result); +        return NULL; +    } + +    value = create_new_x86_operand(); +    if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len)) +    { +        free(reg); +        free(value); +        free(result); +        return NULL; +    } + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + +    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 'test' (8 bits).              * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_test_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     */ +    off_t reg1_pos;                         /* POsition après lecture #1   */ +    asm_x86_operand *reg1;                  /* Registre de destination     */ +    asm_x86_operand *reg2;                  /* Registre de source          */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg1_pos = *pos; +    reg1 = x86_create_rm8_operand(data, ®1_pos, len, true); +    if (reg1 == NULL) +    { +        free(result); +        return NULL; +    } + +    reg2 = x86_create_r8_operand(data[*pos], false); +    if (reg2 == NULL) +    { +        free(result); +        free(reg1); +        return NULL; +    } + +    *pos = reg1_pos; + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); + +    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 'test' (16 ou 32 bits).       * +*                                                                             * +*  Retour      : Instruction mise en place ou NULL.                           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_instr *read_instr_test_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        */ +    off_t reg1_pos;                         /* POsition après lecture #1   */ +    asm_x86_operand *reg1;                  /* Registre de destination     */ +    asm_x86_operand *reg2;                  /* Registre de source          */ + +    result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + +    /* Utilisation des registres 32 bits ? */ +    if (data[*pos] == 0x66) +    { +        oprsize = switch_x86_operand_size(proc); +        (*pos)++; +    } +    else oprsize = get_x86_current_operand_size(proc); + +    ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + +    reg1_pos = *pos; +    reg1 = x86_create_rm1632_operand(data, ®1_pos, len, oprsize == AOS_32_BITS, true); +    if (reg1 == NULL) +    { +        free(result); +        return NULL; +    } + +    reg2 = x86_create_r1632_operand(data[*pos], oprsize == AOS_32_BITS, false); +    if (reg2 == NULL) +    { +        free(result); +        free(reg1); +        return NULL; +    } + +    *pos = reg1_pos; + +    ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); +    ASM_INSTRUCTION(result)->operands_count = 2; + +    ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg1); +    ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2); + +    return result; + +} diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h index 09fed4e..ef5c66c 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -40,12 +40,27 @@ asm_x86_instr *read_instr_adc8_with_reg1632(const uint8_t *, off_t *, off_t, uin  /* Décode une instruction de type 'add' (16 ou 32 bits). */  asm_x86_instr *read_instr_add8_with_reg1632(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 *); +  /* Décode une instruction de type 'and' (16 ou 32 bits). */  asm_x86_instr *read_instr_and8_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'call'. */  asm_x86_instr *read_instr_call(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'call' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_call_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/*  Décode une instruction de type 'cmp' (8 bits). */ +asm_x86_instr *x86_read_instr_cmp_rm8_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'cmp' (8 bits). */ +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_with_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +  /* Décode une instruction de type 'dec'. */  asm_x86_instr *read_instr_dec_1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -58,12 +73,30 @@ asm_x86_instr *read_instr_inc_1632(const uint8_t *, off_t *, off_t, uint64_t, co  /* Décode une instruction de type 'int'. */  asm_x86_instr *read_instr_int(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'je' (petit saut). */ +asm_x86_instr *read_instr_je_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'jne' (petit saut). */ +asm_x86_instr *read_instr_jne_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'jump' (petit saut). */ +asm_x86_instr *read_instr_jmp_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +  /* Décode une instruction de type 'lea' (16 ou 32 bits). */  asm_x86_instr *read_instr_lea(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'leave'. */  asm_x86_instr *read_instr_leave(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'mov ..., al' (8 bits). */ +asm_x86_instr *read_instr_mov_al_to_moffs8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'mov ..., [e]ax' (16/32 bits). */ +asm_x86_instr *read_instr_mov_e_ax_to_moffs1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'mov' (8 bits). */ +asm_x86_instr *read_instr_mov_imm8_to_rm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +  /* Décode une instruction de type 'mov al, ...' (8 bits). */  asm_x86_instr *read_instr_mov_moffs8_to_al(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -103,12 +136,18 @@ asm_x86_instr *read_instr_push_reg1632(const uint8_t *, off_t *, off_t, uint64_t  /* Décode une instruction de type 'ret'. */  asm_x86_instr *read_instr_ret(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* 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 *); +  /* Décode une instruction de type 'sbb'. */  asm_x86_instr *read_instr_sbb8_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);  /* Décode une instruction de type 'sub'. */  asm_x86_instr *read_instr_sub8_with_reg1632(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_to_rm1632(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 *read_instr_test_al(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index 281c139..10a908e 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -505,7 +505,7 @@ asm_x86_operand *x86_create_rm8_operand(const uint8_t *data, off_t *pos, off_t l          free(result);          result = create_new_x86_operand(); -        if (!fill_imm_operand(ASM_OPERAND(result), AOS_8_BITS, data, pos, len)) +        if (!fill_imm_operand(ASM_OPERAND(result), AOS_32_BITS/* FIXME! 16/32 */, data, pos, len))          {              free(result);              return NULL; @@ -573,7 +573,7 @@ asm_x86_operand *x86_create_rm8_operand(const uint8_t *data, off_t *pos, off_t l          case 0x80:              result->displacement = create_new_x86_operand(); -            if (!fill_imm_operand(ASM_OPERAND(result->displacement), AOS_8_BITS, data, pos, len)) +            if (!fill_imm_operand(ASM_OPERAND(result->displacement), AOS_32_BITS/* FIXME ! 16/32 */, data, pos, len))              {                  free(result->displacement);                  free(result); @@ -1188,3 +1188,54 @@ void x86_print_moffs_operand(const asm_x86_operand *operand, char *buffer, size_      }  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                           OPERANDES D'ADRESSES RELATIVES                           */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : data     = flux de données à analyser.                       * +*                pos      = position courante dans ce flux. [OUT]             * +*                len      = taille totale des données à analyser.             * +*                                                                             * +*  Description : Crée une opérande à partir d'une adresse relative (8 bits).  * +*                                                                             * +*  Retour      : Opérande mise en place ou NULL.                              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +asm_x86_operand *x86_create_rel8_operand_in_32b(uint64_t base, const uint8_t *data, off_t *pos, off_t len) +{ +    asm_x86_operand *result;                /* Emplacement à retourner     */ +    off_t init_pos;                         /* Position avant lecture      */ +    int8_t offset;                          /* Décallage à appliquer       */ +    uint32_t address;                       /* Adresse finale visée        */ + +    result = create_new_x86_operand(); + +    init_pos = *pos; +    address = base; + +    if (!read_imm_value(AOS_8_BITS, data, pos, len, &offset)) +    { +        free(result); +        return NULL; +    } + +    address = base + (*pos - init_pos) + offset; + +    if (!fill_imm_operand_with_value(ASM_OPERAND(result), AOS_32_BITS, &address)) +    { +        free(result); +        return NULL; +    } + +    return result; + +} diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h index 42e0f56..04c0cb6 100644 --- a/src/arch/x86/operand.h +++ b/src/arch/x86/operand.h @@ -86,4 +86,12 @@ void x86_print_moffs_operand(const asm_x86_operand *, char *, size_t, AsmSyntax) +/* ------------------------- OPERANDES D'ADRESSES RELATIVES ------------------------- */ + + +/* Crée une opérande à partir d'une adresse relative (8 bits). */ +asm_x86_operand *x86_create_rel8_operand_in_32b(uint64_t, const uint8_t *, off_t *, off_t); + + +  #endif  /* _ARCH_X86_OPERAND_H */ diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 7243064..e7ff753 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -194,8 +194,12 @@ AsmOperandSize switch_x86_operand_size(const asm_x86_processor *proc)  void x86_register_instructions(asm_x86_processor *proc)  { +    register_opcode(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x66, 0x29, "sub", x86_read_instr_sub_r1632_to_rm1632); +      register_opcode(proc->opcodes[X86_OP_XOR_REG1632], 0x00/*0x66*/, 0x31, "xor", read_instr_xor_with_reg1632); +    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", read_instr_inc_1632);      register_opcode(proc->opcodes[X86_OP_INC_E_CX], 0x66, 0x41, "inc", read_instr_inc_1632);      register_opcode(proc->opcodes[X86_OP_INC_E_DX], 0x66, 0x42, "inc", read_instr_inc_1632); @@ -234,6 +238,10 @@ void x86_register_instructions(asm_x86_processor *proc)      register_opcode(proc->opcodes[X86_OP_PUSH_IMM1632], 0x66, 0x68, "push", read_instr_push_imm1632); +    register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM8_IMM8], 0x00, 0x80, 7, "cmp", x86_read_instr_cmp_rm8_with_imm8); + +    register_opcode_with_ext(proc->opcodes[X86_OP_ADD_IMM1632_REG1632], 0x66, 0x81, 0, "add", x86_read_instr_add_imm1632_to_rm1632); +      register_opcode_with_ext(proc->opcodes[X86_OP_ADD8_REG1632], 0x66, 0x83, 0, "add", read_instr_add8_with_reg1632);      register_opcode_with_ext(proc->opcodes[X86_OP_OR8_REG1632], 0x66, 0x83, 1, "or", read_instr_or8_with_reg1632);      register_opcode_with_ext(proc->opcodes[X86_OP_ADC8_REG1632], 0x66, 0x83, 2, "adc", read_instr_adc8_with_reg1632); @@ -241,6 +249,10 @@ void x86_register_instructions(asm_x86_processor *proc)      register_opcode_with_ext(proc->opcodes[X86_OP_AND8_REG1632], 0x66, 0x83, 4, "and", read_instr_and8_with_reg1632);      register_opcode_with_ext(proc->opcodes[X86_OP_SUB8_REG1632], 0x66, 0x83, 5, "sub", read_instr_sub8_with_reg1632);      register_opcode_with_ext(proc->opcodes[X86_OP_XOR8_REG1632], 0x66, 0x83, 6, "xor", read_instr_xor8_with_reg1632); +    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", read_instr_je_8); +    register_opcode(proc->opcodes[X86_OP_JNE_8], 0x00, 0x75, "jne", read_instr_jne_8);      register_opcode(proc->opcodes[X86_OP_TEST_RM8], 0x00, 0x84, "test", read_instr_test_rm8);      register_opcode(proc->opcodes[X86_OP_TEST_RM1632], 0x66, 0x85, "test", read_instr_test_rm1632); @@ -253,8 +265,10 @@ void x86_register_instructions(asm_x86_processor *proc)      register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", read_instr_nop); -    register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_AL], 0x66, 0xa0, "mov", read_instr_mov_moffs8_to_al); +    register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_AL], 0x00, 0xa0, "mov", read_instr_mov_moffs8_to_al);      register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_E_AX], 0x66, 0xa1, "mov", read_instr_mov_moffs1632_to_e_ax); +    register_opcode(proc->opcodes[X86_OP_MOV_AL_TO_MOFFS], 0x00, 0xa2, "mov", read_instr_mov_al_to_moffs8); +    register_opcode(proc->opcodes[X86_OP_MOV_E_AX_TO_MOFFS], 0x66, 0xa3, "mov", read_instr_mov_e_ax_to_moffs1632);      register_opcode(proc->opcodes[X86_OP_TEST_AL], 0x00, 0xa8, "test", read_instr_test_al);      register_opcode(proc->opcodes[X86_OP_TEST_E_AX], 0x66, 0xa9, "test", read_instr_test_e_ax); @@ -268,8 +282,11 @@ void x86_register_instructions(asm_x86_processor *proc)      register_opcode(proc->opcodes[X86_OP_MOV_E_SI], 0x66, 0xbe, "mov", read_instr_mov_to_1632);      register_opcode(proc->opcodes[X86_OP_MOV_E_DI], 0x66, 0xbf, "mov", read_instr_mov_to_1632); +    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", read_instr_ret); +    register_opcode(proc->opcodes[X86_OP_MOV_IMM8_TO_RM8], 0x00, 0xc6, "mov", read_instr_mov_imm8_to_rm8);      register_opcode(proc->opcodes[X86_OP_MOV_TO_CONTENT1632], 0x66, 0xc7, "mov", read_instr_mov_to_content_1632);      register_opcode(proc->opcodes[X86_OP_LEAVE], 0x00, 0xc9, "leave", read_instr_leave); @@ -279,9 +296,12 @@ void x86_register_instructions(asm_x86_processor *proc)      register_opcode(proc->opcodes[X86_OP_CALL], 0x00, 0xe8, "call", read_instr_call); +    register_opcode(proc->opcodes[X86_OP_JMP_8], 0x00, 0xeb, "jmp", read_instr_jmp_8); +      register_opcode(proc->opcodes[X86_OP_HLT], 0x00, 0xf4, "hlt", read_instr_hlt); -    register_opcode(proc->opcodes[X86_OP_PUSH_CONTENT], 0x66, 0xff, "push", read_instr_push_content); +    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_PUSH_CONTENT], 0x66, 0xff, 6, "push", read_instr_push_content);  } | 
