summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/instruction.h4
-rw-r--r--src/arch/x86/op_add.c35
-rw-r--r--src/arch/x86/op_jump.c86
-rw-r--r--src/arch/x86/op_push.c6
-rw-r--r--src/arch/x86/opcodes.h9
-rw-r--r--src/arch/x86/operand.c26
-rw-r--r--src/arch/x86/processor.c18
7 files changed, 175 insertions, 9 deletions
diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h
index 8ef603f..baf911d 100644
--- a/src/arch/x86/instruction.h
+++ b/src/arch/x86/instruction.h
@@ -38,6 +38,8 @@ typedef struct _asm_x86_instr asm_x86_instr;
/* Enumération de tous les opcodes */
typedef enum _X86Opcodes
{
+ X86_OP_ADD_RM8_R8, /* add (0x00) */
+
X86_OP_SUB_R1632_RM1632, /* sub ([0x66] 0x29) */
X86_OP_XOR_RM8_R8, /* xor (0x30) */
@@ -145,12 +147,14 @@ typedef enum _X86Opcodes
X86_OP_INT, /* int (0xcd) */
X86_OP_CALL_REL1632, /* call ([0x66] 0xe8) */
+ X86_OP_JMP_REL1632, /* jmp ([0x66] 0xe9) */
X86_OP_JMP_8, /* jmp (0xeb) */
X86_OP_HLT, /* hlt (0xf4) */
X86_OP_CALL_RM1632, /* call ([0x66] 0xff 2) */
+ X86_OP_JMP_RM1632, /* jmp ([0x66] 0xff 4) */
X86_OP_PUSH_RM1632, /* push ([0x66] 0xff 6) */
X86_OP_COUNT
diff --git a/src/arch/x86/op_add.c b/src/arch/x86/op_add.c
index 52b998f..f42c8f9 100644
--- a/src/arch/x86/op_add.c
+++ b/src/arch/x86/op_add.c
@@ -104,3 +104,38 @@ asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *data, off_t *
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 'add' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_add_rm8_r8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+{
+ asm_x86_instr *result; /* Instruction à retourner */
+
+ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
+
+ ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c
index b301b10..3739b24 100644
--- a/src/arch/x86/op_jump.c
+++ b/src/arch/x86/op_jump.c
@@ -54,6 +54,8 @@ asm_x86_instr *x86_read_instr_je_8(const uint8_t *data, off_t *pos, off_t len, u
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset))
{
free(result);
@@ -89,6 +91,8 @@ asm_x86_instr *x86_read_instr_jne_8(const uint8_t *data, off_t *pos, off_t len,
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset))
{
free(result);
@@ -124,6 +128,8 @@ asm_x86_instr *x86_read_instr_jmp_8(const uint8_t *data, off_t *pos, off_t len,
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, offset))
{
free(result);
@@ -133,3 +139,83 @@ asm_x86_instr *x86_read_instr_jmp_8(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 'jmp' (grand saut relatif). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_jmp_rel1632(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 */
+
+ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
+
+ oprsize = switch_x86_operand_size_if_needed(proc, data, pos);
+
+ ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
+ if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL1632, oprsize, offset))
+ {
+ 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. *
+* offset = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'jmp' (saut en mémoire). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_jmp_rm1632(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 */
+
+ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
+
+ oprsize = switch_x86_operand_size_if_needed(proc, data, pos);
+
+ ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
+ if (!x86_read_one_operand(result, data, pos, len, X86_OTP_RM1632, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_push.c b/src/arch/x86/op_push.c
index ce76919..f51bd6f 100644
--- a/src/arch/x86/op_push.c
+++ b/src/arch/x86/op_push.c
@@ -58,6 +58,8 @@ asm_x86_instr *x86_read_instr_push_imm1632(const uint8_t *data, off_t *pos, off_
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_PUSH;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_IMM1632, oprsize))
{
free(result);
@@ -96,6 +98,8 @@ asm_x86_instr *x86_read_instr_push_r1632(const uint8_t *data, off_t *pos, off_t
ASM_INSTRUCTION(result)->opcode = data[*pos];
+ ASM_INSTRUCTION(result)->type = AIT_PUSH;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_OP_R1632, oprsize, 0x50))
{
free(result);
@@ -134,6 +138,8 @@ asm_x86_instr *x86_read_instr_push_rm1632(const uint8_t *data, off_t *pos, off_t
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+ ASM_INSTRUCTION(result)->type = AIT_PUSH;
+
if (!x86_read_one_operand(result, data, pos, len, X86_OTP_RM1632, oprsize))
{
free(result);
diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h
index cbadcf5..70d41b8 100644
--- a/src/arch/x86/opcodes.h
+++ b/src/arch/x86/opcodes.h
@@ -43,6 +43,9 @@ asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *, off_t *, off_t
/* Décode une instruction de type 'add' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'add' (8 bits). */
+asm_x86_instr *x86_read_instr_add_rm8_r8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'and' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_and_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
@@ -82,6 +85,12 @@ asm_x86_instr *x86_read_instr_jne_8(const uint8_t *, off_t *, off_t, uint64_t, c
/* Décode une instruction de type 'jump' (petit saut). */
asm_x86_instr *x86_read_instr_jmp_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'jmp' (grand saut relatif). */
+asm_x86_instr *x86_read_instr_jmp_rel1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'jmp' (saut en mémoire). */
+asm_x86_instr *x86_read_instr_jmp_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'lea' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_lea(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 375b0a5..e13c793 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -1300,7 +1300,8 @@ asm_x86_operand *x86_create_rel1632_operand_in_32b(uint64_t base, const uint8_t
{
asm_x86_operand *result; /* Emplacement à retourner */
off_t init_pos; /* Position avant lecture */
- int8_t offset; /* Décallage à appliquer */
+ int32_t offset32; /* Décallage 32b à appliquer */
+ int16_t offset16; /* Décallage 16b à appliquer */
uint32_t address; /* Adresse finale visée */
result = create_new_x86_operand();
@@ -1308,13 +1309,28 @@ asm_x86_operand *x86_create_rel1632_operand_in_32b(uint64_t base, const uint8_t
init_pos = *pos;
address = base;
- if (!read_imm_value(is_reg32 ? AOS_32_BITS : AOS_16_BITS, data, pos, len, &offset))
+ if (is_reg32)
{
- free(result);
- return NULL;
+ if (!read_imm_value(AOS_32_BITS, data, pos, len, &offset32))
+ {
+ free(result);
+ return NULL;
+ }
+
+ address = base + (*pos - init_pos) + offset32;
+
}
+ else
+ {
+ if (!read_imm_value(AOS_16_BITS, data, pos, len, &offset16))
+ {
+ free(result);
+ return NULL;
+ }
- address = base + (*pos - init_pos) + offset;
+ address = base + (*pos - init_pos) + offset16;
+
+ }
if (!fill_imm_operand_with_value(ASM_OPERAND(result), AOS_32_BITS, &address))
{
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c
index 0b81a8c..5694d9e 100644
--- a/src/arch/x86/processor.c
+++ b/src/arch/x86/processor.c
@@ -61,7 +61,7 @@ typedef struct _x86_opcode
do { \
target.prefix = _prefix; \
target.opcode = _opcode; \
- target.opt_prefix = true; \
+ target.opt_prefix = (_prefix != 0x00); \
target.has_op_ext = false; \
target.name = _name; \
target.read = _read; \
@@ -72,7 +72,7 @@ typedef struct _x86_opcode
target.prefix = _prefix; \
target.opcode = _opcode; \
target.op_ext = _ext << 3; \
- target.opt_prefix = true; \
+ target.opt_prefix = (_prefix != 0x00); \
target.has_op_ext = true; \
target.name = _name; \
target.read = _read; \
@@ -205,6 +205,8 @@ AsmOperandSize switch_x86_operand_size_if_needed(const asm_x86_processor *proc,
void x86_register_instructions(asm_x86_processor *proc)
{
+ register_opcode(proc->opcodes[X86_OP_ADD_RM8_R8], 0x00, 0x00, "add", x86_read_instr_add_rm8_r8);
+
register_opcode(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x66, 0x29, "sub", x86_read_instr_sub_r1632_from_rm1632);
register_opcode(proc->opcodes[X86_OP_XOR_RM8_R8], 0x00, 0x30, "xor", x86_read_instr_xor_rm8_with_r8);
@@ -314,12 +316,14 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_CALL_REL1632], 0x66, 0xe8, "call", x86_read_instr_call_rel1632);
+ register_opcode(proc->opcodes[X86_OP_JMP_REL1632], 0x66, 0xe9, "jmp", x86_read_instr_jmp_rel1632);
register_opcode(proc->opcodes[X86_OP_JMP_8], 0x00, 0xeb, "jmp", x86_read_instr_jmp_8);
register_opcode(proc->opcodes[X86_OP_HLT], 0x00, 0xf4, "hlt", x86_read_instr_hlt);
register_opcode_with_ext(proc->opcodes[X86_OP_CALL_RM1632], 0x66, 0xff, 2, "call", x86_read_instr_call_rm1632);
+ register_opcode_with_ext(proc->opcodes[X86_OP_JMP_RM1632], 0x66, 0xff, 4, "jmp", x86_read_instr_jmp_rm1632);
register_opcode_with_ext(proc->opcodes[X86_OP_PUSH_RM1632], 0x66, 0xff, 6, "push", x86_read_instr_push_rm1632);
@@ -367,6 +371,12 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d
goto find_instr;
}
+ if (proc->opcodes[i].prefix == 0x00 && data[*pos] == proc->opcodes[i].opcode)
+ {
+ tmp = *pos + 1;
+ goto find_instr;
+ }
+
continue;
find_instr:
@@ -381,7 +391,7 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d
else
{
*pos = old_pos;
- printf("err while decoding at 0x%08llx :: [0x%02hhx] 0x%02hhx\n", offset, proc->opcodes[i].prefix, proc->opcodes[i].opcode);
+ printf("err while x86 decoding at 0x%08llx :: [0x%02hhx] 0x%02hhx\n", offset, proc->opcodes[i].prefix, proc->opcodes[i].opcode);
}
break;
@@ -456,7 +466,7 @@ void x86_print_instruction(const asm_x86_processor *proc, const exe_format *form
/* Impression globale finale */
- if (ASM_INSTRUCTION(instr)->opcode == DB_OPCODE)
+ if (ASM_INSTRUCTION(instr)->type == AIT_DB)
snprintf(buffer, len, "db\t%s", opbuffer[0]);
else