summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/instruction.h5
-rw-r--r--src/arch/x86/op_mov.c124
-rw-r--r--src/arch/x86/opcodes.h6
-rw-r--r--src/arch/x86/operand.c407
-rw-r--r--src/arch/x86/operand.h5
-rw-r--r--src/arch/x86/processor.c5
6 files changed, 482 insertions, 70 deletions
diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h
index 9f89a9e..f8c2f7d 100644
--- a/src/arch/x86/instruction.h
+++ b/src/arch/x86/instruction.h
@@ -88,6 +88,8 @@ typedef enum _X86Opcodes
X86_OP_SUB8_REG1632, /* sub ([0x66] 0x83) */
X86_OP_XOR8_REG1632, /* xor ([0x66] 0x83) */
+ X86_OP_MOV_FROM_CONTENT1632, /* mov ([0x66] 0x8b) */
+
X86_OP_NOP, /* nop (0x90) */
X86_OP_MOV_E_AX, /* mov ([0x66] 0xb8) */
@@ -100,6 +102,9 @@ typedef enum _X86Opcodes
X86_OP_MOV_E_DI, /* mov ([0x66] 0xbf) */
X86_OP_RET, /* ret (0xc3) */
+
+ X86_OP_MOV_TO_CONTENT1632, /* mov ([0x66] 0xc7) */
+
X86_OP_LEAVE, /* leave (0xc9) */
X86_OP_INT, /* int (0xcd) */
diff --git a/src/arch/x86/op_mov.c b/src/arch/x86/op_mov.c
index f0a5fce..60de5cf 100644
--- a/src/arch/x86/op_mov.c
+++ b/src/arch/x86/op_mov.c
@@ -157,3 +157,127 @@ asm_x86_instr *read_instr_mov_to_1632(const uint8_t *data, off_t *pos, off_t len
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. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *read_instr_mov_from_content_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 */
+ AsmOperandSize oprsize; /* Taille des opérandes */
+ asm_x86_operand *reg1; /* Registre de destination */
+ asm_x86_operand *reg2; /* Registre de source */
+
+ 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)++];
+
+ reg1 = x86_create_reg1632_operand_from_modrm(data[*pos], oprsize == AOS_32_BITS, false);
+ if (reg1 == NULL)
+ {
+ (*pos)--;
+ free(result);
+ return NULL;
+ }
+
+ reg2 = x86_create_content1632_operand(data, pos, len, oprsize == AOS_32_BITS, true);
+ if (reg2 == NULL)
+ {
+ (*pos)--;
+ 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(reg1);
+ ASM_INSTRUCTION(result)->operands[1] = ASM_OPERAND(reg2);
+
+ 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. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *read_instr_mov_to_content_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 */
+ 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_content1632_operand(data, pos, len, oprsize == AOS_32_BITS, true);
+ if (reg == NULL)
+ {
+ free(result);
+ return NULL;
+ }
+
+ value = create_new_x86_operand();
+ if (!fill_imm_operand(ASM_OPERAND(value), oprsize, 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/opcodes.h b/src/arch/x86/opcodes.h
index 6cf6d3c..349ea40 100644
--- a/src/arch/x86/opcodes.h
+++ b/src/arch/x86/opcodes.h
@@ -62,9 +62,15 @@ asm_x86_instr *read_instr_int(const uint8_t *, off_t *, off_t, uint64_t, const a
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' (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 *);
+
+/* 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, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'mov' (16 ou 32 bits). */
+asm_x86_instr *read_instr_mov_to_content_1632(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_with_reg1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'nop'. */
diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c
index 3eaefd2..ada66f0 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -24,6 +24,7 @@
#include <malloc.h>
+#include <math.h>
#include <stdio.h>
@@ -45,6 +46,8 @@ typedef enum _X868bRegister
X86_REG8_DH = 6, /* Registre AH */
X86_REG8_BH = 7, /* Registre AH */
+ X86_REG8_NONE /* Aucun registre */
+
} X868bRegister;
/* Liste des registres 16 bits */
@@ -59,6 +62,8 @@ typedef enum _X8616bRegister
X86_REG16_SI = 6, /* Registre SI */
X86_REG16_DI = 7, /* Registre DI */
+ X86_REG16_NONE /* Aucun registre */
+
} X8616bRegister;
/* Liste des registres 32 bits */
@@ -73,9 +78,20 @@ typedef enum _X8632bRegister
X86_REG32_ESI = 6, /* Registre ESI */
X86_REG32_EDI = 7, /* Registre EDI */
+ X86_REG32_NONE /* Aucun registre */
+
} X8632bRegister;
+/* Registre X86 */
+typedef union _x86_register
+{
+ X868bRegister reg8; /* Registre 8 bits */
+ X8616bRegister reg16; /* Registre 16 bits */
+ X8632bRegister reg32; /* Registre 32 bits */
+
+} x86_register;
+
@@ -84,13 +100,13 @@ 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_register rindex; /* Registre servant d'indice */
+
+ bool content; /* Contenu d'un registre */
- } x86_value;
+ uint8_t scale; /* Puissance de deux */
+ x86_register rbase; /* Registre de base */
+ asm_operand *displacement; /* Décallage supplémentaire */
};
@@ -100,6 +116,16 @@ struct _asm_x86_operand
+/* Récupère l'indentifiant interne d'un registre. */
+bool get_x86_register(x86_register *, AsmOperandSize, uint8_t);
+
+
+/* Traduit une opérande de registre en texte. */
+void _x86_print_reg_operand(const x86_register *reg, AsmOperandSize, char *, size_t, AsmSyntax);
+
+
+
+
/******************************************************************************
@@ -116,7 +142,14 @@ struct _asm_x86_operand
asm_x86_operand *create_new_x86_operand(void)
{
- return (asm_x86_operand *)calloc(1, sizeof(asm_x86_operand));
+ asm_x86_operand *result; /* Structure à retourner */
+
+ result = (asm_x86_operand *)calloc(1, sizeof(asm_x86_operand));
+
+ result->scale = 0;
+ result->rbase.reg32 = X86_REG32_NONE;
+
+ return result;
}
@@ -128,6 +161,66 @@ asm_x86_operand *create_new_x86_operand(void)
/******************************************************************************
* *
+* Paramètres : reg = registre à définir. [OUT] *
+* size = indique la taille du registre. *
+* value = valeur correspondant au registre. *
+* *
+* Description : Récupère l'indentifiant interne d'un registre. *
+* *
+* Retour : true si la définition est opérée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool get_x86_register(x86_register *reg, AsmOperandSize size, uint8_t value)
+{
+ switch (size)
+ {
+ case AOS_8_BITS:
+ return false;
+ break;
+
+ case AOS_16_BITS:
+ switch (value)
+ {
+ case 0 ... 7:
+ reg->reg16 = (X8616bRegister)value;
+ break;
+ default:
+ return false;
+ break;
+ }
+ break;
+
+ case AOS_32_BITS:
+ switch (value)
+ {
+ case 0 ... 7:
+ reg->reg32 = (X8632bRegister)value;
+ break;
+ default:
+ return false;
+ break;
+ }
+ break;
+
+ case AOS_64_BITS:
+ return false;
+ break;
+
+ }
+
+ return true;
+
+}
+
+
+
+
+
+/******************************************************************************
+* *
* Paramètres : data = donnée à analyser. *
* is_reg32 = indique si le registre est un registre 32 bits. *
* base = valeur du premier registre. *
@@ -143,38 +236,17 @@ asm_x86_operand *create_new_x86_operand(void)
asm_x86_operand *x86_create_reg1632_operand(uint8_t data, bool is_reg32, uint8_t base)
{
asm_x86_operand *result; /* Registre à retourner */
- X8616bRegister reg16; /* Registre 16 bits */
- X8632bRegister reg32; /* Registre 32 bits */
-
- if (is_reg32)
- switch (data - base)
- {
- case 0 ... 7:
- reg32 = (X8632bRegister)(data - base);
- break;
- default:
- return NULL;
- break;
- }
-
- else
- switch (data - base)
- {
- case 0 ... 7:
- reg16 = (X8616bRegister)(data - base);
- 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;
+ if (!get_x86_register(&result->rindex, ASM_OPERAND(result)->size, data - base))
+ {
+ free(result);
+ return NULL;
+ }
return result;
@@ -199,41 +271,147 @@ asm_x86_operand *x86_create_reg1632_operand_from_modrm(uint8_t data, bool is_reg
{
asm_x86_operand *result; /* Registre à retourner */
uint8_t reg; /* Transcription du registre */
- X8616bRegister reg16; /* Registre 16 bits */
- X8632bRegister reg32; /* Registre 32 bits */
if (first) reg = data & 0x07;
else reg = (data & 0x38) >> 3;
- if (is_reg32)
- switch (reg)
+ result = create_new_x86_operand();
+
+ ASM_OPERAND(result)->type = AOT_REG;
+ ASM_OPERAND(result)->size = (is_reg32 ? AOS_32_BITS : AOS_16_BITS);
+
+ if (!get_x86_register(&result->rindex, ASM_OPERAND(result)->size, reg))
+ {
+ free(result);
+ return NULL;
+ }
+
+ 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. *
+* first = indique la partie du ModR/M à traiter. *
+* *
+* Description : Crée une opérande renvoyant vers un contenu 16 ou 32 bits. *
+* *
+* Retour : Opérande mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_operand *x86_create_content1632_operand(const uint8_t *data, off_t *pos, off_t len, bool is_reg32, bool first)
+{
+ asm_x86_operand *result; /* Registre à retourner */
+ uint8_t mod; /* Modificateur présent */
+
+ /* Pas de contenu */
+ mod = (data[*pos] & 0xc0);
+ if (mod == 0xc0) return NULL;
+
+ result = x86_create_reg1632_operand_from_modrm(data[*pos], is_reg32, first);
+ if (result == NULL) return NULL;
+
+ result->content = true;
+
+ (*pos)++;
+
+ /* Vieille astuce de l'emplacement mémoire fixe ? */
+ if (result->rindex.reg32 == X86_REG32_EBP && mod == 0x00)
+ {
+ free(result);
+
+ result = create_new_x86_operand();
+ if (!fill_imm_operand(ASM_OPERAND(result), AOS_32_BITS/* FIXME ? */, data, pos, len))
{
- case 0 ... 7:
- reg32 = (X8632bRegister)reg;
- break;
- default:
- return NULL;
- break;
+ (*pos)--;
+ free(result);
+ return NULL;
}
- else
- switch (reg)
+ return result;
+
+ }
+
+ /* A la recherche d'un SIB */
+ if (result->rindex.reg32 == X86_REG32_ESP)
+ {
+ if (!get_x86_register(&result->rbase, ASM_OPERAND(result)->size, data[*pos] & 0x07))
{
- case 0 ... 7:
- reg16 = (X8616bRegister)reg;
- break;
- default:
- return NULL;
- break;
+ (*pos)--;
+ free(result);
+ return NULL;
}
- result = create_new_x86_operand();
+ if (!get_x86_register(&result->rindex, ASM_OPERAND(result)->size, (data[*pos] & 0x38) >> 3))
+ {
+ (*pos)--;
+ free(result);
+ return NULL;
+ }
- ASM_OPERAND(result)->type = AOT_REG;
- ASM_OPERAND(result)->size = (is_reg32 ? AOS_32_BITS : AOS_16_BITS);
+ result->scale = ((data[*pos] & 0xc0) >> 6);
+
+ if (result->rindex.reg32 == X86_REG32_ESP)
+ {
+ result->rindex.reg32 = result->rbase.reg32;
+ result->rbase.reg32 = X86_REG32_NONE;
+ }
- if (is_reg32) result->x86_value.reg32 = reg32;
- else result->x86_value.reg16 = reg16;
+ (*pos)++;
+
+ }
+
+ /* Décallage supplémentaire ? */
+ switch (mod)
+ {
+ case 0x00:
+ if (result->rbase.reg32 == X86_REG32_EBP)
+ {
+ result->rbase.reg32 = X86_REG32_NONE;
+
+ result->displacement = create_new_x86_operand();
+ if (!fill_imm_operand(ASM_OPERAND(result->displacement), ASM_OPERAND(result)->size, data, pos, len))
+ {
+ (*pos) -= 2;
+ free(result->displacement);
+ free(result);
+ return NULL;
+ }
+
+ }
+ break;
+
+ case 0x40:
+ result->displacement = create_new_x86_operand();
+ if (!fill_imm_operand(ASM_OPERAND(result->displacement), AOS_8_BITS, data, pos, len))
+ {
+ (*pos) -= 2;
+ free(result->displacement);
+ free(result);
+ return NULL;
+ }
+ break;
+
+ case 0x80:
+ result->displacement = create_new_x86_operand();
+ if (!fill_imm_operand(ASM_OPERAND(result->displacement), AOS_32_BITS, data, pos, len))
+ {
+ (*pos) -= 2;
+ free(result->displacement);
+ free(result);
+ return NULL;
+ }
+ break;
+
+ }
return result;
@@ -242,10 +420,11 @@ asm_x86_operand *x86_create_reg1632_operand_from_modrm(uint8_t data, bool is_reg
/******************************************************************************
* *
-* Paramètres : operand = instruction à traiter. *
-* buffer = tampon de sortie mis à disposition. [OUT] *
-* len = taille de ce tampon. *
-* syntax = type de représentation demandée. *
+* Paramètres : reg = registre à imprimer. *
+* size = indique la taille du registre. *
+* 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. *
* *
@@ -255,15 +434,15 @@ asm_x86_operand *x86_create_reg1632_operand_from_modrm(uint8_t data, bool is_reg
* *
******************************************************************************/
-void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t len, AsmSyntax syntax)
+void _x86_print_reg_operand(const x86_register *reg, AsmOperandSize size, char *buffer, size_t len, AsmSyntax syntax)
{
switch (syntax)
{
case ASX_INTEL:
- switch (ASM_OPERAND(operand)->size)
+ switch (size)
{
case AOS_8_BITS:
- switch (operand->x86_value.reg8)
+ switch (reg->reg8)
{
case X86_REG8_AL:
snprintf(buffer, len, "al");
@@ -289,11 +468,14 @@ void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t
case X86_REG8_BH:
snprintf(buffer, len, "bh");
break;
+ case X86_REG8_NONE:
+ /* Ne devrait jamais arriver */
+ break;
}
break;
case AOS_16_BITS:
- switch (operand->x86_value.reg16)
+ switch (reg->reg16)
{
case X86_REG16_AX:
snprintf(buffer, len, "ax");
@@ -319,11 +501,14 @@ void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t
case X86_REG16_DI:
snprintf(buffer, len, "di");
break;
+ case X86_REG16_NONE:
+ /* Ne devrait jamais arriver */
+ break;
}
break;
case AOS_32_BITS:
- switch (operand->x86_value.reg32)
+ switch (reg->reg32)
{
case X86_REG32_EAX:
snprintf(buffer, len, "eax");
@@ -349,6 +534,9 @@ void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t
case X86_REG32_EDI:
snprintf(buffer, len, "edi");
break;
+ case X86_REG32_NONE:
+ /* Ne devrait jamais arriver */
+ break;
}
break;
@@ -359,10 +547,10 @@ void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t
break;
case ASX_ATT:
- switch (ASM_OPERAND(operand)->size)
+ switch (size)
{
case AOS_8_BITS:
- switch (operand->x86_value.reg8)
+ switch (reg->reg8)
{
case X86_REG8_AL:
snprintf(buffer, len, "%%al");
@@ -388,11 +576,14 @@ void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t
case X86_REG8_BH:
snprintf(buffer, len, "%%bh");
break;
+ case X86_REG8_NONE:
+ /* Ne devrait jamais arriver */
+ break;
}
break;
case AOS_16_BITS:
- switch (operand->x86_value.reg16)
+ switch (reg->reg16)
{
case X86_REG16_AX:
snprintf(buffer, len, "%%ax");
@@ -418,11 +609,14 @@ void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t
case X86_REG16_DI:
snprintf(buffer, len, "%%di");
break;
+ case X86_REG16_NONE:
+ /* Ne devrait jamais arriver */
+ break;
}
break;
case AOS_32_BITS:
- switch (operand->x86_value.reg32)
+ switch (reg->reg32)
{
case X86_REG32_EAX:
snprintf(buffer, len, "%%eax");
@@ -448,6 +642,9 @@ void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t
case X86_REG32_EDI:
snprintf(buffer, len, "%%edi");
break;
+ case X86_REG32_NONE:
+ /* Ne devrait jamais arriver */
+ break;
}
break;
@@ -460,3 +657,75 @@ void x86_print_reg_operand(const asm_x86_operand *operand, char *buffer, size_t
}
}
+
+
+/******************************************************************************
+* *
+* 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)
+{
+ size_t pos; /* Position de traitement */
+
+ switch (syntax)
+ {
+ case ASX_INTEL:
+
+ if (operand->content)
+ {
+ strcpy(buffer, "[");
+
+ if (operand->scale > 0)
+ snprintf(&buffer[1], len - 1, "%d*", (int)pow(2, operand->scale));
+
+ pos = strlen(buffer);
+
+ }
+ else pos = 0;
+
+
+ _x86_print_reg_operand(&operand->rindex, ASM_OPERAND(operand)->size, &buffer[pos], len - pos, syntax);
+
+ if (operand->rbase.reg32 != X86_REG32_NONE)
+ {
+ strcat(buffer, "+"); /* TODO: n */
+ pos = strlen(buffer);
+
+ _x86_print_reg_operand(&operand->rbase, ASM_OPERAND(operand)->size, &buffer[pos], len - pos, syntax);
+
+ }
+
+
+ if (operand->displacement != NULL)
+ {
+ strcat(buffer, "+"); /* TODO: n */
+ pos = strlen(buffer);
+
+ print_imm_operand(operand->displacement, &buffer[pos], len - pos, syntax);
+
+ }
+
+
+
+ if (operand->content) strcat(buffer, "]");
+
+ break;
+
+ case ASX_ATT:
+
+ break;
+
+ }
+
+}
diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h
index e6eb3cc..fbaba57 100644
--- a/src/arch/x86/operand.h
+++ b/src/arch/x86/operand.h
@@ -48,7 +48,10 @@ asm_x86_operand *x86_create_reg1632_operand(uint8_t, bool, uint8_t);
/* Crée une opérande renvoyant vers un registre 16 ou 32 bits. */
asm_x86_operand *x86_create_reg1632_operand_from_modrm(uint8_t, bool, bool);
-/*Traduit une opérande de registre en texte. */
+/* Crée une opérande renvoyant vers un contenu 16 ou 32 bits. */
+asm_x86_operand *x86_create_content1632_operand(const uint8_t *, off_t *, off_t, bool, bool);
+
+/* Traduit une opérande de registre en texte. */
void x86_print_reg_operand(const asm_x86_operand *, char *, size_t, AsmSyntax);
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c
index 0014652..f632f4b 100644
--- a/src/arch/x86/processor.c
+++ b/src/arch/x86/processor.c
@@ -245,6 +245,8 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode_with_ext(proc->opcodes[X86_OP_SUB8_REG1632], 0x66, 0x83, 5, "sub", read_instr_sub8_with_reg1632);
register_opcode_with_ext(proc->opcodes[X86_OP_XOR8_REG1632], 0x66, 0x83, 6, "xor", read_instr_xor8_with_reg1632);
+ register_opcode(proc->opcodes[X86_OP_MOV_FROM_CONTENT1632], 0x66, 0x8b, "mov", read_instr_mov_from_content_1632);
+
register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", read_instr_nop);
register_opcode(proc->opcodes[X86_OP_MOV_E_AX], 0x66, 0xb8, "mov", read_instr_mov_to_1632);
@@ -257,6 +259,9 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_MOV_E_DI], 0x66, 0xbf, "mov", read_instr_mov_to_1632);
register_opcode(proc->opcodes[X86_OP_RET], 0x00, 0xc3, "ret", read_instr_ret);
+
+ register_opcode(proc->opcodes[X86_OP_MOV_TO_CONTENT1632], 0x66, 0xc7, "mov", read_instr_mov_to_content_1632);
+
register_opcode(proc->opcodes[X86_OP_LEAVE], 0x00, 0xc9, "leave", read_instr_leave);
register_opcode(proc->opcodes[X86_OP_INT], 0x00, 0xcd, "int", read_instr_int);