diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/instruction.h | 5 | ||||
-rw-r--r-- | src/arch/x86/op_mov.c | 124 | ||||
-rw-r--r-- | src/arch/x86/opcodes.h | 6 | ||||
-rw-r--r-- | src/arch/x86/operand.c | 407 | ||||
-rw-r--r-- | src/arch/x86/operand.h | 5 | ||||
-rw-r--r-- | src/arch/x86/processor.c | 5 |
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); |