From 15387adcbd3e27fe581754c0ee56edc64272d58e Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 9 Sep 2008 22:52:57 +0000 Subject: Supported the 'moffs' type of operand. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@28 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 17 +++++++ src/arch/operand-int.h | 6 ++- src/arch/x86/instruction.h | 5 +- src/arch/x86/op_mov.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/opcodes.h | 6 +++ src/arch/x86/operand.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/operand.h | 14 ++++++ src/arch/x86/processor.c | 6 +++ 8 files changed, 288 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0725005..af808be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2008-09-10 Cyrille Bagard + + * src/arch/operand-int.h: + Add a new type of operand for the addresses on the data segment (X86). + + * src/arch/x86/instruction.h: + * src/arch/x86/opcodes.h: + Handle two more opcodes (mov: 0xa0 and 0xa1). + + * src/arch/x86/operand.c: + * src/arch/x86/operand.h: + Support the 'moffs' type of operand. + + * src/arch/x86/op_mov.c: + * src/arch/x86/processor.c: + Handle two more opcodes (mov: 0xa0 and 0xa1). + 2008-09-09 Cyrille Bagard * src/arch/x86/instruction.h: diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h index 92fc9bf..db63a9c 100644 --- a/src/arch/operand-int.h +++ b/src/arch/operand-int.h @@ -35,7 +35,11 @@ typedef enum _AsmOperandType AOT_NONE, /* Type d'opérande inconnu ! */ AOT_IMM, /* Valeur immédiate */ AOT_REG, /* Registre quelconque */ - AOT_MEM /* Accès à la mémoire */ + AOT_MEM, /* Accès à la mémoire */ + + /* X86 */ + + AOT_MOFFS /* Emplacement mémoire */ } AsmOperandType; diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index 38315d9..af4f7cf 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -97,7 +97,10 @@ typedef enum _X86Opcodes X86_OP_NOP, /* nop (0x90) */ - X86_OP_TEST_AL, /* test ([0x66] 0xa8) */ + X86_OP_MOV_MOFFS_TO_AL, /* mov (0xa0) */ + X86_OP_MOV_MOFFS_TO_E_AX, /* mov ([0x66] 0xa1) */ + + X86_OP_TEST_AL, /* test (0xa8) */ X86_OP_TEST_E_AX, /* test ([0x66] 0xa9) */ X86_OP_MOV_E_AX, /* mov ([0x66] 0xb8) */ diff --git a/src/arch/x86/op_mov.c b/src/arch/x86/op_mov.c index d0a1bfc..388d67e 100644 --- a/src/arch/x86/op_mov.c +++ b/src/arch/x86/op_mov.c @@ -38,6 +38,124 @@ * offset = adresse virtuelle de l'instruction. * * proc = architecture ciblée par le désassemblage. * * * +* Description : Décode une instruction de type 'mov al, ...' (8 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *read_instr_mov_moffs8_to_al(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + asm_x86_operand *reg; /* Registre de destination */ + asm_x86_operand *value; /* Valeur portée */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + reg = x86_create_r8_operand(0x00, true); + if (reg == NULL) + { + free(result); + return NULL; + } + + value = x86_create_moffs8_operand(data, pos, len); + if (value == NULL) + { + free(reg); + free(result); + return NULL; + } + + ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); + ASM_INSTRUCTION(result)->operands_count = 2; + + ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); + ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * +* Description : Décode une instruction de type 'mov [e]ax, ...' (16/32 bits).* +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *read_instr_mov_moffs1632_to_e_ax(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc) +{ + asm_x86_instr *result; /* Instruction à retourner */ + AsmOperandSize oprsize; /* Taille des opérandes */ + asm_x86_operand *reg; /* Registre de destination */ + asm_x86_operand *value; /* Valeur portée */ + + result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); + + /* Utilisation des registres 32 bits ? */ + if (data[*pos] == 0x66) + { + oprsize = switch_x86_operand_size(proc); + (*pos)++; + } + else oprsize = get_x86_current_operand_size(proc); + + ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; + + reg = x86_create_r1632_operand(0x00, oprsize == AOS_32_BITS, true); + if (reg == NULL) + { + free(result); + return NULL; + } + + value = x86_create_moffs1632_operand(data, pos, len, oprsize == AOS_32_BITS); + if (value == NULL) + { + free(reg); + free(result); + return NULL; + } + + ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); + ASM_INSTRUCTION(result)->operands_count = 2; + + ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); + ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + + return result; + +} + + + + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* offset = adresse virtuelle de l'instruction. * +* proc = architecture ciblée par le désassemblage. * +* * * Description : Décode une instruction de type 'mov' (16 ou 32 bits). * * * * Retour : Instruction mise en place ou NULL. * diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h index 64614dc..09fed4e 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -64,6 +64,12 @@ asm_x86_instr *read_instr_lea(const uint8_t *, off_t *, off_t, uint64_t, const a /* Décode une instruction de type 'leave'. */ asm_x86_instr *read_instr_leave(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); +/* Décode une instruction de type 'mov al, ...' (8 bits). */ +asm_x86_instr *read_instr_mov_moffs8_to_al(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + +/* Décode une instruction de type 'mov [e]ax, ...' (16/32 bits). */ +asm_x86_instr *read_instr_mov_moffs1632_to_e_ax(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *); + /* Décode une instruction de type 'mov' (16 ou 32 bits). */ asm_x86_instr *read_instr_mov_from_content_1632(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 a232211..281c139 100644 --- a/src/arch/x86/operand.c +++ b/src/arch/x86/operand.c @@ -1070,3 +1070,121 @@ void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t } } + + + + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERANDES D'EMPLACEMENTS MEMOIRE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* * +* Description : Crée une opérande à partir d'un emplacement mémoire 8 bits. * +* * +* Retour : Opérande mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_operand *x86_create_moffs8_operand(const uint8_t *data, off_t *pos, off_t len) +{ + asm_x86_operand *result; /* Emplacement à retourner */ + + result = create_new_x86_operand(); + + if (!fill_imm_operand(ASM_OPERAND(result), AOS_8_BITS, data, pos, len)) + { + free(result); + return NULL; + } + + ASM_OPERAND(result)->type = AOT_MOFFS; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* is_reg32 = indique si le registre est un registre 32 bits. * +* * +* Description : Crée une opérande à partir d'un emplacement mémoire 16/32b. * +* * +* Retour : Opérande mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_operand *x86_create_moffs1632_operand(const uint8_t *data, off_t *pos, off_t len, bool is_reg32) +{ + asm_x86_operand *result; /* Emplacement à retourner */ + + result = create_new_x86_operand(); + + if (!fill_imm_operand(ASM_OPERAND(result), is_reg32 ? AOS_32_BITS : AOS_16_BITS, data, pos, len)) + { + free(result); + return NULL; + } + + ASM_OPERAND(result)->type = AOT_MOFFS; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instruction à traiter. * +* buffer = tampon de sortie mis à disposition. [OUT] * +* len = taille de ce tampon. * +* syntax = type de représentation demandée. * +* * +* Description : Traduit une opérande d'emplacement mémoire en texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void x86_print_moffs_operand(const asm_x86_operand *operand, char *buffer, size_t len, AsmSyntax syntax) +{ + size_t pos; /* Position de traitement */ + + switch (syntax) + { + case ASX_INTEL: + if (len > 3) + { + strcpy(buffer, "ds:"); + print_imm_operand(ASM_OPERAND(operand), &buffer[3], len - 3, ASX_INTEL); + } + break; + + case ASX_ATT: + print_imm_operand(ASM_OPERAND(operand), buffer, len, ASX_INTEL); + break; + + } + +} diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h index c330b8e..42e0f56 100644 --- a/src/arch/x86/operand.h +++ b/src/arch/x86/operand.h @@ -72,4 +72,18 @@ void x86_print_reg_operand(const asm_x86_operand *, char *, size_t, AsmSyntax); +/* ------------------------ OPERANDES D'EMPLACEMENTS MEMOIRE ------------------------ */ + + +/* Crée une opérande à partir d'un emplacement mémoire 8 bits. */ +asm_x86_operand *x86_create_moffs8_operand(const uint8_t *, off_t *, off_t); + +/* Crée une opérande à partir d'un emplacement mémoire 16/32b. */ +asm_x86_operand *x86_create_moffs1632_operand(const uint8_t *, off_t *, off_t, bool); + +/* Traduit une opérande d'emplacement mémoire en texte. */ +void x86_print_moffs_operand(const asm_x86_operand *, char *, size_t, AsmSyntax); + + + #endif /* _ARCH_X86_OPERAND_H */ diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 3ca14b9..4326294 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -253,6 +253,9 @@ void x86_register_instructions(asm_x86_processor *proc) register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", read_instr_nop); + register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_AL], 0x66, 0xa0, "mov", read_instr_mov_moffs8_to_al); + register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_E_AX], 0x66, 0xa1, "mov", read_instr_mov_moffs1632_to_e_ax); + register_opcode(proc->opcodes[X86_OP_TEST_AL], 0x00, 0xa8, "test", read_instr_test_al); register_opcode(proc->opcodes[X86_OP_TEST_E_AX], 0x66, 0xa9, "test", read_instr_test_e_ax); @@ -387,6 +390,9 @@ void x86_print_instruction(const asm_x86_processor *proc, const asm_x86_instr *i break; case AOT_MEM: break; + case AOT_MOFFS: + x86_print_moffs_operand(ASM_INSTRUCTION(instr)->operands[i], opbuffer[i], 64, syntax); + break; } /* Impression globale finale */ -- cgit v0.11.2-87-g4458