summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--src/arch/operand-int.h6
-rw-r--r--src/arch/x86/instruction.h5
-rw-r--r--src/arch/x86/op_mov.c118
-rw-r--r--src/arch/x86/opcodes.h6
-rw-r--r--src/arch/x86/operand.c118
-rw-r--r--src/arch/x86/operand.h14
-rw-r--r--src/arch/x86/processor.c6
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 <nocbos@gmail.com>
+
+ * 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 <nocbos@gmail.com>
* 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 */