diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/instruction.c | 507 | ||||
-rw-r--r-- | src/arch/x86/op_jump.c | 2 | ||||
-rw-r--r-- | src/arch/x86/op_scas.c | 63 | ||||
-rw-r--r-- | src/arch/x86/operand.c | 14 | ||||
-rw-r--r-- | src/arch/x86/operand.h | 10 | ||||
-rw-r--r-- | src/arch/x86/registers.c | 530 | ||||
-rw-r--r-- | src/arch/x86/registers.h | 54 |
7 files changed, 1167 insertions, 13 deletions
diff --git a/src/arch/x86/instruction.c b/src/arch/x86/instruction.c new file mode 100644 index 0000000..f68ec59 --- /dev/null +++ b/src/arch/x86/instruction.c @@ -0,0 +1,507 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * instruction.c - gestion des instructions de l'architecture x86 + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "instruction.h" + + +#include "../instruction-int.h" +#include "../../common/extstr.h" + + + +/* Définition générique d'une instruction d'architecture x86 (instance) */ +struct _GX86Instruction +{ + GArchInstruction parent; /* A laisser en premier */ + + X86Opcodes type; /* Position dans la liste */ + + X86Prefix prefixes; /* Préfixes finalement trouvés */ + +}; + +/* Définition générique d'une instruction d'architecture x86 (classe) */ +struct _GX86InstructionClass +{ + GArchInstructionClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des instructions pour x86. */ +static void g_x86_instruction_class_init(GX86InstructionClass *); + +/* Initialise une instance d'opérande d'architecture x86. */ +static void g_x86_instruction_init(GX86Instruction *); + + + +/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */ + + +/* Répertoire de toutes les instructions x86 */ +typedef struct _x86_instruction +{ + bool care_of_data; /* Devinette = repas ? */ + bin_t opcode; /* Opcode de l'instruction */ + bin_t op_extension; /* Extension de l'opcode */ + + const char *keyword; /* Mot clef de la commande */ + + X86Prefix prefix; /* Eventuel(s) préfixe(s) */ + +} x86_instruction; + + +#define OPCODE_EXT(eop) ((eop) & 0x38) +#define IDX_TO_EXT(idx) (idx == -1 ? 0xff : idx << 3) + + +static x86_instruction _instructions[XOP_COUNT] = { + + [XOP_ADD_RM8_R8] = { false, 0x00, IDX_TO_EXT(-1), "add", XPX_NONE }, + [XOP_ADD_RM1632_R1632] = { false, 0x01, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADD_R8_RM8] = { false, 0x02, IDX_TO_EXT(-1), "add", XPX_NONE }, + [XOP_ADD_R1632_RM1632] = { false, 0x03, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADD_AL_IMM8] = { false, 0x04, IDX_TO_EXT(-1), "add", XPX_NONE }, + [XOP_ADD_E_AX_IMM1632] = { false, 0x05, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE }, + + [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE }, + [XOP_OR_AL_IMM8] = { false, 0x0c, IDX_TO_EXT(-1), "or", XPX_NONE }, + + [XOP_ADC_RM8_R8] = { false, 0x10, IDX_TO_EXT(-1), "adc", XPX_NONE }, + + [XOP_AND_RM8_R8] = { false, 0x20, IDX_TO_EXT(-1), "and", XPX_NONE }, + + [XOP_SUB_RM1632_R1632] = { false, 0x29, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, + + [XOP_SUB_R8_RM8] = { false, 0x2a, IDX_TO_EXT(-1), "sub", XPX_NONE }, + [XOP_SUB_AL_IMM8] = { false, 0x2c, IDX_TO_EXT(-1), "sub", XPX_NONE }, + + [XOP_SUB_E_AX_IMM1632] = { false, 0x2d, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE }, + + + + [XOP_XOR_RM8_R8] = { false, 0x30, IDX_TO_EXT(-1), "xor", XPX_NONE}, + [XOP_XOR_RM1632_R1632] = { false, 0x31, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XOR_R8_RM8] = { false, 0x32, IDX_TO_EXT(-1), "xor", XPX_NONE}, + [XOP_XOR_R1632_RM1632] = { false, 0x33, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XOR_AL_IMM8] = { false, 0x34, IDX_TO_EXT(-1), "xor", XPX_NONE }, + [XOP_XOR_E_AX_IMM1632] = { false, 0x35, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + + + + + + [XOP_CMP_RM1632_R1632] = { false, 0x39, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_AX] = { true, 0x40, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_CX] = { true, 0x41, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_DX] = { true, 0x42, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_BX] = { true, 0x43, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_SP] = { true, 0x44, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_BP] = { true, 0x45, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_SI] = { true, 0x46, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_INC_E_DI] = { true, 0x47, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_AX] = { true, 0x48, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_CX] = { true, 0x49, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_DX] = { true, 0x4a, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_BX] = { true, 0x4b, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_SP] = { true, 0x4c, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_BP] = { true, 0x4d, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_SI] = { true, 0x4e, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_DEC_E_DI] = { true, 0x4f, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_AX] = { true, 0x50, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_CX] = { true, 0x51, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_DX] = { true, 0x52, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_BX] = { true, 0x53, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_SP] = { true, 0x54, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_BP] = { true, 0x55, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_SI] = { true, 0x56, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_E_DI] = { true, 0x57, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_AX] = { true, 0x58, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_CX] = { true, 0x59, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_DX] = { true, 0x5a, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_BX] = { true, 0x5b, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_SP] = { true, 0x5c, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_BP] = { true, 0x5d, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_SI] = { true, 0x5e, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_POP_E_DI] = { true, 0x5f, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_PUSH_IMM1632] = { false, 0x68, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE }, + + + + [XOP_JO_REL8] = { false, 0x70, IDX_TO_EXT(-1), "jo", XPX_NONE }, + [XOP_JNO_REL8] = { false, 0x71, IDX_TO_EXT(-1), "jno", XPX_NONE }, + [XOP_JB_REL8] = { false, 0x72, IDX_TO_EXT(-1), "jb", XPX_NONE }, + [XOP_JNB_REL8] = { false, 0x73, IDX_TO_EXT(-1), "jnb", XPX_NONE }, + [XOP_JE_REL8] = { false, 0x74, IDX_TO_EXT(-1), "je", XPX_NONE }, + [XOP_JNE_REL8] = { false, 0x75, IDX_TO_EXT(-1), "jne", XPX_NONE }, + [XOP_JNA_REL8] = { false, 0x76, IDX_TO_EXT(-1), "jna", XPX_NONE }, + [XOP_JA_REL8] = { false, 0x77, IDX_TO_EXT(-1), "ja", XPX_NONE }, + [XOP_JS_REL8] = { false, 0x78, IDX_TO_EXT(-1), "js", XPX_NONE }, + [XOP_JNS_REL8] = { false, 0x79, IDX_TO_EXT(-1), "jns", XPX_NONE }, + [XOP_JP_REL8] = { false, 0x7a, IDX_TO_EXT(-1), "jp", XPX_NONE }, + [XOP_JNP_REL8] = { false, 0x7b, IDX_TO_EXT(-1), "jnp", XPX_NONE }, + [XOP_JL_REL8] = { false, 0x7c, IDX_TO_EXT(-1), "jl", XPX_NONE }, + [XOP_JNL_REL8] = { false, 0x7d, IDX_TO_EXT(-1), "jnl", XPX_NONE }, + [XOP_JNG_REL8] = { false, 0x7e, IDX_TO_EXT(-1), "jng", XPX_NONE }, + [XOP_JG_REL8] = { false, 0x7f, IDX_TO_EXT(-1), "jg", XPX_NONE }, + [XOP_ADD_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(0), "add", XPX_NONE }, + [XOP_OR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(1), "or", XPX_NONE }, + [XOP_ADC_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(2), "adc", XPX_NONE }, + [XOP_SBB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(3), "sbb", XPX_NONE }, + [XOP_AND_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(4), "and", XPX_NONE }, + [XOP_SUB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(5), "sub", XPX_NONE }, + [XOP_XOR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(6), "xor", XPX_NONE }, + [XOP_CMP_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(7), "cmp", XPX_NONE }, + [XOP_ADD_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_OR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADC_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SBB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_AND_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SUB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XOR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_CMP_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, + + + + [XOP_ADD_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_OR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(1), "or", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ADC_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SBB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_AND_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SUB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XOR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_CMP_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_TEST_RM8_R8] = { false, 0x84, IDX_TO_EXT(-1), "test", XPX_NONE }, + [XOP_TEST_RM1632_R1632] = { false, 0x85, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, + + [XOP_MOV_RM8_R8] = { false, 0x88, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_RM1632_R1632] = { false, 0x89, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_MOV_R1632_RM1632] = { false, 0x8b, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_LEA_R1632_M] = { false, 0x8d, IDX_TO_EXT(-1), "lea", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_NOP] = { false, 0x90, IDX_TO_EXT(-1), "nop", XPX_NONE }, + [XOP_XCHG_R1632_E_AX] = { true, 0x90, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_CX] = { true, 0x91, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_DX] = { true, 0x92, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_BX] = { true, 0x93, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_SP] = { true, 0x94, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_BP] = { true, 0x95, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_SI] = { true, 0x96, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_XCHG_R1632_E_DI] = { true, 0x97, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE }, + + + + [XOP_MOV_AL_MOFFS8] = { false, 0xa0, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_E_AX_MOFFS1632] = { false, 0xa1, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_MOFFS8_AL] = { false, 0xa2, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_MOFFS1632_E_AX] = { false, 0xa3, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_TEST_AL_IMM8] = { false, 0xa8, IDX_TO_EXT(-1), "test", XPX_NONE }, + [XOP_TEST_E_AX_IMM1632] = { false, 0xa9, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_SCAS_AL_M8] = { false, 0xae, IDX_TO_EXT(-1), "scas", XPX_NONE }, + + + [XOP_MOV_AL_IMM8] = { true, 0xb0, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_CL_IMM8] = { true, 0xb1, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_DL_IMM8] = { true, 0xb2, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_BL_IMM8] = { true, 0xb3, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_AH_IMM8] = { true, 0xb4, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_CH_IMM8] = { true, 0xb5, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_DH_IMM8] = { true, 0xb6, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_BH_IMM8] = { true, 0xb7, IDX_TO_EXT(-1), "mov", XPX_NONE }, + [XOP_MOV_E_AX_IMM1632] = { true, 0xb8, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_CX_IMM1632] = { true, 0xb9, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_DX_IMM1632] = { true, 0xba, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_BX_IMM1632] = { true, 0xbb, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_SP_IMM1632] = { true, 0xbc, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_BP_IMM1632] = { true, 0xbd, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_SI_IMM1632] = { true, 0xbe, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_MOV_E_DI_IMM1632] = { true, 0xbf, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + + + + [XOP_ROL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(0), "rol", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_ROR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(1), "ror", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_RCL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(2), "rcl", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_RCR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(3), "rcr", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SHL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SHR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(5), "shr", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SAL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(6), "sal", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_SAR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(7), "sar", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_RET] = { false, 0xc3, IDX_TO_EXT(-1), "ret", XPX_NONE }, + + + [XOP_MOV_RM8_IMM8] = { false, 0xc6, IDX_TO_EXT(0), "mov", XPX_NONE }, + [XOP_MOV_RM1632_IMM1632] = { false, 0xc7, IDX_TO_EXT(0), "mov", XPX_OPERAND_SIZE_OVERRIDE }, + + + + [XOP_LEAVE] = { false, 0xc9, IDX_TO_EXT(-1), "leave", XPX_NONE }, + + + [XOP_INT_3] = { false, 0xcc, IDX_TO_EXT(-1), "int", XPX_NONE }, + [XOP_INT] = { false, 0xcd, IDX_TO_EXT(-1), "int", XPX_NONE }, + + + [XOP_SHL_RM1632_CL] = { false, 0xd3, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_CALL_REL1632] = { false, 0xe8, IDX_TO_EXT(-1), "call", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JMP_REL1632] = { false, 0xe9, IDX_TO_EXT(-1), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, + + [XOP_JMP_REL8] = { false, 0xeb, IDX_TO_EXT(-1), "jmp", XPX_NONE }, + + [XOP_HLT] = { false, 0xf4, IDX_TO_EXT(-1), "hlt", XPX_NONE }, + + [XOP_NOT_RM1632] = { false, 0xf7, IDX_TO_EXT(2), "not", XPX_OPERAND_SIZE_OVERRIDE }, + + + [XOP_CLD] = { false, 0xfc, IDX_TO_EXT(-1), "cld", XPX_NONE }, + + [XOP_CALL_RM1632] = { false, 0xff, IDX_TO_EXT(2), "call", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_JMP_RM1632] = { false, 0xff, IDX_TO_EXT(4), "jmp", XPX_OPERAND_SIZE_OVERRIDE }, + [XOP_PUSH_RM1632] = { false, 0xff, IDX_TO_EXT(6), "push", XPX_OPERAND_SIZE_OVERRIDE } + +}; + + + + + +/* Traduit une instruction en version humainement lisible. */ +static const char *x86_get_instruction_text(const GX86Instruction *, const exe_format *, AsmSyntax); + + + + + + +/* Indique le type défini pour une instruction d'architecture x86. */ +G_DEFINE_TYPE(GX86Instruction, g_x86_instruction, G_TYPE_ARCH_INSTRUCTION); + + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des instructions pour x86. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_x86_instruction_class_init(GX86InstructionClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance à initialiser. * +* * +* Description : Initialise une instance d'instruction d'architecture x86. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_x86_instruction_init(GX86Instruction *instr) +{ + GArchInstruction *parent; /* Instance parente */ + + parent = G_ARCH_INSTRUCTION(instr); + + parent->get_text = (get_instruction_text_fc)x86_get_instruction_text; + +} + + +/****************************************************************************** +* * +* Paramètres : type = type d'instruction à représenter. * +* * +* Description : Crée une instruction pour l'architecture x86. * +* * +* Retour : Architecture mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *g_x86_instruction_new(X86Opcodes type) +{ + GArchInstruction *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_X86_INSTRUCTION, NULL); + + G_X86_INSTRUCTION(result)->type = type; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à venir compléter. * +* prefixes = listes des préfixes rencontrés. * +* * +* Description : Attache à une instructions ses préfixes associés. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_x86_instruction_set_prefixes(GX86Instruction *instr, X86Prefix prefixes) +{ + instr->prefixes = prefixes; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* AIDE A LA MISE EN PLACE D'INSTRUCTIONS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. * +* len = taille totale des données à analyser. * +* prefix = éventuel(s) préfixe(s) remarqué(s). [OUT] * +* care = la lecture de l'instr. veut-elle les opcodes ? [OUT]* +* * +* Description : Recherche l'identifiant de la prochaine instruction. * +* * +* Retour : Identifiant de la prochaine instruction à tenter de charger. * +* * +* Remarques : - * +* * +******************************************************************************/ + +X86Opcodes x86_guess_next_instruction(const bin_t *data, off_t pos, off_t len, X86Prefix *prefix, bool *care) +{ + X86Opcodes result; /* Identifiant à retourner */ + X86Prefix extra; /* Préfixes n'intervenant pas */ + bin_t opcode; /* Opcode à trouver */ + + extra = XPX_NONE; + *prefix = XPX_NONE; + + while (pos < len) + switch (data[pos]) + { + case 0x66: + pos++; + *prefix |= XPX_OPERAND_SIZE_OVERRIDE; + break; + case 0xf2: + pos++; + extra |= XPX_REPEAT_STRING_OPERATION; + break; + default: + goto xgni_look_for; + break; + } + + xgni_look_for: + + if (pos == len) return XOP_COUNT; + + opcode = data[pos]; + + for (result = 0; result < XOP_COUNT; result++) + { + if ((_instructions[result].prefix & *prefix) != *prefix) continue; + + if (_instructions[result].opcode != opcode) continue; + + if (_instructions[result].op_extension != IDX_TO_EXT(-1)) + { + if ((pos + 1) == len) continue; + if (_instructions[result].op_extension != OPCODE_EXT(data[pos + 1])) continue; + } + + *prefix |= extra; + *care = _instructions[result].care_of_data; + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instruction à traiter. * +* format = format du binaire manipulé. * +* syntax = type de représentation demandée. * +* * +* Description : Traduit une instruction en version humainement lisible. * +* * +* Retour : Chaîne de caractères à libérer de la mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static const char *x86_get_instruction_text(const GX86Instruction *instr, const exe_format *format, AsmSyntax syntax) +{ + const char *result; /* Chaîne à retourner */ + + result = strdup(_instructions[instr->type].keyword); + + if (instr->prefixes & XPX_REPEAT_STRING_OPERATION) + result = strprep(result, "repnz "); + + return result; + +} diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c index 709ff24..be993f1 100644 --- a/src/arch/x86/op_jump.c +++ b/src/arch/x86/op_jump.c @@ -1,6 +1,6 @@ /* OpenIDA - Outil d'analyse de fichiers binaires - * op_jump.c - décodage des sauts conditionnels + * op_jump.c - décodage des sauts inconditionnels * * Copyright (C) 2008 Cyrille Bagard * diff --git a/src/arch/x86/op_scas.c b/src/arch/x86/op_scas.c new file mode 100644 index 0000000..2ec8230 --- /dev/null +++ b/src/arch/x86/op_scas.c @@ -0,0 +1,63 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_scas.c - décodage des recherches dans des chaînes ASCII + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* addr = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'scas al, ...' (8 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *x86_read_instr_scas_al_m8(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc) +{ + GArchInstruction *result; /* Instruction à retourner */ + + result = g_x86_instruction_new(XOP_SCAS_AL_M8); + + if (!x86_read_two_operands(result, data, pos, len, X86_OTP_AL, X86_OTP_AL/*FIXME*/)) + { + /* TODO free(result);*/ + return NULL; + } + + return result; + +} diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c index e916541..5e01fd7 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -40,7 +40,7 @@ /* ---------------------- COQUILLE VIDE POUR LES OPERANDES X86 ---------------------- */ -/* Définition d'un opérande de la x86 (instance) */ +/* Définition d'un opérande de x86 (instance) */ struct _GX86Operand { GArchOperand parent; /* Instance parente */ @@ -48,7 +48,7 @@ struct _GX86Operand }; -/* Définition d'un opérande de la x86 (classe) */ +/* Définition d'un opérande de x86 (classe) */ struct _GX86OperandClass { GArchOperandClass parent; /* Classe parente */ @@ -59,7 +59,7 @@ struct _GX86OperandClass /* Initialise la classe des opérandes x86 de base. */ static void g_x86_operand_class_init(GX86OperandClass *); -/* Initialise une instance d'opérande de base pour la x86. */ +/* Initialise une instance d'opérande de base pour x86. */ static void g_x86_operand_init(GX86Operand *); @@ -224,7 +224,7 @@ static void g_x86_operand_class_init(GX86OperandClass *klass) * * * Paramètres : operand = instance à initialiser. * * * -* Description : Initialise une instance d'opérande de registre x86. * +* Description : Initialise une instance d'opérande de base pour x86. * * * * Retour : - * * * @@ -297,7 +297,7 @@ static void g_x86_register_operand_init(GX86RegisterOperand *operand) * size = taille de l'opérande, et donc du registre. * * base = indice du premier registre. * * * -* Description : Crée un opérande visant un registre X86. * +* Description : Crée un opérande visant un registre x86. * * * * Retour : Opérande mis en place. * * * @@ -336,7 +336,7 @@ GArchOperand *g_x86_register_operand_new_from_opcode(const bin_t *data, off_t *p * size = taille de l'opérande, et donc du registre. * * first = indique la partie du ModR/M à traiter. * * * -* Description : Crée un opérande visant un registre X86. * +* Description : Crée un opérande visant un registre x86. * * * * Retour : Opérande mis en place. * * * @@ -376,7 +376,7 @@ GArchOperand *g_x86_register_operand_new_from_mod_rm(const bin_t *data, off_t *p * Paramètres : index = indice du registre visé. * * size = taille de l'opérande, et donc du registre. * * * -* Description : Crée un opérande visant un registre X86 donnée. * +* Description : Crée un opérande visant un registre x86 donné. * * * * Retour : Opérande mis en place. * * * diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h index ebab200..1139fe2 100644 --- a/src/arch/x86/operand.h +++ b/src/arch/x86/operand.h @@ -41,10 +41,10 @@ #define G_X86_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_x86_operand_get_type(), GX86OperandIface)) -/* Définition d'un opérande de la x86 (instance) */ +/* Définition d'un opérande de x86 (instance) */ typedef struct _GX86Operand GX86Operand; -/* Définition d'un opérande de la x86 (classe) */ +/* Définition d'un opérande de x86 (classe) */ typedef struct _GX86OperandClass GX86OperandClass; @@ -72,13 +72,13 @@ typedef struct _GX86RegisterOperandClass GX86RegisterOperandClass; /* Indique le type défini par la GLib pour un opérande de registre x86. */ GType g_x86_register_operand_get_type(void); -/* Crée un opérande visant un registre X86. */ +/* Crée un opérande visant un registre x86. */ GArchOperand *g_x86_register_operand_new_from_opcode(const bin_t *, off_t *, off_t, AsmOperandSize, bin_t); -/* Crée un opérande visant un registre X86. */ +/* Crée un opérande visant un registre x86. */ GArchOperand *g_x86_register_operand_new_from_mod_rm(const bin_t *, off_t *, off_t, AsmOperandSize, bool); -/* Crée un opérande visant un registre X86 donnée. */ +/* Crée un opérande visant un registre x86 donné. */ GArchOperand *g_x86_register_operand_new_from_index(bin_t, AsmOperandSize); diff --git a/src/arch/x86/registers.c b/src/arch/x86/registers.c new file mode 100644 index 0000000..802e2f6 --- /dev/null +++ b/src/arch/x86/registers.c @@ -0,0 +1,530 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * registers.c - aides auxiliaires relatives aux registres x86 + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "registers.h" + + +#include <malloc.h> +#include <stdio.h> + + + +/* Liste des registres 8 bits */ +typedef enum _X868bRegister +{ + X86_REG8_AL = 0, /* Registre AL */ + X86_REG8_CL = 1, /* Registre AL */ + X86_REG8_DL = 2, /* Registre AL */ + X86_REG8_BL = 3, /* Registre AL */ + X86_REG8_AH = 4, /* Registre AH */ + X86_REG8_CH = 5, /* Registre AH */ + X86_REG8_DH = 6, /* Registre AH */ + X86_REG8_BH = 7, /* Registre AH */ + + X86_REG8_NONE /* Aucun registre */ + +} X868bRegister; + +/* Liste des registres 16 bits */ +typedef enum _X8616bRegister +{ + X86_REG16_AX = 0, /* Registre AX */ + X86_REG16_CX = 1, /* Registre AX */ + X86_REG16_DX = 2, /* Registre AX */ + X86_REG16_BX = 3, /* Registre AX */ + X86_REG16_SP = 4, /* Registre SP */ + X86_REG16_BP = 5, /* Registre BP */ + X86_REG16_SI = 6, /* Registre SI */ + X86_REG16_DI = 7, /* Registre DI */ + + X86_REG16_NONE /* Aucun registre */ + +} X8616bRegister; + +/* Liste des registres 32 bits */ +typedef enum _X8632bRegister +{ + X86_REG32_EAX = 0, /* Registre EAX */ + X86_REG32_ECX = 1, /* Registre EAX */ + X86_REG32_EDX = 2, /* Registre EAX */ + X86_REG32_EBX = 3, /* Registre EAX */ + X86_REG32_ESP = 4, /* Registre ESP */ + X86_REG32_EBP = 5, /* Registre EBP */ + X86_REG32_ESI = 6, /* Registre ESI */ + X86_REG32_EDI = 7, /* Registre EDI */ + + X86_REG32_NONE /* Aucun registre */ + +} X8632bRegister; + + +/* Registre x86 */ +struct _x86_register +{ + union + { + X868bRegister reg8; /* Registre 8 bits */ + X8616bRegister reg16; /* Registre 16 bits */ + X8632bRegister reg32; /* Registre 32 bits */ + + } reg; + + AsmOperandSize size; /* Taille de ce registre */ + +}; + + + +/****************************************************************************** +* * +* Paramètres : size = indique la taille du registre. * +* value = valeur correspondant au registre. * +* * +* Description : Récupère l'indentifiant interne d'un registre. * +* * +* Retour : Registre définit ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +x86_register *get_x86_register(AsmOperandSize size, bin_t value) +{ + x86_register *result; /* Représentation à renvoyer */ + + result = (x86_register *)calloc(1, sizeof(x86_register)); + + result->size = size; + + switch (size) + { + case AOS_8_BITS: + switch (value) + { + case 0 ... 7: + result->reg.reg8 = (X868bRegister)value; + break; + default: + goto gxr_error; + break; + } + break; + + case AOS_16_BITS: + switch (value) + { + case 0 ... 7: + result->reg.reg16 = (X8616bRegister)value; + break; + default: + goto gxr_error; + break; + } + break; + + case AOS_32_BITS: + switch (value) + { + case 0 ... 7: + result->reg.reg32 = (X8632bRegister)value; + break; + default: + goto gxr_error; + break; + } + break; + + default: + goto gxr_error; + break; + + } + + return result; + + gxr_error: + + free(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre à supprimer. * +* * +* Description : Efface de la mémoire l'indentifiant interne d'un registre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void free_x86_register(x86_register *reg) +{ + free(reg); + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre à consulter. * +* * +* Description : Indique si le registre correspond à ebp ou similaire. * +* * +* Retour : true si la correspondance est avérée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool is_x86_register_base_pointer(const x86_register *reg) +{ + bool result; /* Bilan à remonter */ + + switch (reg->size) + { + case AOS_8_BITS_UNSIGNED: + case AOS_8_BITS_SIGNED: + result = (reg->reg.reg8 == X86_REG8_CH); + break; + case AOS_16_BITS_UNSIGNED: + case AOS_16_BITS_SIGNED: + result = (reg->reg.reg16 == X86_REG16_BP); + break; + case AOS_32_BITS_UNSIGNED: + case AOS_32_BITS_SIGNED: + result = (reg->reg.reg32 == X86_REG32_EBP); + break; + /* + case AOS_64_BITS_UNSIGNED: + case AOS_64_BITS_SIGNED: + result = (reg->reg.reg8 == X86_REG8_CH); + break; + */ + default: + result = false; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre à consulter. * +* * +* Description : Indique si le registre correspond à esp ou similaire. * +* * +* Retour : true si la correspondance est avérée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool is_x86_register_stack_pointer(const x86_register *reg) +{ + bool result; /* Bilan à remonter */ + + switch (reg->size) + { + case AOS_8_BITS_UNSIGNED: + case AOS_8_BITS_SIGNED: + result = (reg->reg.reg8 == X86_REG8_AH); + break; + case AOS_16_BITS_UNSIGNED: + case AOS_16_BITS_SIGNED: + result = (reg->reg.reg16 == X86_REG16_SP); + break; + case AOS_32_BITS_UNSIGNED: + case AOS_32_BITS_SIGNED: + result = (reg->reg.reg32 == X86_REG32_ESP); + break; + /* + case AOS_64_BITS_UNSIGNED: + case AOS_64_BITS_SIGNED: + result = (reg->reg.reg8 == X86_REG8_CH); + break; + */ + default: + result = false; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre à imprimer. * +* syntax = type de représentation demandée. * +* * +* Description : Traduit un registre x86 en texte. * +* * +* Retour : Traduction en chaîne à libérer de la mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax) +{ + char *result; /* Chaîne à renvoyer */ + + result = (char *)calloc(5, sizeof(char)); + + switch (syntax) + { + case ASX_INTEL: + switch (reg->size) + { + case AOS_8_BITS: + switch (reg->reg.reg8) + { + case X86_REG8_AL: + snprintf(result, 5, "al"); + break; + case X86_REG8_CL: + snprintf(result, 5, "cl"); + break; + case X86_REG8_DL: + snprintf(result, 5, "dl"); + break; + case X86_REG8_BL: + snprintf(result, 5, "bl"); + break; + case X86_REG8_AH: + snprintf(result, 5, "ah"); + break; + case X86_REG8_CH: + snprintf(result, 5, "ch"); + break; + case X86_REG8_DH: + snprintf(result, 5, "dh"); + break; + case X86_REG8_BH: + snprintf(result, 5, "bh"); + break; + case X86_REG8_NONE: + /* Ne devrait jamais arriver */ + break; + } + break; + + case AOS_16_BITS: + switch (reg->reg.reg16) + { + case X86_REG16_AX: + snprintf(result, 5, "ax"); + break; + case X86_REG16_CX: + snprintf(result, 5, "cx"); + break; + case X86_REG16_DX: + snprintf(result, 5, "dx"); + break; + case X86_REG16_BX: + snprintf(result, 5, "bx"); + break; + case X86_REG16_SP: + snprintf(result, 5, "sp"); + break; + case X86_REG16_BP: + snprintf(result, 5, "bp"); + break; + case X86_REG16_SI: + snprintf(result, 5, "si"); + break; + case X86_REG16_DI: + snprintf(result, 5, "di"); + break; + case X86_REG16_NONE: + /* Ne devrait jamais arriver */ + break; + } + break; + + case AOS_32_BITS: + switch (reg->reg.reg32) + { + case X86_REG32_EAX: + snprintf(result, 5, "eax"); + break; + case X86_REG32_ECX: + snprintf(result, 5, "ecx"); + break; + case X86_REG32_EDX: + snprintf(result, 5, "edx"); + break; + case X86_REG32_EBX: + snprintf(result, 5, "ebx"); + break; + case X86_REG32_ESP: + snprintf(result, 5, "esp"); + break; + case X86_REG32_EBP: + snprintf(result, 5, "ebp"); + break; + case X86_REG32_ESI: + snprintf(result, 5, "esi"); + break; + case X86_REG32_EDI: + snprintf(result, 5, "edi"); + break; + case X86_REG32_NONE: + printf("null reg\n"); + /* Ne devrait jamais arriver */ + break; + } + break; + + default: + break; + + } + break; + + case ASX_ATT: + switch (reg->size) + { + case AOS_8_BITS: + switch (reg->reg.reg8) + { + case X86_REG8_AL: + snprintf(result, 5, "%%al"); + break; + case X86_REG8_CL: + snprintf(result, 5, "%%cl"); + break; + case X86_REG8_DL: + snprintf(result, 5, "%%dl"); + break; + case X86_REG8_BL: + snprintf(result, 5, "%%bl"); + break; + case X86_REG8_AH: + snprintf(result, 5, "%%ah"); + break; + case X86_REG8_CH: + snprintf(result, 5, "%%ch"); + break; + case X86_REG8_DH: + snprintf(result, 5, "%%dh"); + break; + case X86_REG8_BH: + snprintf(result, 5, "%%bh"); + break; + case X86_REG8_NONE: + /* Ne devrait jamais arriver */ + break; + } + break; + + case AOS_16_BITS: + switch (reg->reg.reg16) + { + case X86_REG16_AX: + snprintf(result, 5, "%%ax"); + break; + case X86_REG16_CX: + snprintf(result, 5, "%%cx"); + break; + case X86_REG16_DX: + snprintf(result, 5, "%%dx"); + break; + case X86_REG16_BX: + snprintf(result, 5, "%%bx"); + break; + case X86_REG16_SP: + snprintf(result, 5, "%%sp"); + break; + case X86_REG16_BP: + snprintf(result, 5, "%%bp"); + break; + case X86_REG16_SI: + snprintf(result, 5, "%%si"); + break; + case X86_REG16_DI: + snprintf(result, 5, "%%di"); + break; + case X86_REG16_NONE: + /* Ne devrait jamais arriver */ + break; + } + break; + + case AOS_32_BITS: + switch (reg->reg.reg32) + { + case X86_REG32_EAX: + snprintf(result, 5, "%%eax"); + break; + case X86_REG32_ECX: + snprintf(result, 5, "%%ecx"); + break; + case X86_REG32_EDX: + snprintf(result, 5, "%%edx"); + break; + case X86_REG32_EBX: + snprintf(result, 5, "%%ebx"); + break; + case X86_REG32_ESP: + snprintf(result, 5, "%%esp"); + break; + case X86_REG32_EBP: + snprintf(result, 5, "%%ebp"); + break; + case X86_REG32_ESI: + snprintf(result, 5, "%%esi"); + break; + case X86_REG32_EDI: + snprintf(result, 5, "%%edi"); + break; + case X86_REG32_NONE: + /* Ne devrait jamais arriver */ + break; + } + break; + + default: + break; + + } + break; + + default: + break; + + } + + return result; + +} diff --git a/src/arch/x86/registers.h b/src/arch/x86/registers.h new file mode 100644 index 0000000..491d5bc --- /dev/null +++ b/src/arch/x86/registers.h @@ -0,0 +1,54 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * registers.h - prototypes pour les aides auxiliaires relatives aux registres x86 + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_X86_REGISTERS_H +#define _ARCH_X86_REGISTERS_H + + +#include "../archbase.h" +#include "../operand.h" + + + +/* Registre x86 */ +typedef struct _x86_register x86_register; + + +/* Récupère l'indentifiant interne d'un registre. */ +x86_register *get_x86_register(AsmOperandSize, bin_t); + +/* Efface de la mémoire l'indentifiant interne d'un registre. */ +void free_x86_register(x86_register *); + +/* Indique si le registre correspond à ebp ou similaire. */ +bool is_x86_register_base_pointer(const x86_register *); + +/* Indique si le registre correspond à esp ou similaire. */ +bool is_x86_register_stack_pointer(const x86_register *); + +/* Traduit un registre x86 en texte. */ +char *x86_register_as_text(const x86_register *, AsmSyntax); + + + +#endif /* _ARCH_X86_REGISTERS_H */ |