summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/Makefile.am1
-rw-r--r--src/arch/x86/instruction.h6
-rw-r--r--src/arch/x86/op_call.c83
-rw-r--r--src/arch/x86/op_dec.c19
-rw-r--r--src/arch/x86/op_hlt.c10
-rw-r--r--src/arch/x86/op_inc.c19
-rw-r--r--src/arch/x86/op_int.c10
-rw-r--r--src/arch/x86/op_mov.c21
-rw-r--r--src/arch/x86/op_nop.c10
-rw-r--r--src/arch/x86/op_pop.c19
-rw-r--r--src/arch/x86/op_push.c72
-rw-r--r--src/arch/x86/opcodes.h24
-rw-r--r--src/arch/x86/processor.c138
-rw-r--r--src/arch/x86/processor.h8
14 files changed, 333 insertions, 107 deletions
diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am
index c610592..da03534 100644
--- a/src/arch/x86/Makefile.am
+++ b/src/arch/x86/Makefile.am
@@ -3,6 +3,7 @@ lib_LIBRARIES = libarchx86.a
libarchx86_a_SOURCES = \
instruction.h \
+ op_call.c \
op_dec.c \
op_hlt.c \
op_inc.c \
diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h
index 83f8cf0..d88e971 100644
--- a/src/arch/x86/instruction.h
+++ b/src/arch/x86/instruction.h
@@ -74,6 +74,8 @@ typedef enum _X86Opcodes
X86_OP_POP_ESI, /* pop (0x5e) */
X86_OP_POP_EDI, /* pop (0x5f) */
+ X86_OP_PUSH_IMM32, /* push (0x68) */
+
X86_OP_NOP, /* nop (0x90) */
X86_OP_MOV_AX, /* mov (0xb8) */
@@ -87,6 +89,8 @@ typedef enum _X86Opcodes
X86_OP_INT, /* int (0xcd) */
+ X86_OP_CALL, /* call (0xe8) */
+
X86_OP_HLT, /* hlt (0xf4) */
X86_OP_INC_AX, /* inc (0x66 0x40) */
@@ -125,6 +129,8 @@ typedef enum _X86Opcodes
X86_OP_POP_SI, /* pop (0x66 0x5e) */
X86_OP_POP_DI, /* pop (0x66 0x5f) */
+ X86_OP_PUSH_IMM16, /* push (0x66 0x68) */
+
X86_OP_MOV_EAX, /* mov (0x66 0xb8) */
X86_OP_MOV_ECX, /* mov (0x66 0xb9) */
X86_OP_MOV_EDX, /* mov (0x66 0xba) */
diff --git a/src/arch/x86/op_call.c b/src/arch/x86/op_call.c
new file mode 100644
index 0000000..61d9874
--- /dev/null
+++ b/src/arch/x86/op_call.c
@@ -0,0 +1,83 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_call.c - décodage des appels
+ *
+ * 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. *
+* offset = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'call' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *read_instr_call(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 *value; /* Valeur empilé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)++;
+ offset++;
+ }
+ else oprsize = get_x86_current_operand_size(proc);
+
+ ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+
+ value = create_new_x86_operand();
+ if (!fill_relimm_operand(ASM_OPERAND(value), oprsize, data, pos, len, ++offset))
+ {
+ free(value);
+ 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(value);
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_dec.c b/src/arch/x86/op_dec.c
index 9bdbf74..e6add37 100644
--- a/src/arch/x86/op_dec.c
+++ b/src/arch/x86/op_dec.c
@@ -32,9 +32,11 @@
/******************************************************************************
* *
-* Paramètres : data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
+* 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 'inc' (16 ou 32 bits). *
* *
@@ -44,24 +46,25 @@
* *
******************************************************************************/
-asm_x86_instr *read_instr_dec_1632(const uint8_t *data, off_t *pos, off_t len)
+asm_x86_instr *read_instr_dec_1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
{
asm_x86_instr *result; /* Instruction à retourner */
- bool is_reg32; /* Implique un registre 32 bits*/
+ AsmOperandSize oprsize; /* Taille des opérandes */
asm_x86_operand *reg; /* Registre de destination */
result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
/* Utilisation des registres 32 bits ? */
- is_reg32 = (data[*pos] != 0x66);
- if (!is_reg32)
+ 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_reg1632_operand(data[(*pos)++], is_reg32, 0x48);
+ reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0x48);
if (reg == NULL)
{
free(result);
diff --git a/src/arch/x86/op_hlt.c b/src/arch/x86/op_hlt.c
index ddb5882..9443e7d 100644
--- a/src/arch/x86/op_hlt.c
+++ b/src/arch/x86/op_hlt.c
@@ -31,9 +31,11 @@
/******************************************************************************
* *
-* Paramètres : data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
+* 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 'hlt'. *
* *
@@ -43,7 +45,7 @@
* *
******************************************************************************/
-asm_x86_instr *read_instr_hlt(const uint8_t *data, off_t *pos, off_t len)
+asm_x86_instr *read_instr_hlt(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
{
asm_x86_instr *result;
diff --git a/src/arch/x86/op_inc.c b/src/arch/x86/op_inc.c
index dd21471..aa05d04 100644
--- a/src/arch/x86/op_inc.c
+++ b/src/arch/x86/op_inc.c
@@ -32,9 +32,11 @@
/******************************************************************************
* *
-* Paramètres : data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
+* 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 'inc' (16 ou 32 bits). *
* *
@@ -44,24 +46,25 @@
* *
******************************************************************************/
-asm_x86_instr *read_instr_inc_1632(const uint8_t *data, off_t *pos, off_t len)
+asm_x86_instr *read_instr_inc_1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
{
asm_x86_instr *result; /* Instruction à retourner */
- bool is_reg32; /* Implique un registre 32 bits*/
+ AsmOperandSize oprsize; /* Taille des opérandes */
asm_x86_operand *reg; /* Registre de destination */
result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
/* Utilisation des registres 32 bits ? */
- is_reg32 = (data[*pos] != 0x66);
- if (!is_reg32)
+ 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_reg1632_operand(data[(*pos)++], is_reg32, 0x40);
+ reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0x40);
if (reg == NULL)
{
free(result);
diff --git a/src/arch/x86/op_int.c b/src/arch/x86/op_int.c
index 3c621d6..69e49ff 100644
--- a/src/arch/x86/op_int.c
+++ b/src/arch/x86/op_int.c
@@ -32,9 +32,11 @@
/******************************************************************************
* *
-* Paramètres : data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
+* 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 'int'. *
* *
@@ -44,7 +46,7 @@
* *
******************************************************************************/
-asm_x86_instr *read_instr_int(const uint8_t *data, off_t *pos, off_t len)
+asm_x86_instr *read_instr_int(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
{
asm_x86_instr *result; /* Instruction à retourner */
asm_x86_operand *syscall; /* Indice de l'appel système */
diff --git a/src/arch/x86/op_mov.c b/src/arch/x86/op_mov.c
index 2ce8464..e14a2f7 100644
--- a/src/arch/x86/op_mov.c
+++ b/src/arch/x86/op_mov.c
@@ -32,9 +32,11 @@
/******************************************************************************
* *
-* Paramètres : data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
+* 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). *
* *
@@ -44,25 +46,26 @@
* *
******************************************************************************/
-asm_x86_instr *read_instr_mov_to_1632(const uint8_t *data, off_t *pos, off_t len)
+asm_x86_instr *read_instr_mov_to_1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
{
asm_x86_instr *result; /* Instruction à retourner */
- bool is_reg32; /* Implique un registre 32 bits*/
+ 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 ? */
- is_reg32 = (data[*pos] == 0x66);
- if (is_reg32)
+ 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_reg1632_operand(data[(*pos)++], is_reg32, 0xb8);
+ reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0xb8);
if (reg == NULL)
{
free(result);
@@ -70,7 +73,7 @@ asm_x86_instr *read_instr_mov_to_1632(const uint8_t *data, off_t *pos, off_t len
}
value = create_new_x86_operand();
- if (!fill_imm_operand(ASM_OPERAND(value), is_reg32 ? AOS_32_BITS : AOS_16_BITS, data, pos, len))
+ if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len))
{
free(reg);
free(value);
diff --git a/src/arch/x86/op_nop.c b/src/arch/x86/op_nop.c
index 0062186..438e034 100644
--- a/src/arch/x86/op_nop.c
+++ b/src/arch/x86/op_nop.c
@@ -31,9 +31,11 @@
/******************************************************************************
* *
-* Paramètres : data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
+* 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 'nop'. *
* *
@@ -43,7 +45,7 @@
* *
******************************************************************************/
-asm_x86_instr *read_instr_nop(const uint8_t *data, off_t *pos, off_t len)
+asm_x86_instr *read_instr_nop(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
{
asm_x86_instr *result;
diff --git a/src/arch/x86/op_pop.c b/src/arch/x86/op_pop.c
index 3e725eb..4d7f520 100644
--- a/src/arch/x86/op_pop.c
+++ b/src/arch/x86/op_pop.c
@@ -32,9 +32,11 @@
/******************************************************************************
* *
-* Paramètres : data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
+* 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 'pop' (16 ou 32 bits). *
* *
@@ -44,24 +46,25 @@
* *
******************************************************************************/
-asm_x86_instr *read_instr_pop_1632(const uint8_t *data, off_t *pos, off_t len)
+asm_x86_instr *read_instr_pop_reg1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
{
asm_x86_instr *result; /* Instruction à retourner */
- bool is_reg32; /* Implique un registre 32 bits*/
+ AsmOperandSize oprsize; /* Taille des opérandes */
asm_x86_operand *reg; /* Registre de destination */
result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
/* Utilisation des registres 32 bits ? */
- is_reg32 = (data[*pos] != 0x66);
- if (!is_reg32)
+ 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_reg1632_operand(data[(*pos)++], is_reg32, 0x58);
+ reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0x58);
if (reg == NULL)
{
free(result);
diff --git a/src/arch/x86/op_push.c b/src/arch/x86/op_push.c
index ac5319d..0edd9bc 100644
--- a/src/arch/x86/op_push.c
+++ b/src/arch/x86/op_push.c
@@ -27,14 +27,17 @@
#include "../instruction-int.h"
#include "opcodes.h"
#include "operand.h"
+#include "processor.h"
/******************************************************************************
* *
-* Paramètres : data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
+* 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 'push' (16 ou 32 bits). *
* *
@@ -44,24 +47,77 @@
* *
******************************************************************************/
-asm_x86_instr *read_instr_push_1632(const uint8_t *data, off_t *pos, off_t len)
+asm_x86_instr *read_instr_push_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
{
asm_x86_instr *result; /* Instruction à retourner */
- bool is_reg32; /* Implique un registre 32 bits*/
+ AsmOperandSize oprsize; /* Taille des opérandes */
+ asm_x86_operand *value; /* Valeur empilé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)++];
+
+ value = create_new_x86_operand();
+ if (!fill_imm_operand(ASM_OPERAND(value), oprsize, data, pos, len))
+ {
+ free(value);
+ 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(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 'push' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *read_instr_push_reg1632(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 */
result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
/* Utilisation des registres 32 bits ? */
- is_reg32 = (data[*pos] != 0x66);
- if (!is_reg32)
+ 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_reg1632_operand(data[(*pos)++], is_reg32, 0x50);
+ reg = x86_create_reg1632_operand(data[(*pos)++], oprsize == AOS_32_BITS, 0x50);
if (reg == NULL)
{
free(result);
diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h
index f847b48..3efefaf 100644
--- a/src/arch/x86/opcodes.h
+++ b/src/arch/x86/opcodes.h
@@ -25,36 +25,44 @@
#define _ARCH_X86_OPCODES_H
+#include <stdint.h>
#include <sys/types.h>
+#include "processor.h"
#include "instruction.h"
+/* Décode une instruction de type 'call'. */
+asm_x86_instr *read_instr_call(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'dec'. */
-asm_x86_instr *read_instr_dec_1632(const uint8_t *, off_t *, off_t);
+asm_x86_instr *read_instr_dec_1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'hlt'. */
-asm_x86_instr *read_instr_hlt(const uint8_t *, off_t *, off_t);
+asm_x86_instr *read_instr_hlt(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'inc'. */
-asm_x86_instr *read_instr_inc_1632(const uint8_t *, off_t *, off_t);
+asm_x86_instr *read_instr_inc_1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'int'. */
-asm_x86_instr *read_instr_int(const uint8_t *, off_t *, off_t);
+asm_x86_instr *read_instr_int(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_to_1632(const uint8_t *, off_t *, off_t);
+asm_x86_instr *read_instr_mov_to_1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'nop'. */
-asm_x86_instr *read_instr_nop(const uint8_t *, off_t *, off_t);
+asm_x86_instr *read_instr_nop(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'pop' (16 ou 32 bits). */
-asm_x86_instr *read_instr_pop_1632(const uint8_t *, off_t *, off_t);
+asm_x86_instr *read_instr_pop_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'push' (16 ou 32 bits). */
+asm_x86_instr *read_instr_push_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'push' (16 ou 32 bits). */
-asm_x86_instr *read_instr_push_1632(const uint8_t *, off_t *, off_t);
+asm_x86_instr *read_instr_push_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c
index 9c7f2bd..94f2a51 100644
--- a/src/arch/x86/processor.c
+++ b/src/arch/x86/processor.c
@@ -35,7 +35,7 @@
-typedef asm_x86_instr * (* read_instr) (const uint8_t *, off_t *, off_t);
+typedef asm_x86_instr * (* read_instr) (const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Carte d'identité d'un opcode */
@@ -59,13 +59,15 @@ target.read = func; \
/* Définition générique d'une architecture */
-typedef struct _asm_x86_processor
+struct _asm_x86_processor
{
asm_processor base; /* A laisser en premier... */
+ AsmOperandSize operand_size; /* Taille par défaut */
+
x86_opcode opcodes[X86_OP_COUNT]; /* Liste des opcodes supportés */
-} asm_x86_processor;
+};
@@ -76,7 +78,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 uint8_t *, off_t *, off_t);
+asm_instr *x86_fetch_instruction(const asm_x86_processor *, const uint8_t *, off_t *, off_t, uint64_t);
/* Traduit une instruction en version humainement lisible. */
void x86_print_instruction(const asm_x86_processor *, const asm_x86_instr *, char *, size_t, AsmSyntax);
@@ -103,17 +105,54 @@ asm_processor *create_x86_processor(void)
result = (asm_x86_processor *)calloc(1, sizeof(asm_x86_processor));
+ result->operand_size = AOS_32_BITS;
+
x86_register_instructions(result);
- ASM_PROCESSOR(result)->fetch_instr = x86_fetch_instruction;
- ASM_PROCESSOR(result)->print_instr = x86_print_instruction;
+ ASM_PROCESSOR(result)->fetch_instr = (fetch_instruction)x86_fetch_instruction;
+ ASM_PROCESSOR(result)->print_instr = (print_instruction)x86_print_instruction;
return ASM_PROCESSOR(result);
}
+/******************************************************************************
+* *
+* Paramètres : proc = architecture visée par la consultation. *
+* *
+* Description : Fournit la taille courante des opérandes pour x86. *
+* *
+* Retour : Taille d'opérande (16 ou 32 bits). *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+AsmOperandSize get_x86_current_operand_size(const asm_x86_processor *proc)
+{
+ return proc->operand_size;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = architecture visée par la consultation. *
+* *
+* Description : Fournit la taille supplantée des opérandes pour x86. *
+* *
+* Retour : Taille d'opérande (16 ou 32 bits). *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+AsmOperandSize switch_x86_operand_size(const asm_x86_processor *proc)
+{
+ return (proc->operand_size == AOS_32_BITS ? AOS_16_BITS : AOS_32_BITS);
+
+}
/******************************************************************************
@@ -150,23 +189,25 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_DEC_ESI], 0x00, 0x4e, "dec", read_instr_dec_1632);
register_opcode(proc->opcodes[X86_OP_DEC_EDI], 0x00, 0x4f, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_EAX], 0x00, 0x50, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_ECX], 0x00, 0x51, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_EDX], 0x00, 0x52, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_EBX], 0x00, 0x53, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_ESP], 0x00, 0x54, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_EBP], 0x00, 0x55, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_ESI], 0x00, 0x56, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_EDI], 0x00, 0x57, "push", read_instr_push_1632);
-
- register_opcode(proc->opcodes[X86_OP_POP_EAX], 0x00, 0x58, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_ECX], 0x00, 0x59, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_EDX], 0x00, 0x5a, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_EBX], 0x00, 0x5b, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_ESP], 0x00, 0x5c, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_EBP], 0x00, 0x5d, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_ESI], 0x00, 0x5e, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_EDI], 0x00, 0x5f, "pop", read_instr_pop_1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_EAX], 0x00, 0x50, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_ECX], 0x00, 0x51, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_EDX], 0x00, 0x52, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_EBX], 0x00, 0x53, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_ESP], 0x00, 0x54, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_EBP], 0x00, 0x55, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_ESI], 0x00, 0x56, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_EDI], 0x00, 0x57, "push", read_instr_push_reg1632);
+
+ register_opcode(proc->opcodes[X86_OP_POP_EAX], 0x00, 0x58, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_ECX], 0x00, 0x59, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_EDX], 0x00, 0x5a, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_EBX], 0x00, 0x5b, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_ESP], 0x00, 0x5c, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_EBP], 0x00, 0x5d, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_ESI], 0x00, 0x5e, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_EDI], 0x00, 0x5f, "pop", read_instr_pop_reg1632);
+
+ register_opcode(proc->opcodes[X86_OP_PUSH_IMM32], 0x00, 0x68, "push", read_instr_push_imm1632);
register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", read_instr_nop);
@@ -185,6 +226,8 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_INT], 0x00, 0xcd, "int", read_instr_int);
+ register_opcode(proc->opcodes[X86_OP_CALL], 0x00, 0xe8, "call", read_instr_call);
+
register_opcode(proc->opcodes[X86_OP_HLT], 0x00, 0xf4, "hlt", read_instr_hlt);
@@ -206,23 +249,25 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_DEC_SI], 0x66, 0x4e, "dec", read_instr_dec_1632);
register_opcode(proc->opcodes[X86_OP_DEC_DI], 0x66, 0x4f, "dec", read_instr_dec_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_AX], 0x66, 0x50, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_CX], 0x66, 0x51, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_DX], 0x66, 0x52, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_BX], 0x66, 0x53, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_SP], 0x66, 0x54, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_BP], 0x66, 0x55, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_SI], 0x66, 0x56, "push", read_instr_push_1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_DI], 0x66, 0x57, "push", read_instr_push_1632);
-
- register_opcode(proc->opcodes[X86_OP_POP_AX], 0x66, 0x58, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_CX], 0x66, 0x59, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_DX], 0x66, 0x5a, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_BX], 0x66, 0x5b, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_SP], 0x66, 0x5c, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_BP], 0x66, 0x5d, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_SI], 0x66, 0x5e, "pop", read_instr_pop_1632);
- register_opcode(proc->opcodes[X86_OP_POP_DI], 0x66, 0x5f, "pop", read_instr_pop_1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_AX], 0x66, 0x50, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_CX], 0x66, 0x51, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_DX], 0x66, 0x52, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_BX], 0x66, 0x53, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_SP], 0x66, 0x54, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_BP], 0x66, 0x55, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_SI], 0x66, 0x56, "push", read_instr_push_reg1632);
+ register_opcode(proc->opcodes[X86_OP_PUSH_DI], 0x66, 0x57, "push", read_instr_push_reg1632);
+
+ register_opcode(proc->opcodes[X86_OP_POP_AX], 0x66, 0x58, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_CX], 0x66, 0x59, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_DX], 0x66, 0x5a, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_BX], 0x66, 0x5b, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_SP], 0x66, 0x5c, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_BP], 0x66, 0x5d, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_SI], 0x66, 0x5e, "pop", read_instr_pop_reg1632);
+ register_opcode(proc->opcodes[X86_OP_POP_DI], 0x66, 0x5f, "pop", read_instr_pop_reg1632);
+
+ register_opcode(proc->opcodes[X86_OP_PUSH_IMM16], 0x66, 0x68, "push", read_instr_push_imm1632);
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);
@@ -241,10 +286,11 @@ void x86_register_instructions(asm_x86_processor *proc)
/******************************************************************************
* *
-* Paramètres : proc = architecture visée par la procédure. *
-* data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
-* len = taille totale des données à analyser. *
+* Paramètres : proc = architecture visée par la procédure. *
+* 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. *
* *
* Description : Décode une instruction dans un flux de données. *
* *
@@ -254,7 +300,7 @@ void x86_register_instructions(asm_x86_processor *proc)
* *
******************************************************************************/
-asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *data, off_t *pos, off_t len)
+asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *data, off_t *pos, off_t len, uint64_t offset)
{
asm_x86_instr *result; /* Résultat à faire remonter */
X86Opcodes i; /* Boucle de parcours */
@@ -266,7 +312,7 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d
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);
+ result = proc->opcodes[i].read(data, pos, len, offset, proc);
if (result != NULL) result->type = i;
printf("err while decoding :: [0x%02hhx] 0x%02hhx\n", proc->opcodes[i].prefix, proc->opcodes[i].opcode);
break;
diff --git a/src/arch/x86/processor.h b/src/arch/x86/processor.h
index 0bd587d..c898d80 100644
--- a/src/arch/x86/processor.h
+++ b/src/arch/x86/processor.h
@@ -30,10 +30,18 @@
+/* Définition générique d'une architecture */
+typedef struct _asm_x86_processor asm_x86_processor;
+
+
/* Crée le support de l'architecture x86. */
asm_processor *create_x86_processor(void);
+/* Fournit la taille courante des opérandes pour x86. */
+AsmOperandSize get_x86_current_operand_size(const asm_x86_processor *);
+/* Fournit la taille supplantée des opérandes pour x86. */
+AsmOperandSize switch_x86_operand_size(const asm_x86_processor *);