From 197933fdf469ab9b8897b33c51809c128f1e3c03 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 26 Oct 2008 23:37:51 +0000 Subject: Completed support of the 0x81 and 0xc1 opcodes. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@37 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 48 +++++++ src/arch/processor.c | 5 + src/arch/x86/Makefile.am | 7 + src/arch/x86/instruction.h | 28 +++- src/arch/x86/op_adc.c | 38 +++++ src/arch/x86/op_add.c | 18 +-- src/arch/x86/op_and.c | 38 +++++ src/arch/x86/op_cmp.c | 38 +++++ src/arch/x86/op_movzx.c | 68 +++++++++ src/arch/x86/op_or.c | 38 +++++ src/arch/x86/op_rcl.c | 68 +++++++++ src/arch/x86/op_rcr.c | 68 +++++++++ src/arch/x86/op_rol.c | 68 +++++++++ src/arch/x86/op_ror.c | 68 +++++++++ src/arch/x86/op_sar.c | 4 +- src/arch/x86/op_sbb.c | 38 +++++ src/arch/x86/op_shl.c | 68 +++++++++ src/arch/x86/op_shr.c | 68 +++++++++ src/arch/x86/op_sub.c | 38 +++++ src/arch/x86/op_xor.c | 40 +++--- src/arch/x86/opcodes.h | 56 +++++++- src/arch/x86/processor.c | 346 +++++++++++++++++++++++++-------------------- 22 files changed, 1063 insertions(+), 193 deletions(-) create mode 100644 src/arch/x86/op_movzx.c create mode 100644 src/arch/x86/op_rcl.c create mode 100644 src/arch/x86/op_rcr.c create mode 100644 src/arch/x86/op_rol.c create mode 100644 src/arch/x86/op_ror.c create mode 100644 src/arch/x86/op_shl.c create mode 100644 src/arch/x86/op_shr.c diff --git a/ChangeLog b/ChangeLog index 701100a..c251af9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,51 @@ +2008-10-27 Cyrille Bagard + + * src/arch/processor.c: + Take care here of decoding failures. + + * src/arch/x86/instruction.h: + Register some new instructions. + + * src/arch/x86/Makefile.am: + Add op_movzx.c, op_rcl.c, op_rcr.c, op_rol.c, op_ror.c, op_shl.c and + op_shr.c to libarchx86_a_SOURCES. + + * src/arch/x86/op_adc.c: + * src/arch/x86/op_add.c: + * src/arch/x86/op_and.c: + * src/arch/x86/op_cmp.c: + Complete support of the 0x81 and 0xc1 opcodes. + + * src/arch/x86/opcodes.h: + Register some new instructions. + + * src/arch/x86/op_movzx.c: + First attempt to handle a two-byte instruction. + + * src/arch/x86/op_or.c: + Complete support of the 0x81 and 0xc1 opcodes. + + * src/arch/x86/op_rcl.c: + * src/arch/x86/op_rcr.c: + * src/arch/x86/op_rol.c: + * src/arch/x86/op_ror.c: + New entries: complete support of the 0x81 and 0xc1 opcodes. + + * src/arch/x86/op_sar.c: + * src/arch/x86/op_sbb.c: + Complete support of the 0x81 and 0xc1 opcodes. + + * src/arch/x86/op_shl.c: + * src/arch/x86/op_shr.c: + New entries: complete support of the 0x81 and 0xc1 opcodes. + + * src/arch/x86/op_sub.c: + * src/arch/x86/op_xor.c: + Complete support of the 0x81 and 0xc1 opcodes. + + * src/arch/x86/processor.c: + Better handle prefixes. Complete support of the 0x81 and 0xc1 opcodes. + 2008-10-21 Cyrille Bagard * src/arch/x86/processor.c: 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 . + */ + + +#include + + +#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 . + */ + + +#include + + +#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 . + */ + + +#include + + +#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 . + */ + + +#include + + +#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 . + */ + + +#include + + +#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 . + */ + + +#include + + +#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 . + */ + + +#include + + +#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; } -- cgit v0.11.2-87-g4458