summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/Makefile.am5
-rw-r--r--src/arch/x86/instruction.h29
-rw-r--r--src/arch/x86/op_add.c38
-rw-r--r--src/arch/x86/op_cld.c58
-rw-r--r--src/arch/x86/op_jump.c74
-rw-r--r--src/arch/x86/op_mov.c35
-rw-r--r--src/arch/x86/op_movsx.c71
-rw-r--r--src/arch/x86/op_movzx.c3
-rw-r--r--src/arch/x86/op_not.c68
-rw-r--r--src/arch/x86/op_shl.c38
-rw-r--r--src/arch/x86/opcodes.h30
-rw-r--r--src/arch/x86/operand.c12
-rw-r--r--src/arch/x86/operand.h1
-rw-r--r--src/arch/x86/processor.c49
14 files changed, 480 insertions, 31 deletions
diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am
index 58ffaa8..42326c9 100644
--- a/src/arch/x86/Makefile.am
+++ b/src/arch/x86/Makefile.am
@@ -7,6 +7,7 @@ libarchx86_a_SOURCES = \
op_add.c \
op_and.c \
op_call.c \
+ op_cld.c \
op_cmp.c \
op_dec.c \
op_hlt.c \
@@ -15,9 +16,11 @@ libarchx86_a_SOURCES = \
op_jump.c \
op_lea.c \
op_leave.c \
- op_nop.c \
op_mov.c \
+ op_movsx.c \
op_movzx.c \
+ op_nop.c \
+ op_not.c \
op_or.c \
op_pop.c \
op_push.c \
diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h
index 1c97255..0092ba0 100644
--- a/src/arch/x86/instruction.h
+++ b/src/arch/x86/instruction.h
@@ -39,6 +39,7 @@ typedef struct _asm_x86_instr asm_x86_instr;
typedef enum _X86Opcodes
{
X86_OP_ADD_RM8_R8, /* add (0x00) */
+ X86_OP_ADD_RM1632_R1632, /* add ([0x66] 0x01) */
X86_OP_SUB_R1632_RM1632, /* sub ([0x66] 0x29) */
@@ -89,6 +90,9 @@ typedef enum _X86Opcodes
X86_OP_PUSH_IMM1632, /* push ([0x66] 0x68) */
+ X86_OP_JB_REL8, /* jb (0x72) */
+ X86_OP_JNB_REL8, /* jnb (0x73) */
+
X86_OP_JE_8, /* je (0x74) */
X86_OP_JNE_8, /* jne (0x75) */
@@ -116,6 +120,7 @@ typedef enum _X86Opcodes
X86_OP_TEST_RM8_R8, /* test ([0x66] 0x84) */
X86_OP_TEST_RM1632_R1632, /* test ([0x66] 0x85) */
+ X86_OP_MOV_RM8_R8, /* mov (0x88) */
X86_OP_MOV_RM1632_R1632, /* mov ([0x66] 0x89) */
X86_OP_MOV_R1632_RM1632, /* mov ([0x66] 0x8b) */
@@ -141,14 +146,14 @@ typedef enum _X86Opcodes
X86_OP_MOV_E_SI, /* mov ([0x66] 0xbe) */
X86_OP_MOV_E_DI, /* mov ([0x66] 0xbf) */
- X86_OP_ROL_RM1632_IMM8, /* rol ([0x66 0xc1 0) */
- X86_OP_ROR_RM1632_IMM8, /* ror ([0x66 0xc1 1) */
- X86_OP_RCL_RM1632_IMM8, /* rcl ([0x66 0xc1 2) */
- X86_OP_RCR_RM1632_IMM8, /* rcr ([0x66 0xc1 3) */
- X86_OP_SHL_RM1632_IMM8, /* shl ([0x66 0xc1 4) */
- X86_OP_SHR_RM1632_IMM8, /* shr ([0x66 0xc1 5) */
- X86_OP_SAL_RM1632_IMM8, /* sal ([0x66 0xc1 6) */
- X86_OP_SAR_RM1632_IMM8, /* sar ([0x66 0xc1 7) */
+ X86_OP_ROL_RM1632_IMM8, /* rol ([0x66] 0xc1 0) */
+ X86_OP_ROR_RM1632_IMM8, /* ror ([0x66] 0xc1 1) */
+ X86_OP_RCL_RM1632_IMM8, /* rcl ([0x66] 0xc1 2) */
+ X86_OP_RCR_RM1632_IMM8, /* rcr ([0x66] 0xc1 3) */
+ X86_OP_SHL_RM1632_IMM8, /* shl ([0x66] 0xc1 4) */
+ X86_OP_SHR_RM1632_IMM8, /* shr ([0x66] 0xc1 5) */
+ X86_OP_SAL_RM1632_IMM8, /* sal ([0x66] 0xc1 6) */
+ X86_OP_SAR_RM1632_IMM8, /* sar ([0x66] 0xc1 7) */
X86_OP_RET, /* ret (0xc3) */
@@ -159,6 +164,8 @@ typedef enum _X86Opcodes
X86_OP_INT, /* int (0xcd) */
+ X86_OP_SHL_RM1632_CL, /* shl ([0x66] 0xd3 4) */
+
X86_OP_CALL_REL1632, /* call ([0x66] 0xe8) */
X86_OP_JMP_REL1632, /* jmp ([0x66] 0xe9) */
@@ -166,12 +173,18 @@ typedef enum _X86Opcodes
X86_OP_HLT, /* hlt (0xf4) */
+ X86_OP_NOT_RM1632, /* not ([0x66] 0xf7 2) */
+
+ X86_OP_CLD, /* cld (0xfc) */
+
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_MOVZX_R1632_RM8, /* movzx ([0x66] 0x0f 0xb6) */
+ X86_OP_MOVSX_R1632_RM8, /* movsx ([0x66] 0x0f 0xbe) */
+
X86_OP_COUNT
} X86Opcodes;
diff --git a/src/arch/x86/op_add.c b/src/arch/x86/op_add.c
index 42e8d3b..b065617 100644
--- a/src/arch/x86/op_add.c
+++ b/src/arch/x86/op_add.c
@@ -139,3 +139,41 @@ asm_x86_instr *x86_read_instr_add_rm1632_imm1632(const uint8_t *data, off_t *pos
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' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_add_rm1632_r1632(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)++];
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_R1632, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_cld.c b/src/arch/x86/op_cld.c
new file mode 100644
index 0000000..c6d5411
--- /dev/null
+++ b/src/arch/x86/op_cld.c
@@ -0,0 +1,58 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_cld.c - décodage de la suppression du drapeau de direction
+ *
+ * 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"
+
+
+
+/******************************************************************************
+* *
+* 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 'cld'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_cld(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+{
+ asm_x86_instr *result;
+
+ result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
+
+ ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c
index 3739b24..44256e9 100644
--- a/src/arch/x86/op_jump.c
+++ b/src/arch/x86/op_jump.c
@@ -38,6 +38,43 @@
* offset = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
+* Description : Décode une instruction de type 'jb' (saut 8b si inférieur). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_jb_rel8(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)++];
+
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
+ if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, 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 'je' (petit saut). *
* *
* Retour : Instruction mise en place ou NULL. *
@@ -75,6 +112,43 @@ asm_x86_instr *x86_read_instr_je_8(const uint8_t *data, off_t *pos, off_t len, u
* offset = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
+* Description : Décode une instruction de type 'jnb' (saut 8b si !inférieur).*
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_jnb_rel8(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)++];
+
+ ASM_INSTRUCTION(result)->type = AIT_JUMP;
+
+ if (!x86_read_one_operand(result, data, pos, len, X86_OTP_REL8, 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 'jne' (petit saut). *
* *
* Retour : Instruction mise en place ou NULL. *
diff --git a/src/arch/x86/op_mov.c b/src/arch/x86/op_mov.c
index 01e04ff..efa23c4 100644
--- a/src/arch/x86/op_mov.c
+++ b/src/arch/x86/op_mov.c
@@ -392,3 +392,38 @@ asm_x86_instr *x86_read_instr_mov_rm1632_to_r1632(const uint8_t *data, off_t *po
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' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_mov_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_movsx.c b/src/arch/x86/op_movsx.c
new file mode 100644
index 0000000..461309f
--- /dev/null
+++ b/src/arch/x86/op_movsx.c
@@ -0,0 +1,71 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_movsx.c - décodage des copies d'opérandes sans mise à zéro
+ *
+ * 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 'movsx' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_movsx_r1632_rm8(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));
+
+ /* 0x0f : passage en mode 2 octets */
+ (*pos)++;
+
+ oprsize = switch_x86_operand_size_if_needed(proc, data, pos);
+
+ ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM8, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_movzx.c b/src/arch/x86/op_movzx.c
index bb781cf..4df1303 100644
--- a/src/arch/x86/op_movzx.c
+++ b/src/arch/x86/op_movzx.c
@@ -53,6 +53,9 @@ asm_x86_instr *x86_read_instr_movzx_r1632_rm8(const uint8_t *data, off_t *pos, o
result = (asm_x86_instr *)calloc(1, sizeof(asm_x86_instr));
+ /* 0x0f : passage en mode 2 octets */
+ (*pos)++;
+
oprsize = switch_x86_operand_size_if_needed(proc, data, pos);
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
diff --git a/src/arch/x86/op_not.c b/src/arch/x86/op_not.c
new file mode 100644
index 0000000..6deb61c
--- /dev/null
+++ b/src/arch/x86/op_not.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_not.c - décodage des négations par complément à un
+ *
+ * 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 'not' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_not_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)++];
+
+ 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_shl.c b/src/arch/x86/op_shl.c
index 4e2bbba..fbcb0db 100644
--- a/src/arch/x86/op_shl.c
+++ b/src/arch/x86/op_shl.c
@@ -38,6 +38,44 @@
* offset = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
+* Description : Décode une instruction de type 'shl'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_shl_rm1632_cl(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)++];
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_CL, oprsize))
+ {
+ 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 'shl' (8 bits). *
* *
* Retour : Instruction mise en place ou NULL. *
diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h
index 56f5b2f..54398d3 100644
--- a/src/arch/x86/opcodes.h
+++ b/src/arch/x86/opcodes.h
@@ -46,21 +46,27 @@ asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *, off_t *, off_t
/* 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 'add' (16 ou 32 bits). */
+asm_x86_instr *x86_read_instr_add_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'add' (16 ou 32 bits). */
+asm_x86_instr *x86_read_instr_add_rm1632_r1632(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 *);
/* Décode une instruction de type 'and' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_and_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
-/* Décode une instruction de type 'add' (16 ou 32 bits). */
-asm_x86_instr *x86_read_instr_add_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
-
/* Décode une instruction de type 'call'. */
asm_x86_instr *x86_read_instr_call_rel1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'call' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_call_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'cld'. */
+asm_x86_instr *x86_read_instr_cld(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'cmp' (8 bits). */
asm_x86_instr *x86_read_instr_cmp_rm8_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
@@ -85,9 +91,15 @@ asm_x86_instr *x86_read_instr_inc_r1632(const uint8_t *, off_t *, off_t, uint64_
/* Décode une instruction de type 'int'. */
asm_x86_instr *x86_read_instr_int(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'jb' (saut 8b si inférieur). */
+asm_x86_instr *x86_read_instr_jb_rel8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'je' (petit saut). */
asm_x86_instr *x86_read_instr_je_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'jnb' (saut 8b si !inférieur). */
+asm_x86_instr *x86_read_instr_jnb_rel8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'jne' (petit saut). */
asm_x86_instr *x86_read_instr_jne_8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
@@ -133,12 +145,21 @@ asm_x86_instr *x86_read_instr_mov_r1632_to_rm1632(const uint8_t *, off_t *, off_
/* Décode une instruction de type 'mov' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_mov_rm1632_to_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'mov' (8 bits). */
+asm_x86_instr *x86_read_instr_mov_rm8_r8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'movsx' (8 bits). */
+asm_x86_instr *x86_read_instr_movsx_r1632_rm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'movzx' (8 bits). */
asm_x86_instr *x86_read_instr_movzx_r1632_rm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'nop'. */
asm_x86_instr *x86_read_instr_nop(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'not' (16 ou 32 bits). */
+asm_x86_instr *x86_read_instr_not_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'or' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_or_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
@@ -184,6 +205,9 @@ asm_x86_instr *x86_read_instr_sbb_rm1632_with_imm8(const uint8_t *, off_t *, off
/* Décode une instruction de type 'sbb' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_sbb_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'shl'. */
+asm_x86_instr *x86_read_instr_shl_rm1632_cl(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'shl' (8 bits). */
asm_x86_instr *x86_read_instr_shl_rm1632_imm8(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 e13c793..a028dc2 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -1436,6 +1436,10 @@ bool x86_read_one_operand(asm_x86_instr *instr, const uint8_t *data, off_t *pos,
op = x86_create_rm1632_operand(data, pos, len, oprsize == AOS_32_BITS);
break;
+ case X86_OTP_CL:
+ op = x86_create_r8_operand(0x01, true);
+ break;
+
case X86_OTP_AL:
op = x86_create_r8_operand(0x00, true);
break;
@@ -1545,6 +1549,10 @@ bool x86_read_two_operands(asm_x86_instr *instr, const uint8_t *data, off_t *pos
op1 = x86_create_rm1632_operand(data, &op1_pos, len, oprsize == AOS_32_BITS);
break;
+ case X86_OTP_CL:
+ op1 = x86_create_r8_operand(0x01, op1_first);
+ break;
+
case X86_OTP_AL:
op1 = x86_create_r8_operand(0x00, op1_first);
break;
@@ -1616,6 +1624,10 @@ bool x86_read_two_operands(asm_x86_instr *instr, const uint8_t *data, off_t *pos
op2 = x86_create_rm1632_operand(data, &op2_pos, len, oprsize == AOS_32_BITS);
break;
+ case X86_OTP_CL:
+ op2 = x86_create_r8_operand(0x01, op2_first);
+ break;
+
case X86_OTP_AL:
op2 = x86_create_r8_operand(0x00, op2_first);
break;
diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h
index c48a0be..c9ade39 100644
--- a/src/arch/x86/operand.h
+++ b/src/arch/x86/operand.h
@@ -128,6 +128,7 @@ typedef enum _X86OperandType
X86_OTP_RM8 = X86_OTP_RM(1), /* Registre 8 bits ou mémoire */
X86_OTP_RM1632 = X86_OTP_RM(2), /* Registre 16/32b ou mémoire */
+ X86_OTP_CL = 0x0ffd, /* Registre cl */
X86_OTP_AL = 0x0ffe, /* Registre al */
X86_OTP_E_AX = 0x0fff /* Registre eax ou ax */
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c
index 3fde754..8cc3a72 100644
--- a/src/arch/x86/processor.c
+++ b/src/arch/x86/processor.c
@@ -239,6 +239,7 @@ 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, "add", x86_read_instr_add_rm8_r8);
+ register_opcode(proc->opcodes[X86_OP_ADD_RM1632_R1632], 0x01, "add", x86_read_instr_add_rm1632_r1632);
register_opcode_1632(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x29, "sub", x86_read_instr_sub_r1632_from_rm1632);
@@ -289,6 +290,9 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode_1632(proc->opcodes[X86_OP_PUSH_IMM1632], 0x68, "push", x86_read_instr_push_imm1632);
+ register_opcode(proc->opcodes[X86_OP_JB_REL8], 0x72, "jb", x86_read_instr_jb_rel8);
+ register_opcode(proc->opcodes[X86_OP_JNB_REL8], 0x73, "jnb", x86_read_instr_jnb_rel8);
+
register_opcode(proc->opcodes[X86_OP_JE_8], 0x74, "je", x86_read_instr_je_8);
register_opcode(proc->opcodes[X86_OP_JNE_8], 0x75, "jne", x86_read_instr_jne_8);
@@ -316,6 +320,7 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_TEST_RM8_R8], 0x84, "test", x86_read_instr_test_rm8_with_r8);
register_opcode_1632(proc->opcodes[X86_OP_TEST_RM1632_R1632], 0x85, "test", x86_read_instr_test_rm1632_with_r1632);
+ register_opcode(proc->opcodes[X86_OP_MOV_RM8_R8], 0x88, "mov", x86_read_instr_mov_rm8_r8);
register_opcode_1632(proc->opcodes[X86_OP_MOV_RM1632_R1632], 0x89, "mov", x86_read_instr_mov_r1632_to_rm1632);
register_opcode_1632(proc->opcodes[X86_OP_MOV_R1632_RM1632], 0x8b, "mov", x86_read_instr_mov_rm1632_to_r1632);
@@ -359,6 +364,7 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_INT], 0xcd, "int", x86_read_instr_int);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_SHL_RM1632_CL], 0xd3, 4, "shl", x86_read_instr_shl_rm1632_cl);
register_opcode_1632(proc->opcodes[X86_OP_CALL_REL1632], 0xe8, "call", x86_read_instr_call_rel1632);
register_opcode_1632(proc->opcodes[X86_OP_JMP_REL1632], 0xe9, "jmp", x86_read_instr_jmp_rel1632);
@@ -367,11 +373,17 @@ void x86_register_instructions(asm_x86_processor *proc)
register_opcode(proc->opcodes[X86_OP_HLT], 0xf4, "hlt", x86_read_instr_hlt);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_NOT_RM1632], 0xf7, 7, "not", x86_read_instr_not_rm1632);
+
+ register_opcode(proc->opcodes[X86_OP_CLD], 0xfc, "cld", x86_read_instr_cld);
+
register_opcode_1632_with_ext(proc->opcodes[X86_OP_CALL_RM1632], 0xff, 2, "call", x86_read_instr_call_rm1632);
register_opcode_1632_with_ext(proc->opcodes[X86_OP_JMP_RM1632], 0xff, 4, "jmp", x86_read_instr_jmp_rm1632);
register_opcode_1632_with_ext(proc->opcodes[X86_OP_PUSH_RM1632], 0xff, 6, "push", x86_read_instr_push_rm1632);
- //register_2b_opcode_1632(proc->opcodes[X86_OP_MOVZX_R1632_RM8], 0xb6, "movzx", x86_read_instr_movzx_r1632_rm8);
+ register_2b_opcode_1632(proc->opcodes[X86_OP_MOVZX_R1632_RM8], 0xb6, "movzx", x86_read_instr_movzx_r1632_rm8);
+
+ register_2b_opcode_1632(proc->opcodes[X86_OP_MOVSX_R1632_RM8], 0xbe, "movsx", x86_read_instr_movsx_r1632_rm8);
}
@@ -398,33 +410,32 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d
{
asm_x86_instr *result; /* Résultat à faire remonter */
X86Prefix prefix; /* Préfixe détecté */
+ off_t k; /* Itération sur le contenu */
X86Opcodes i; /* Boucle de parcours */
result = NULL;
prefix = X86_PRE_NONE;
- consume_prefix:
-
- switch (data[*pos])
- {
- case 0x66:
- prefix |= X86_PRE_OPSIZE;
- (*pos)++;
- break;
+ for (k = *pos; k < len; k++)
+ switch (data[k])
+ {
+ case 0x66:
+ prefix |= X86_PRE_OPSIZE;
+ break;
- case 0x0f:
- prefix |= X86_PRE_ESCAPE;
- (*pos)++;
- break;
+ case 0x0f:
+ prefix |= X86_PRE_ESCAPE;
+ break;
- default:
- goto found_instr;
- break;
+ default:
+ goto found_instr;
+ break;
- }
+ }
- goto consume_prefix;
+ /* Contenu binaire tronqué */
+ return NULL;
found_instr:
@@ -432,7 +443,7 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d
{
if ((prefix & proc->opcodes[i].prefix) != prefix) continue;
- if (data[*pos] != proc->opcodes[i].opcode) continue;
+ if (data[k] != proc->opcodes[i].opcode) continue;
result = proc->opcodes[i].read(data, pos, len, offset, proc);
if (result != NULL) result->type = i;