diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2008-07-27 19:38:15 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2008-07-27 19:38:15 (GMT) |
commit | 1bf9c5ebe8bb3326e10491974cd43b221e2a56a1 (patch) | |
tree | 01a745a798661478eb7a6e02c0a0831bb1b4950c /src/arch/x86 | |
parent | dbf4d1f93e54251568854bff0ebc9c84f60857f6 (diff) |
Supported new x86 opcodes (nop and mov).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@7 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/Makefile.am | 3 | ||||
-rw-r--r-- | src/arch/x86/instruction.h | 36 | ||||
-rw-r--r-- | src/arch/x86/op_int.c | 22 | ||||
-rw-r--r-- | src/arch/x86/op_mov.c | 89 | ||||
-rw-r--r-- | src/arch/x86/op_nop.c | 56 | ||||
-rw-r--r-- | src/arch/x86/opcodes.h | 10 | ||||
-rw-r--r-- | src/arch/x86/operand.c | 402 | ||||
-rw-r--r-- | src/arch/x86/operand.h | 53 | ||||
-rw-r--r-- | src/arch/x86/processor.c | 105 |
9 files changed, 742 insertions, 34 deletions
diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am index 6fe55c8..4947118 100644 --- a/src/arch/x86/Makefile.am +++ b/src/arch/x86/Makefile.am @@ -4,7 +4,10 @@ lib_LIBRARIES = libarchx86.a libarchx86_a_SOURCES = \ instruction.h \ op_int.c \ + op_nop.c \ + op_mov.c \ opcodes.h \ + operand.h operand.c \ processor.h processor.c libarchx86_a_CFLAGS = $(AM_CFLAGS) diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h index 47617ea..c3c417b 100644 --- a/src/arch/x86/instruction.h +++ b/src/arch/x86/instruction.h @@ -38,8 +38,27 @@ typedef struct _asm_x86_instr asm_x86_instr; /* Enumération de tous les opcodes */ typedef enum _X86Opcodes { + X86_OP_NOP, /* nop (0x90) */ + + X86_OP_MOV_AX, /* mov (0xb0) */ + X86_OP_MOV_CX, /* mov (0xb1) */ + X86_OP_MOV_DX, /* mov (0xb2) */ + X86_OP_MOV_BX, /* mov (0xb3) */ + X86_OP_MOV_SP, /* mov (0xb4) */ + X86_OP_MOV_BP, /* mov (0xb5) */ + X86_OP_MOV_SI, /* mov (0xb6) */ + X86_OP_MOV_DI, /* mov (0xb7) */ + X86_OP_INT, /* int (0xcd) */ + X86_OP_MOV_EAX, /* mov (0x66 0xb0) */ + X86_OP_MOV_ECX, /* mov (0x66 0xb1) */ + X86_OP_MOV_EDX, /* mov (0x66 0xb2) */ + X86_OP_MOV_EBX, /* mov (0x66 0xb3) */ + X86_OP_MOV_ESP, /* mov (0x66 0xb4) */ + X86_OP_MOV_EBP, /* mov (0x66 0xb5) */ + X86_OP_MOV_ESI, /* mov (0x66 0xb6) */ + X86_OP_MOV_EDI, /* mov (0x66 0xb7) */ X86_OP_COUNT @@ -48,6 +67,19 @@ typedef enum _X86Opcodes +/* Eventuel préfixe rencontré */ +typedef enum _X86Prefix +{ + X86_PRE_NONE = 0, /* Aucun préfixe */ + + + X86_PRE_OPSIZE /* Basculement des opérandes */ + + +} X86Prefix; + + + /* Définition d'une instruction x86 */ struct _asm_x86_instr { @@ -55,6 +87,10 @@ struct _asm_x86_instr X86Opcodes type; + + X86Prefix prefix; /* Eventuel préfixe trouvé */ + + }; diff --git a/src/arch/x86/op_int.c b/src/arch/x86/op_int.c index e7805e1..3c621d6 100644 --- a/src/arch/x86/op_int.c +++ b/src/arch/x86/op_int.c @@ -24,9 +24,9 @@ #include <malloc.h> -#include "instruction.h" #include "../instruction-int.h" - +#include "opcodes.h" +#include "operand.h" @@ -44,20 +44,28 @@ * * ******************************************************************************/ -asm_x86_instr *read_instr_int(const char *data, off_t *pos, off_t len) +asm_x86_instr *read_instr_int(const uint8_t *data, off_t *pos, off_t len) { - asm_x86_instr *result; + asm_x86_instr *result; /* Instruction à retourner */ + asm_x86_operand *syscall; /* Indice de l'appel système */ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr)); ASM_INSTRUCTION(result)->opcode = data[(*pos)++]; - /* TODO: check result */ - fill_db_operand(&ASM_INSTRUCTION(result)->operands[0], data[(*pos)++]); + syscall = create_new_x86_operand(); + if (!fill_imm_operand(ASM_OPERAND(syscall), AOS_8_BITS, data, pos, len)) + { + free(syscall); + free(result); + return NULL; + } + ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(1, sizeof(asm_operand *)); ASM_INSTRUCTION(result)->operands_count = 1; + ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(syscall); + return result; } - diff --git a/src/arch/x86/op_mov.c b/src/arch/x86/op_mov.c new file mode 100644 index 0000000..22cb828 --- /dev/null +++ b/src/arch/x86/op_mov.c @@ -0,0 +1,89 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_mov.c - décodage des déplacements de données + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" +#include "operand.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* * +* Description : Décode une instruction de type 'mov' (16 ou 32 bits). * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *read_instr_mov_to_1632(const uint8_t *data, off_t *pos, off_t len) +{ + asm_x86_instr *result; /* Instruction à retourner */ + bool is_reg32; /* Implique un registre 32 bits*/ + 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 ? */ + is_reg32 = (data[*pos] == 0x66); + if (is_reg32) + { + (*pos)++; + } + + ASM_INSTRUCTION(result)->opcode = data[*pos]; + + reg = x86_create_reg1632_operand(data[(*pos)++], is_reg32); + if (reg == NULL) + { + free(result); + return NULL; + } + + value = create_new_x86_operand(); + if (!fill_imm_operand(ASM_OPERAND(value), is_reg32 ? AOS_32_BITS : AOS_16_BITS, data, pos, len)) + { + free(reg); + free(value); + free(result); + return NULL; + } + + ASM_INSTRUCTION(result)->operands = (asm_operand **)calloc(2, sizeof(asm_operand *)); + ASM_INSTRUCTION(result)->operands_count = 2; + + ASM_INSTRUCTION(result)->operands[0] = ASM_OPERAND(reg); + ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(value); + + return result; + +} diff --git a/src/arch/x86/op_nop.c b/src/arch/x86/op_nop.c new file mode 100644 index 0000000..c23b5f1 --- /dev/null +++ b/src/arch/x86/op_nop.c @@ -0,0 +1,56 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * op_nop.c - décodage des instructions nulles + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <malloc.h> + + +#include "../instruction-int.h" +#include "opcodes.h" + + + +/****************************************************************************** +* * +* Paramètres : data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* * +* Description : Décode une instruction de type 'nop'. * +* * +* Retour : Instruction mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_instr *read_instr_nop(const uint8_t *data, off_t *pos, off_t len) +{ + 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/opcodes.h b/src/arch/x86/opcodes.h index 17316e7..d6be6a1 100644 --- a/src/arch/x86/opcodes.h +++ b/src/arch/x86/opcodes.h @@ -28,12 +28,18 @@ #include <sys/types.h> -#include "../instruction.h" +#include "instruction.h" /* Décode une instruction de type 'int'. */ -asm_x86_instr *read_instr_int(const char *, off_t *, off_t); +asm_x86_instr *read_instr_int(const uint8_t *, off_t *, off_t); + +/* Décode une instruction de type 'mov' (16 ou 32 bits). */ +asm_x86_instr *read_instr_mov_to_1632(const uint8_t *, off_t *, off_t); + +/* Décode une instruction de type 'nop'. */ +asm_x86_instr *read_instr_nop(const uint8_t *, off_t *, off_t); diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c new file mode 100644 index 0000000..84d4038 --- /dev/null +++ b/src/arch/x86/operand.c @@ -0,0 +1,402 @@ +/* OpenIDA - Outil d'analyse de fichiers binaires + * operand.c - gestion des operandes de l'architecture x86 + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "operand.h" + + +#include <malloc.h> +#include <stdio.h> + + +#include "../operand.h" +#include "../operand-int.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 */ + +} 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 */ + +} 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 */ + +} X8632bRegister; + + + + + +/* Définition d'une opérande x86 */ +struct _asm_x86_operand +{ + asm_operand base; /* A laisser en premier */ + + union + { + X868bRegister reg8; /* Registre 8 bits */ + X8616bRegister reg16; /* Registre 16 bits */ + X8632bRegister reg32; /* Registre 32 bits */ + + } x86_value; + +}; + + + +#define NULL ((void *)0) + + + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une opérande vierge pour x86. * +* * +* Retour : Opérande nouvellement créée. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_operand *create_new_x86_operand(void) +{ + return (asm_x86_operand *)calloc(1, sizeof(asm_x86_operand)); + +} + + + + + + + +/****************************************************************************** +* * +* Paramètres : data = donnée à analyser. * +* is_reg32 = indique si le registre est un registre 32 bits. * +* * +* Description : Crée une opérande renvoyant vers un registre 16 ou 32 bits. * +* * +* Retour : Opérande mise en place ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +asm_x86_operand *x86_create_reg1632_operand(uint8_t data, bool is_reg32) +{ + asm_x86_operand *result; /* Registre à retourner */ + X8616bRegister reg16; /* Registre 16 bits */ + X8632bRegister reg32; /* Registre 32 bits */ + + if (is_reg32) + switch (data - 0xb8) + { + case 0 ... 7: + reg32 = (X8632bRegister)(data - 0xb8); + break; + default: + return NULL; + break; + } + + else + switch (data - 0xb0) + { + case 0 ... 7: + reg16 = (X8616bRegister)(data - 0xb0); + break; + default: + return NULL; + break; + } + + result = create_new_x86_operand(); + + ASM_OPERAND(result)->type = AOT_REG; + ASM_OPERAND(result)->size = (is_reg32 ? AOS_32_BITS : AOS_16_BITS); + + if (is_reg32) result->x86_value.reg32 = reg32; + else result->x86_value.reg16 = reg16; + + 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 de registre en texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t len, AsmSyntax syntax) +{ + switch (syntax) + { + case ASX_INTEL: + switch (ASM_OPERAND(operand)->size) + { + case AOS_8_BITS: + switch (operand->x86_value.reg8) + { + case X86_REG8_AL: + snprintf(buffer, len, "al"); + break; + case X86_REG8_CL: + snprintf(buffer, len, "cl"); + break; + case X86_REG8_DL: + snprintf(buffer, len, "dl"); + break; + case X86_REG8_BL: + snprintf(buffer, len, "bl"); + break; + case X86_REG8_AH: + snprintf(buffer, len, "ah"); + break; + case X86_REG8_CH: + snprintf(buffer, len, "ch"); + break; + case X86_REG8_DH: + snprintf(buffer, len, "dh"); + break; + case X86_REG8_BH: + snprintf(buffer, len, "bh"); + break; + } + break; + + case AOS_16_BITS: + switch (operand->x86_value.reg16) + { + case X86_REG16_AX: + snprintf(buffer, len, "ax"); + break; + case X86_REG16_CX: + snprintf(buffer, len, "cx"); + break; + case X86_REG16_DX: + snprintf(buffer, len, "dx"); + break; + case X86_REG16_BX: + snprintf(buffer, len, "bx"); + break; + case X86_REG16_SP: + snprintf(buffer, len, "sp"); + break; + case X86_REG16_BP: + snprintf(buffer, len, "bp"); + break; + case X86_REG16_SI: + snprintf(buffer, len, "si"); + break; + case X86_REG16_DI: + snprintf(buffer, len, "di"); + break; + } + break; + + case AOS_32_BITS: + switch (operand->x86_value.reg32) + { + case X86_REG32_EAX: + snprintf(buffer, len, "eax"); + break; + case X86_REG32_ECX: + snprintf(buffer, len, "ecx"); + break; + case X86_REG32_EDX: + snprintf(buffer, len, "edx"); + break; + case X86_REG32_EBX: + snprintf(buffer, len, "ebx"); + break; + case X86_REG32_ESP: + snprintf(buffer, len, "esp"); + break; + case X86_REG32_EBP: + snprintf(buffer, len, "ebp"); + break; + case X86_REG32_ESI: + snprintf(buffer, len, "esi"); + break; + case X86_REG32_EDI: + snprintf(buffer, len, "edi"); + break; + } + break; + + case AOS_64_BITS: + break; + + } + break; + + case ASX_ATT: + switch (ASM_OPERAND(operand)->size) + { + case AOS_8_BITS: + switch (operand->x86_value.reg8) + { + case X86_REG8_AL: + snprintf(buffer, len, "%%al"); + break; + case X86_REG8_CL: + snprintf(buffer, len, "%%cl"); + break; + case X86_REG8_DL: + snprintf(buffer, len, "%%dl"); + break; + case X86_REG8_BL: + snprintf(buffer, len, "%%bl"); + break; + case X86_REG8_AH: + snprintf(buffer, len, "%%ah"); + break; + case X86_REG8_CH: + snprintf(buffer, len, "%%ch"); + break; + case X86_REG8_DH: + snprintf(buffer, len, "%%dh"); + break; + case X86_REG8_BH: + snprintf(buffer, len, "%%bh"); + break; + } + break; + + case AOS_16_BITS: + switch (operand->x86_value.reg16) + { + case X86_REG16_AX: + snprintf(buffer, len, "%%ax"); + break; + case X86_REG16_CX: + snprintf(buffer, len, "%%cx"); + break; + case X86_REG16_DX: + snprintf(buffer, len, "%%dx"); + break; + case X86_REG16_BX: + snprintf(buffer, len, "%%bx"); + break; + case X86_REG16_SP: + snprintf(buffer, len, "%%sp"); + break; + case X86_REG16_BP: + snprintf(buffer, len, "%%bp"); + break; + case X86_REG16_SI: + snprintf(buffer, len, "%%si"); + break; + case X86_REG16_DI: + snprintf(buffer, len, "%%di"); + break; + } + break; + + case AOS_32_BITS: + switch (operand->x86_value.reg32) + { + case X86_REG32_EAX: + snprintf(buffer, len, "%%eax"); + break; + case X86_REG32_ECX: + snprintf(buffer, len, "%%ecx"); + break; + case X86_REG32_EDX: + snprintf(buffer, len, "%%edx"); + break; + case X86_REG32_EBX: + snprintf(buffer, len, "%%ebx"); + break; + case X86_REG32_ESP: + snprintf(buffer, len, "%%esp"); + break; + case X86_REG32_EBP: + snprintf(buffer, len, "%%ebp"); + break; + case X86_REG32_ESI: + snprintf(buffer, len, "%%esi"); + break; + case X86_REG32_EDI: + snprintf(buffer, len, "%%edi"); + break; + } + break; + + case AOS_64_BITS: + break; + + } + break; + + } + +} diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h new file mode 100644 index 0000000..0773333 --- /dev/null +++ b/src/arch/x86/operand.h @@ -0,0 +1,53 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * operand.h - prototypes pour la gestion des operandes de l'architecture x86 + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_X86_OPERAND_H +#define _ARCH_X86_OPERAND_H + + +#include <stdbool.h> +#include <stdint.h> + + +#include "../operand.h" /* TODO : AsmSyntax ? */ + + +/* Définition d'une opérande x86 */ +typedef struct _asm_x86_operand asm_x86_operand; + + + +/* Crée une opérande vierge pour x86. */ +asm_x86_operand *create_new_x86_operand(void); + + + +/* Crée une opérande renvoyant vers un registre 16 ou 32 bits. */ +asm_x86_operand *x86_create_reg1632_operand(uint8_t, bool); + +/*Traduit une opérande de registre en texte. */ +void x86_print_reg_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 4ef1377..895c8b1 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -24,30 +24,34 @@ #include "processor.h" +#include <malloc.h> +#include <stdio.h> + + #include "../processor-int.h" #include "instruction.h" #include "opcodes.h" - - -#include <malloc.h> +#include "operand.h" -typedef asm_x86_instr * (* read_instr) (const char *, off_t *, off_t); +typedef asm_x86_instr * (* read_instr) (const uint8_t *, off_t *, off_t); /* Carte d'identité d'un opcode */ typedef struct _x86_opcode { - char opcode; /* Opcode + préfixe eventuel */ + uint8_t prefix; /* préfixe eventuel */ + uint8_t opcode; /* Opcode seul */ const char *name; /* Désignation humaine */ read_instr read; /* Décodage de l'instruction */ } x86_opcode; -#define register_opcode(target, bin, n, func) \ +#define register_opcode(target, pre, bin, n, func) \ do {\ +target.prefix = pre; \ target.opcode = bin; \ target.name = n; \ target.read = func; \ @@ -72,7 +76,7 @@ void x86_register_instructions(asm_x86_processor *); /* Décode une instruction dans un flux de données. */ -asm_instr *x86_fetch_instruction(const asm_x86_processor *, const char *, off_t *, off_t); +asm_instr *x86_fetch_instruction(const asm_x86_processor *, const uint8_t *, off_t *, off_t); /* Traduit une instruction en version humainement lisible. */ void x86_print_instruction(const asm_x86_processor *, const asm_x86_instr *, char *, size_t, AsmSyntax); @@ -129,11 +133,32 @@ void x86_register_instructions(asm_x86_processor *proc) - register_opcode(proc->opcodes[X86_OP_INT], 0xcd, "int", read_instr_int); + register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", read_instr_nop); + register_opcode(proc->opcodes[X86_OP_MOV_AX], 0x00, 0xb8, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_DX], 0x00, 0xb9, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_DX], 0x00, 0xba, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_BX], 0x00, 0xbb, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_SP], 0x00, 0xbc, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_BP], 0x00, 0xbd, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_SI], 0x00, 0xbe, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_DI], 0x00, 0xbf, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_INT], 0x00, 0xcd, "int", read_instr_int); + + + + register_opcode(proc->opcodes[X86_OP_MOV_EAX], 0x66, 0xb8, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_ECX], 0x66, 0xb9, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_EDX], 0x66, 0xba, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_EBX], 0x66, 0xbb, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_ESP], 0x66, 0xbc, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_EBP], 0x66, 0xbd, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_ESI], 0x66, 0xbe, "mov", read_instr_mov_to_1632); + register_opcode(proc->opcodes[X86_OP_MOV_EDI], 0x66, 0xbf, "mov", read_instr_mov_to_1632); + } @@ -155,25 +180,17 @@ void x86_register_instructions(asm_x86_processor *proc) * * ******************************************************************************/ -asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const char *data, off_t *pos, off_t len) +asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *data, off_t *pos, off_t len) { asm_x86_instr *result; /* Résultat à faire remonter */ X86Opcodes i; /* Boucle de parcours */ result = NULL; - //printf("--------\n"); - for (i = 0; i < X86_OP_COUNT; i++) { - - /* - printf(" cmp :: 0x%02hhx vs 0x%02hhx ? %d\n", - data[*pos], proc->opcodes[i].opcode, - data[*pos] == proc->opcodes[i].opcode); - */ - - if (data[*pos] == proc->opcodes[i].opcode) + if ((proc->opcodes[i].prefix > 0 && data[*pos] == proc->opcodes[i].prefix && data[*pos + 1] == proc->opcodes[i].opcode) + || (proc->opcodes[i].prefix == 0 && data[*pos] == proc->opcodes[i].opcode)) { result = proc->opcodes[i].read(data, pos, len); if (result != NULL) result->type = i; @@ -182,7 +199,6 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const char *data } - return ASM_INSTRUCTION(result); } @@ -206,17 +222,56 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const char *data void x86_print_instruction(const asm_x86_processor *proc, const asm_x86_instr *instr, char *buffer, size_t len, AsmSyntax syntax) { + size_t i; /* Boucle de parcours */ + char opbuffer[3][64]; /* Tampon pour les textes */ - if (ASM_INSTRUCTION(instr)->opcode == DB_OPCODE) - + /* Impression des opérandes */ - snprintf(buffer, len, "db\t0x%02hhx", ASM_INSTRUCTION(instr)->operands[0].value.val8); + for (i = 0; i < ASM_INSTRUCTION(instr)->operands_count; i++) + switch (ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i])->type) + { + case AOT_NONE: + print_db_operand(ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i]), opbuffer[i], 64, syntax); + break; + case AOT_IMM: + print_imm_operand(ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i]), opbuffer[i], 64, syntax); + break; + case AOT_REG: + x86_print_reg_operand(ASM_INSTRUCTION(instr)->operands[i], opbuffer[i], 64, syntax); + break; + case AOT_MEM: + break; + } + /* Impression globale finale */ - else + if (ASM_INSTRUCTION(instr)->opcode == DB_OPCODE) + snprintf(buffer, len, "db\t%s", opbuffer[0]); - snprintf(buffer, len, "%s\t0x%02hhx", proc->opcodes[instr->type].name, ASM_INSTRUCTION(instr)->operands[0].value.val8); + else + switch (ASM_INSTRUCTION(instr)->operands_count) + { + case 0: + snprintf(buffer, len, "%s", proc->opcodes[instr->type].name); + break; + + case 1: + snprintf(buffer, len, "%s\t%s", proc->opcodes[instr->type].name, opbuffer[0]); + break; + + case 2: + switch (syntax) + { + case ASX_INTEL: + snprintf(buffer, len, "%s\t%s, %s", proc->opcodes[instr->type].name, opbuffer[0], opbuffer[1]); + break; + case ASX_ATT: + snprintf(buffer, len, "%s\t%s, %s", proc->opcodes[instr->type].name, opbuffer[1], opbuffer[0]); + break; + } + break; + } } |