From 2e5893f9261ba59e06fadcc6ddfa9a1253e286b3 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Mon, 27 Oct 2008 20:00:09 +0000 Subject: Extended the current opcode support (0x01, 0x72, 0x73, 0x88, 0xd3, 0xf7, 0xfc, 0xb6 and 0xbe). git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@38 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 41 +++++++++++++++++++++++++ src/arch/x86/Makefile.am | 5 +++- src/arch/x86/instruction.h | 29 +++++++++++++----- src/arch/x86/op_add.c | 38 ++++++++++++++++++++++++ src/arch/x86/op_cld.c | 58 ++++++++++++++++++++++++++++++++++++ src/arch/x86/op_jump.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/op_mov.c | 35 ++++++++++++++++++++++ src/arch/x86/op_movsx.c | 71 ++++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/op_movzx.c | 3 ++ src/arch/x86/op_not.c | 68 ++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/op_shl.c | 38 ++++++++++++++++++++++++ src/arch/x86/opcodes.h | 30 +++++++++++++++++-- src/arch/x86/operand.c | 12 ++++++++ src/arch/x86/operand.h | 1 + src/arch/x86/processor.c | 49 ++++++++++++++++++------------ 15 files changed, 521 insertions(+), 31 deletions(-) create mode 100644 src/arch/x86/op_cld.c create mode 100644 src/arch/x86/op_movsx.c create mode 100644 src/arch/x86/op_not.c diff --git a/ChangeLog b/ChangeLog index c251af9..e4d24d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,46 @@ 2008-10-27 Cyrille Bagard + * src/arch/x86/instruction.h: + Register some new instructions. + + * src/arch/x86/Makefile.am: + Add op_cld, op_movsx and op_not to libarchx86_a_SOURCES. + + * src/arch/x86/op_add.c: + Extend the current opcode support. + + * rc/arch/x86/op_cld.c: + New entry: handle a new opcode. + + * src/arch/x86/opcodes.h: + Register some new instructions. + + * src/arch/x86/operand.c: + * src/arch/x86/operand.h: + Accept the 'cl' register as operand. + + * src/arch/x86/op_jump.c: + * src/arch/x86/op_mov.c: + Extend the current opcode support. + + * src/arch/x86/op_movsx.c: + New entry: handle a new opcode. + + * src/arch/x86/op_movzx.c: + Extend the current opcode support. + + * src/arch/x86/op_not.c: + New entry: handle a new opcode. + + * src/arch/x86/op_shl.c: + Extend the current opcode support. + + * src/arch/x86/processor.c: + Extend the current opcode support (0x01, 0x72, 0x73, 0x88, 0xd3, 0xf7, + 0xfc, 0xb6 and 0xbe). + +2008-10-27 Cyrille Bagard + * src/arch/processor.c: Take care here of decoding failures. diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am index 58ffaa8..42326c9 100644 --- a/src/arch/x86/Makefile.am +++ b/src/arch/x86/Makefile.am @@ -7,6 +7,7 @@ libarchx86_a_SOURCES = \ op_add.c \ op_and.c \ op_call.c \ + op_cld.c \ op_cmp.c \ op_dec.c \ op_hlt.c \ @@ -15,9 +16,11 @@ libarchx86_a_SOURCES = \ op_jump.c \ op_lea.c \ op_leave.c \ - op_nop.c \ op_mov.c \ + op_movsx.c \ op_movzx.c \ + op_nop.c \ + op_not.c \ op_or.c \ op_pop.c \ op_push.c \ diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index 1c97255..0092ba0 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -39,6 +39,7 @@ typedef struct _asm_x86_instr asm_x86_instr; typedef enum _X86Opcodes { X86_OP_ADD_RM8_R8, /* add (0x00) */ + X86_OP_ADD_RM1632_R1632, /* add ([0x66] 0x01) */ X86_OP_SUB_R1632_RM1632, /* sub ([0x66] 0x29) */ @@ -89,6 +90,9 @@ typedef enum _X86Opcodes X86_OP_PUSH_IMM1632, /* push ([0x66] 0x68) */ + X86_OP_JB_REL8, /* jb (0x72) */ + X86_OP_JNB_REL8, /* jnb (0x73) */ + X86_OP_JE_8, /* je (0x74) */ X86_OP_JNE_8, /* jne (0x75) */ @@ -116,6 +120,7 @@ typedef enum _X86Opcodes X86_OP_TEST_RM8_R8, /* test ([0x66] 0x84) */ X86_OP_TEST_RM1632_R1632, /* test ([0x66] 0x85) */ + X86_OP_MOV_RM8_R8, /* mov (0x88) */ X86_OP_MOV_RM1632_R1632, /* mov ([0x66] 0x89) */ X86_OP_MOV_R1632_RM1632, /* mov ([0x66] 0x8b) */ @@ -141,14 +146,14 @@ 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_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) */ @@ -159,6 +164,8 @@ typedef enum _X86Opcodes X86_OP_INT, /* int (0xcd) */ + X86_OP_SHL_RM1632_CL, /* shl ([0x66] 0xd3 4) */ + X86_OP_CALL_REL1632, /* call ([0x66] 0xe8) */ X86_OP_JMP_REL1632, /* jmp ([0x66] 0xe9) */ @@ -166,12 +173,18 @@ typedef enum _X86Opcodes X86_OP_HLT, /* hlt (0xf4) */ + X86_OP_NOT_RM1632, /* not ([0x66] 0xf7 2) */ + + X86_OP_CLD, /* cld (0xfc) */ + X86_OP_CALL_RM1632, /* call ([0x66] 0xff 2) */ 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_MOVSX_R1632_RM8, /* movsx ([0x66] 0x0f 0xbe) */ + X86_OP_COUNT } X86Opcodes; diff --git a/src/arch/x86/op_add.c b/src/arch/x86/op_add.c index 42e8d3b..b065617 100644 --- a/src/arch/x86/op_add.c +++ b/src/arch/x86/op_add.c @@ -139,3 +139,41 @@ asm_x86_instr *x86_read_instr_add_rm1632_imm1632(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 'add' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_add_rm1632_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 */ + + 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_R1632, oprsize)) + { + free(result); + return NULL; + } + + return result; + +} diff --git a/src/arch/x86/op_cld.c b/src/arch/x86/op_cld.c new file mode 100644 index 0000000..c6d5411 --- /dev/null +++ b/src/arch/x86/op_cld.c @@ -0,0 +1,58 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_cld.c - décodage de la suppression du drapeau de direction + * + * 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" + + + +/****************************************************************************** +* * +* 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 'cld'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_cld(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + return result; + +} diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c index 3739b24..44256e9 100644 --- a/src/arch/x86/op_jump.c +++ b/src/arch/x86/op_jump.c @@ -38,6 +38,43 @@ * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * +* Description : Décode une instruction de type 'jb' (saut 8b si inférieur). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_jb_rel8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + ASM_INSTRUCTION(result)->type = AIT_JUMP; + + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset)) + { + 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 'je' (petit saut). * * * * Retour : Instruction mise en place ou NULL. * @@ -75,6 +112,43 @@ asm_x86_instr *x86_read_instr_je_8(const uint8_t *data, off_t *pos, off_t len, u * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * +* Description : Décode une instruction de type 'jnb' (saut 8b si !inférieur).* +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_jnb_rel8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + ASM_INSTRUCTION(result)->type = AIT_JUMP; + + if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset)) + { + 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 'jne' (petit saut). * * * * Retour : Instruction mise en place ou NULL. * diff --git a/src/arch/x86/op_mov.c b/src/arch/x86/op_mov.c index 01e04ff..efa23c4 100644 --- a/src/arch/x86/op_mov.c +++ b/src/arch/x86/op_mov.c @@ -392,3 +392,38 @@ asm_x86_instr *x86_read_instr_mov_rm1632_to_r1632(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 'mov' (8 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_mov_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 */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8)) + { + free(result); + return NULL; + } + + return result; + +} diff --git a/src/arch/x86/op_movsx.c b/src/arch/x86/op_movsx.c new file mode 100644 index 0000000..461309f --- /dev/null +++ b/src/arch/x86/op_movsx.c @@ -0,0 +1,71 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_movsx.c - décodage des copies d'opérandes sans 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 'movsx' (8 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_movsx_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)); + + /* 0x0f : passage en mode 2 octets */ + (*pos)++; + + 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_movzx.c b/src/arch/x86/op_movzx.c index bb781cf..4df1303 100644 --- a/src/arch/x86/op_movzx.c +++ b/src/arch/x86/op_movzx.c @@ -53,6 +53,9 @@ asm_x86_instr *x86_read_instr_movzx_r1632_rm8(const uint8_t *data, off_t *pos, o result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + /* 0x0f : passage en mode 2 octets */ + (*pos)++; + oprsize = switch_x86_operand_size_if_needed(proc, data, pos); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; diff --git a/src/arch/x86/op_not.c b/src/arch/x86/op_not.c new file mode 100644 index 0000000..6deb61c --- /dev/null +++ b/src/arch/x86/op_not.c @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_not.c - décodage des négations par complément à un + * + * 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 'not' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_not_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_one_operand(result, data, pos, len, X86_OTP_RM1632, oprsize)) + { + free(result); + return NULL; + } + + return result; + +} diff --git a/src/arch/x86/op_shl.c b/src/arch/x86/op_shl.c index 4e2bbba..fbcb0db 100644 --- a/src/arch/x86/op_shl.c +++ b/src/arch/x86/op_shl.c @@ -38,6 +38,44 @@ * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * +* Description : Décode une instruction de type 'shl'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *x86_read_instr_shl_rm1632_cl(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_CL, 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 'shl' (8 bits). * * * * Retour : Instruction mise en place ou NULL. * diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h index 56f5b2f..54398d3 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -46,21 +46,27 @@ asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *, off_t *, off_t /* 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 *); +/* 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 'add' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_add_rm1632_r1632(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_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 *); /* 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 'cld'. */ +asm_x86_instr *x86_read_instr_cld(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 *); @@ -85,9 +91,15 @@ asm_x86_instr *x86_read_instr_inc_r1632(const uint8_t *, off_t *, off_t, uint64_ /* Décode une instruction de type 'int'. */ asm_x86_instr *x86_read_instr_int(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'jb' (saut 8b si inférieur). */ +asm_x86_instr *x86_read_instr_jb_rel8(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 *x86_read_instr_je_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'jnb' (saut 8b si !inférieur). */ +asm_x86_instr *x86_read_instr_jnb_rel8(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 *x86_read_instr_jne_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); @@ -133,12 +145,21 @@ 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 'mov' (8 bits). */ +asm_x86_instr *x86_read_instr_mov_rm8_r8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'movsx' (8 bits). */ +asm_x86_instr *x86_read_instr_movsx_r1632_rm8(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 'not' (16 ou 32 bits). */ +asm_x86_instr *x86_read_instr_not_rm1632(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 *); @@ -184,6 +205,9 @@ asm_x86_instr *x86_read_instr_sbb_rm1632_with_imm8(const uint8_t *, off_t *, off /* 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'. */ +asm_x86_instr *x86_read_instr_shl_rm1632_cl(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 *); diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index e13c793..a028dc2 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -1436,6 +1436,10 @@ bool x86_read_one_operand(asm_x86_instr *instr, const uint8_t *data, off_t *pos, op = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS); break; + case X86_OTP_CL: + op = x86_create_r8_operand(0x01, true); + break; + case X86_OTP_AL: op = x86_create_r8_operand(0x00, true); break; @@ -1545,6 +1549,10 @@ bool x86_read_two_operands(asm_x86_instr *instr, const uint8_t *data, off_t *pos op1 = x86_create_rm1632_operand(data, &op1_pos, len, oprsize == AOS_32_BITS); break; + case X86_OTP_CL: + op1 = x86_create_r8_operand(0x01, op1_first); + break; + case X86_OTP_AL: op1 = x86_create_r8_operand(0x00, op1_first); break; @@ -1616,6 +1624,10 @@ bool x86_read_two_operands(asm_x86_instr *instr, const uint8_t *data, off_t *pos op2 = x86_create_rm1632_operand(data, &op2_pos, len, oprsize == AOS_32_BITS); break; + case X86_OTP_CL: + op2 = x86_create_r8_operand(0x01, op2_first); + break; + case X86_OTP_AL: op2 = x86_create_r8_operand(0x00, op2_first); break; diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h index c48a0be..c9ade39 100644 --- a/src/arch/x86/operand.h +++ b/src/arch/x86/operand.h @@ -128,6 +128,7 @@ typedef enum _X86OperandType X86_OTP_RM8 = X86_OTP_RM(1), /* Registre 8 bits ou mémoire */ X86_OTP_RM1632 = X86_OTP_RM(2), /* Registre 16/32b ou mémoire */ + X86_OTP_CL = 0x0ffd, /* Registre cl */ X86_OTP_AL = 0x0ffe, /* Registre al */ X86_OTP_E_AX = 0x0fff /* Registre eax ou ax */ diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 3fde754..8cc3a72 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -239,6 +239,7 @@ 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, "add", x86_read_instr_add_rm8_r8); + register_opcode(proc->opcodes[X86_OP_ADD_RM1632_R1632], 0x01, "add", x86_read_instr_add_rm1632_r1632); register_opcode_1632(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x29, "sub", x86_read_instr_sub_r1632_from_rm1632); @@ -289,6 +290,9 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode_1632(proc->opcodes[X86_OP_PUSH_IMM1632], 0x68, "push", x86_read_instr_push_imm1632); + register_opcode(proc->opcodes[X86_OP_JB_REL8], 0x72, "jb", x86_read_instr_jb_rel8); + register_opcode(proc->opcodes[X86_OP_JNB_REL8], 0x73, "jnb", x86_read_instr_jnb_rel8); + 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); @@ -316,6 +320,7 @@ void x86_register_instructions(asm_x86_processor *proc) 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(proc->opcodes[X86_OP_MOV_RM8_R8], 0x88, "mov", x86_read_instr_mov_rm8_r8); 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); @@ -359,6 +364,7 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode(proc->opcodes[X86_OP_INT], 0xcd, "int", x86_read_instr_int); + register_opcode_1632_with_ext(proc->opcodes[X86_OP_SHL_RM1632_CL], 0xd3, 4, "shl", x86_read_instr_shl_rm1632_cl); 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); @@ -367,11 +373,17 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode(proc->opcodes[X86_OP_HLT], 0xf4, "hlt", x86_read_instr_hlt); + register_opcode_1632_with_ext(proc->opcodes[X86_OP_NOT_RM1632], 0xf7, 7, "not", x86_read_instr_not_rm1632); + + register_opcode(proc->opcodes[X86_OP_CLD], 0xfc, "cld", x86_read_instr_cld); + 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); + register_2b_opcode_1632(proc->opcodes[X86_OP_MOVZX_R1632_RM8], 0xb6, "movzx", x86_read_instr_movzx_r1632_rm8); + + register_2b_opcode_1632(proc->opcodes[X86_OP_MOVSX_R1632_RM8], 0xbe, "movsx", x86_read_instr_movsx_r1632_rm8); } @@ -398,33 +410,32 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d { asm_x86_instr *result; /* Résultat à faire remonter */ X86Prefix prefix; /* Préfixe détecté */ + off_t k; /* Itération sur le contenu */ X86Opcodes i; /* Boucle de parcours */ result = NULL; prefix = X86_PRE_NONE; - consume_prefix: - - switch (data[*pos]) - { - case 0x66: - prefix |= X86_PRE_OPSIZE; - (*pos)++; - break; + for (k = *pos; k < len; k++) + switch (data[k]) + { + case 0x66: + prefix |= X86_PRE_OPSIZE; + break; - case 0x0f: - prefix |= X86_PRE_ESCAPE; - (*pos)++; - break; + case 0x0f: + prefix |= X86_PRE_ESCAPE; + break; - default: - goto found_instr; - break; + default: + goto found_instr; + break; - } + } - goto consume_prefix; + /* Contenu binaire tronqué */ + return NULL; found_instr: @@ -432,7 +443,7 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d { if ((prefix & proc->opcodes[i].prefix) != prefix) continue; - if (data[*pos] != proc->opcodes[i].opcode) continue; + if (data[k] != proc->opcodes[i].opcode) continue; result = proc->opcodes[i].read(data, pos, len, offset, proc); if (result != NULL) result->type = i; -- cgit v0.11.2-87-g4458