summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2008-10-26 23:37:51 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2008-10-26 23:37:51 (GMT)
commit197933fdf469ab9b8897b33c51809c128f1e3c03 (patch)
tree104d91be1a69d80eb4b59b247e4b719531bc7492
parentac438e8ad47f267c9eb6f462eb5a7e2b5c017f26 (diff)
Completed support of the 0x81 and 0xc1 opcodes.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@37 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog48
-rw-r--r--src/arch/processor.c5
-rw-r--r--src/arch/x86/Makefile.am7
-rw-r--r--src/arch/x86/instruction.h28
-rw-r--r--src/arch/x86/op_adc.c38
-rw-r--r--src/arch/x86/op_add.c18
-rw-r--r--src/arch/x86/op_and.c38
-rw-r--r--src/arch/x86/op_cmp.c38
-rw-r--r--src/arch/x86/op_movzx.c68
-rw-r--r--src/arch/x86/op_or.c38
-rw-r--r--src/arch/x86/op_rcl.c68
-rw-r--r--src/arch/x86/op_rcr.c68
-rw-r--r--src/arch/x86/op_rol.c68
-rw-r--r--src/arch/x86/op_ror.c68
-rw-r--r--src/arch/x86/op_sar.c4
-rw-r--r--src/arch/x86/op_sbb.c38
-rw-r--r--src/arch/x86/op_shl.c68
-rw-r--r--src/arch/x86/op_shr.c68
-rw-r--r--src/arch/x86/op_sub.c38
-rw-r--r--src/arch/x86/op_xor.c40
-rw-r--r--src/arch/x86/opcodes.h56
-rw-r--r--src/arch/x86/processor.c346
22 files changed, 1063 insertions, 193 deletions
diff --git a/ChangeLog b/ChangeLog
index 701100a..c251af9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+2008-10-27 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/arch/processor.c:
+ Take care here of decoding failures.
+
+ * src/arch/x86/instruction.h:
+ Register some new instructions.
+
+ * src/arch/x86/Makefile.am:
+ Add op_movzx.c, op_rcl.c, op_rcr.c, op_rol.c, op_ror.c, op_shl.c and
+ op_shr.c to libarchx86_a_SOURCES.
+
+ * src/arch/x86/op_adc.c:
+ * src/arch/x86/op_add.c:
+ * src/arch/x86/op_and.c:
+ * src/arch/x86/op_cmp.c:
+ Complete support of the 0x81 and 0xc1 opcodes.
+
+ * src/arch/x86/opcodes.h:
+ Register some new instructions.
+
+ * src/arch/x86/op_movzx.c:
+ First attempt to handle a two-byte instruction.
+
+ * src/arch/x86/op_or.c:
+ Complete support of the 0x81 and 0xc1 opcodes.
+
+ * src/arch/x86/op_rcl.c:
+ * src/arch/x86/op_rcr.c:
+ * src/arch/x86/op_rol.c:
+ * src/arch/x86/op_ror.c:
+ New entries: complete support of the 0x81 and 0xc1 opcodes.
+
+ * src/arch/x86/op_sar.c:
+ * src/arch/x86/op_sbb.c:
+ Complete support of the 0x81 and 0xc1 opcodes.
+
+ * src/arch/x86/op_shl.c:
+ * src/arch/x86/op_shr.c:
+ New entries: complete support of the 0x81 and 0xc1 opcodes.
+
+ * src/arch/x86/op_sub.c:
+ * src/arch/x86/op_xor.c:
+ Complete support of the 0x81 and 0xc1 opcodes.
+
+ * src/arch/x86/processor.c:
+ Better handle prefixes. Complete support of the 0x81 and 0xc1 opcodes.
+
2008-10-21 Cyrille Bagard <nocbos@gmail.com>
* src/arch/x86/processor.c:
diff --git a/src/arch/processor.c b/src/arch/processor.c
index fc9f773..1afb576 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -52,8 +52,11 @@ asm_instr *decode_instruction(const asm_processor *proc, const uint8_t *data, of
{
asm_instr *result; /* Représentation à renvoyer */
+ off_t old_pos; /* Sauvegarde de la position */
+ old_pos = *pos;
+
result = proc->fetch_instr(proc, data, pos, len, offset);
@@ -63,6 +66,8 @@ asm_instr *decode_instruction(const asm_processor *proc, const uint8_t *data, of
if (result == NULL)
{
+ *pos = old_pos;
+
printf("err while decoding opcode 0x%0hhx at 0x%08llx\n", data[*pos], offset);
result = create_db_instruction(data, pos, len);
}
diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am
index 139bcde..58ffaa8 100644
--- a/src/arch/x86/Makefile.am
+++ b/src/arch/x86/Makefile.am
@@ -17,12 +17,19 @@ libarchx86_a_SOURCES = \
op_leave.c \
op_nop.c \
op_mov.c \
+ op_movzx.c \
op_or.c \
op_pop.c \
op_push.c \
+ op_rcl.c \
+ op_rcr.c \
op_ret.c \
+ op_rol.c \
+ op_ror.c \
op_sar.c \
op_sbb.c \
+ op_shl.c \
+ op_shr.c \
op_sub.c \
op_test.c \
op_xor.c \
diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h
index baf911d..1c97255 100644
--- a/src/arch/x86/instruction.h
+++ b/src/arch/x86/instruction.h
@@ -92,11 +92,17 @@ typedef enum _X86Opcodes
X86_OP_JE_8, /* je (0x74) */
X86_OP_JNE_8, /* jne (0x75) */
- X86_OP_XOR_RM8_IMM8, /* xor (0x81 6) */
+ X86_OP_XOR_RM8_IMM8, /* xor (0x80 6) */
X86_OP_CMP_RM8_IMM8, /* cmp (0x80 7) */
- X86_OP_ADD_RM1632_IMM1632, /* add ([0x66] 0x81 0) */
+ X86_OP_ADD_RM1632_IMM1632, /* add ([0x66] 0x81 0) */
+ X86_OP_OR_RM1632_IMM1632, /* or ([0x66] 0x81 1) */
+ X86_OP_ADC_RM1632_IMM1632, /* adc ([0x66] 0x81 2) */
+ X86_OP_SBB_RM1632_IMM1632, /* sbb ([0x66] 0x81 3) */
+ X86_OP_AND_RM1632_IMM1632, /* and ([0x66] 0x81 4) */
+ X86_OP_SUB_RM1632_IMM1632, /* sub ([0x66] 0x81 5) */
X86_OP_XOR_RM1632_IMM1632, /* xor ([0x66] 0x81 6) */
+ X86_OP_CMP_RM1632_IMM1632, /* xor ([0x66] 0x81 7) */
X86_OP_ADD_RM1632_IMM8, /* add ([0x66] 0x83 0) */
X86_OP_OR_RM1632_IMM8, /* or ([0x66] 0x83 1) */
@@ -135,6 +141,13 @@ 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_RET, /* ret (0xc3) */
@@ -157,6 +170,8 @@ typedef enum _X86Opcodes
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_COUNT
} X86Opcodes;
@@ -167,11 +182,16 @@ typedef enum _X86Opcodes
/* Eventuel préfixe rencontré */
typedef enum _X86Prefix
{
- X86_PRE_NONE = 0, /* Aucun préfixe */
+ X86_PRE_NONE = (0 << 0), /* Aucun préfixe */
+
+
+ /* Groupe 3 */
+ X86_PRE_OPSIZE = (1 << 1), /* Basculement des opérandes */
- X86_PRE_OPSIZE /* Basculement des opérandes */
+ /* Autres */
+ X86_PRE_ESCAPE = (1 << 3) /* Opcode sur deux octets */
} X86Prefix;
diff --git a/src/arch/x86/op_adc.c b/src/arch/x86/op_adc.c
index 8927607..7ac80f3 100644
--- a/src/arch/x86/op_adc.c
+++ b/src/arch/x86/op_adc.c
@@ -66,3 +66,41 @@ asm_x86_instr *x86_read_instr_adc_imm8_to_rm1632(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 'adc' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_adc_rm1632_imm1632(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_IMM1632, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_add.c b/src/arch/x86/op_add.c
index f42c8f9..42e8d3b 100644
--- a/src/arch/x86/op_add.c
+++ b/src/arch/x86/op_add.c
@@ -76,7 +76,7 @@ asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *data, off_t *pos
* 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). *
+* Description : Décode une instruction de type 'add' (8 bits). *
* *
* Retour : Instruction mise en place ou NULL. *
* *
@@ -84,18 +84,15 @@ asm_x86_instr *x86_read_instr_add_imm8_to_rm1632(const uint8_t *data, off_t *pos
* *
******************************************************************************/
-asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+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 */
- 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_IMM1632, oprsize))
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8))
{
free(result);
return NULL;
@@ -114,7 +111,7 @@ asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *data, off_t *
* offset = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
-* Description : Décode une instruction de type 'add' (8 bits). *
+* Description : Décode une instruction de type 'add' (16 ou 32 bits). *
* *
* Retour : Instruction mise en place ou NULL. *
* *
@@ -122,15 +119,18 @@ asm_x86_instr *x86_read_instr_add_imm1632_to_rm1632(const uint8_t *data, off_t *
* *
******************************************************************************/
-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 *x86_read_instr_add_rm1632_imm1632(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_RM8, X86_OTP_R8))
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize))
{
free(result);
return NULL;
diff --git a/src/arch/x86/op_and.c b/src/arch/x86/op_and.c
index 3e3ba26..2d877a6 100644
--- a/src/arch/x86/op_and.c
+++ b/src/arch/x86/op_and.c
@@ -66,3 +66,41 @@ asm_x86_instr *x86_read_instr_and_rm1632_with_imm8(const uint8_t *data, off_t *p
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 'and' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_and_rm1632_imm1632(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_IMM1632, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_cmp.c b/src/arch/x86/op_cmp.c
index 5afd794..95e1347 100644
--- a/src/arch/x86/op_cmp.c
+++ b/src/arch/x86/op_cmp.c
@@ -119,6 +119,44 @@ asm_x86_instr *x86_read_instr_cmp_rm1632_with_imm8(const uint8_t *data, off_t *p
* *
******************************************************************************/
+asm_x86_instr *x86_read_instr_cmp_rm1632_imm1632(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_IMM1632, 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 'cmp' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
asm_x86_instr *x86_read_instr_cmp_rm1632_with_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 */
diff --git a/src/arch/x86/op_movzx.c b/src/arch/x86/op_movzx.c
new file mode 100644
index 0000000..bb781cf
--- /dev/null
+++ b/src/arch/x86/op_movzx.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_movzx.c - décodage des copies d'opérandes avec 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 'movzx' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_movzx_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));
+
+ 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_or.c b/src/arch/x86/op_or.c
index 0dd7cf3..42fcfe5 100644
--- a/src/arch/x86/op_or.c
+++ b/src/arch/x86/op_or.c
@@ -66,3 +66,41 @@ asm_x86_instr *x86_read_instr_or_rm1632_with_imm8(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 'or' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_or_rm1632_imm1632(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_IMM1632, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_rcl.c b/src/arch/x86/op_rcl.c
new file mode 100644
index 0000000..ab0fd05
--- /dev/null
+++ b/src/arch/x86/op_rcl.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_rcl.c - décodage des rotations à gauche avec retenue
+ *
+ * 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 'rcl' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_rcl_rm1632_imm8(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_IMM8, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_rcr.c b/src/arch/x86/op_rcr.c
new file mode 100644
index 0000000..78807f9
--- /dev/null
+++ b/src/arch/x86/op_rcr.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_rcr.c - décodage des rotations à droite avec retenue
+ *
+ * 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 'rcr' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_rcr_rm1632_imm8(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_IMM8, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_rol.c b/src/arch/x86/op_rol.c
new file mode 100644
index 0000000..047f7cd
--- /dev/null
+++ b/src/arch/x86/op_rol.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_rol.c - décodage des rotations à gauche sans retenue
+ *
+ * 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 'rol' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_rol_rm1632_imm8(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_IMM8, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_ror.c b/src/arch/x86/op_ror.c
new file mode 100644
index 0000000..5dca287
--- /dev/null
+++ b/src/arch/x86/op_ror.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_ror.c - décodage des rotations à droite sans retenue
+ *
+ * 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 'ror' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_ror_rm1632_imm8(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_IMM8, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_sar.c b/src/arch/x86/op_sar.c
index 70b57c9..5e82cd8 100644
--- a/src/arch/x86/op_sar.c
+++ b/src/arch/x86/op_sar.c
@@ -1,6 +1,6 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
- * op_cmp.c - décodage des comparaisons d'opérandes
+ * op_sar.c - décodage des décallages arithmetiques à droite
*
* Copyright (C) 2008 Cyrille Bagard
*
@@ -46,7 +46,7 @@
* *
******************************************************************************/
-asm_x86_instr *x86_read_instr_sar_rm1632_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+asm_x86_instr *x86_read_instr_sar_rm1632_imm8(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 */
diff --git a/src/arch/x86/op_sbb.c b/src/arch/x86/op_sbb.c
index eba4e04..20619cc 100644
--- a/src/arch/x86/op_sbb.c
+++ b/src/arch/x86/op_sbb.c
@@ -66,3 +66,41 @@ asm_x86_instr *x86_read_instr_sbb_rm1632_with_imm8(const uint8_t *data, off_t *p
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 'sbb' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_sbb_rm1632_imm1632(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_IMM1632, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_shl.c b/src/arch/x86/op_shl.c
new file mode 100644
index 0000000..4e2bbba
--- /dev/null
+++ b/src/arch/x86/op_shl.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_shl.c - décodage des décallages logiques à gauche
+ *
+ * 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 'shl' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_shl_rm1632_imm8(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_IMM8, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_shr.c b/src/arch/x86/op_shr.c
new file mode 100644
index 0000000..0ba8c4e
--- /dev/null
+++ b/src/arch/x86/op_shr.c
@@ -0,0 +1,68 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_shr.c - décodage des décallages logiques à droite
+ *
+ * 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 'shr' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_shr_rm1632_imm8(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_IMM8, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_sub.c b/src/arch/x86/op_sub.c
index 7c282cc..6978a26 100644
--- a/src/arch/x86/op_sub.c
+++ b/src/arch/x86/op_sub.c
@@ -104,3 +104,41 @@ asm_x86_instr *x86_read_instr_sub_r1632_from_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 'sub' (16 ou 32 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+asm_x86_instr *x86_read_instr_sub_rm1632_imm1632(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_IMM1632, oprsize))
+ {
+ free(result);
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_xor.c b/src/arch/x86/op_xor.c
index 8d44f9c..eabb88e 100644
--- a/src/arch/x86/op_xor.c
+++ b/src/arch/x86/op_xor.c
@@ -149,7 +149,7 @@ asm_x86_instr *x86_read_instr_xor_rm8_with_imm8(const uint8_t *data, off_t *pos,
* offset = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
-* Description : Décode une instruction de type 'xor' (16 ou 32 bits). *
+* Description : Décode une instruction de type 'xor' (8 bits). *
* *
* Retour : Instruction mise en place ou NULL. *
* *
@@ -157,18 +157,15 @@ asm_x86_instr *x86_read_instr_xor_rm8_with_imm8(const uint8_t *data, off_t *pos,
* *
******************************************************************************/
-asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+asm_x86_instr *x86_read_instr_xor_r8_with_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));
- 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_IMM1632, oprsize))
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R8, X86_OTP_RM8))
{
free(result);
return NULL;
@@ -187,7 +184,7 @@ asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *data, off_t
* offset = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
-* Description : Décode une instruction de type 'xor' (8 bits). *
+* Description : Décode une instruction de type 'xor' (16 ou 32 bits). *
* *
* Retour : Instruction mise en place ou NULL. *
* *
@@ -195,15 +192,18 @@ asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *data, off_t
* *
******************************************************************************/
-asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+asm_x86_instr *x86_read_instr_xor_r1632_with_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_two_operands(result, data, pos, len, X86_OTP_R8, X86_OTP_RM8))
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_R1632, X86_OTP_RM1632, oprsize))
{
free(result);
return NULL;
@@ -222,7 +222,7 @@ asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *data, off_t *pos, o
* offset = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
-* Description : Décode une instruction de type 'xor' (16 ou 32 bits). *
+* Description : Décode une instruction de type 'xor' (8 bits). *
* *
* Retour : Instruction mise en place ou NULL. *
* *
@@ -230,18 +230,15 @@ asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *data, off_t *pos, o
* *
******************************************************************************/
-asm_x86_instr *x86_read_instr_xor_r1632_with_rm1632(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+asm_x86_instr *x86_read_instr_xor_rm8_with_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 */
- 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_R1632, X86_OTP_RM1632, oprsize))
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM8, X86_OTP_R8))
{
free(result);
return NULL;
@@ -260,7 +257,7 @@ asm_x86_instr *x86_read_instr_xor_r1632_with_rm1632(const uint8_t *data, off_t *
* offset = adresse virtuelle de l'instruction. *
* proc = architecture ciblée par le désassemblage. *
* *
-* Description : Décode une instruction de type 'xor' (8 bits). *
+* Description : Décode une instruction de type 'xor' (16 ou 32 bits). *
* *
* Retour : Instruction mise en place ou NULL. *
* *
@@ -268,15 +265,18 @@ asm_x86_instr *x86_read_instr_xor_r1632_with_rm1632(const uint8_t *data, off_t *
* *
******************************************************************************/
-asm_x86_instr *x86_read_instr_xor_rm8_with_r8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(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_RM8, X86_OTP_R8))
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize))
{
free(result);
return NULL;
@@ -303,7 +303,7 @@ asm_x86_instr *x86_read_instr_xor_rm8_with_r8(const uint8_t *data, off_t *pos, o
* *
******************************************************************************/
-asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(const uint8_t *data, off_t *pos, off_t len, uint64_t offset, const asm_x86_processor *proc)
+asm_x86_instr *x86_read_instr_xor_rm1632_imm1632(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 */
@@ -314,7 +314,7 @@ asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(const uint8_t *data, off_t *p
ASM_INSTRUCTION(result)->opcode = data[(*pos)++];
- if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM8, oprsize))
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_RM1632, X86_OTP_IMM1632, oprsize))
{
free(result);
return NULL;
diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h
index 70d41b8..56f5b2f 100644
--- a/src/arch/x86/opcodes.h
+++ b/src/arch/x86/opcodes.h
@@ -37,11 +37,11 @@
/* Décode une instruction de type 'adc' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_adc_imm8_to_rm1632(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_imm8_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'adc' (16 ou 32 bits). */
+asm_x86_instr *x86_read_instr_adc_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_imm1632_to_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+asm_x86_instr *x86_read_instr_add_imm8_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 *);
@@ -49,6 +49,12 @@ asm_x86_instr *x86_read_instr_add_rm8_r8(const uint8_t *, off_t *, off_t, uint64
/* 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 *);
@@ -62,6 +68,9 @@ asm_x86_instr *x86_read_instr_cmp_rm8_with_imm8(const uint8_t *, off_t *, off_t,
asm_x86_instr *x86_read_instr_cmp_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'cmp' (16 ou 32 bits). */
+asm_x86_instr *x86_read_instr_cmp_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'cmp' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_cmp_rm1632_with_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'dec'. */
@@ -124,12 +133,18 @@ 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 '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 '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 *);
+/* Décode une instruction de type 'or' (16 ou 32 bits). */
+asm_x86_instr *x86_read_instr_or_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'pop' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_pop_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
@@ -142,21 +157,48 @@ asm_x86_instr *x86_read_instr_push_r1632(const uint8_t *, off_t *, off_t, uint64
/* Décode une instruction de type 'push' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_push_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'rcl' (8 bits). */
+asm_x86_instr *x86_read_instr_rcl_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'rcr' (8 bits). */
+asm_x86_instr *x86_read_instr_rcr_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'ret'. */
asm_x86_instr *x86_read_instr_ret(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'rol' (8 bits). */
+asm_x86_instr *x86_read_instr_rol_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'ror' (8 bits). */
+asm_x86_instr *x86_read_instr_ror_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'sal' (8 bits). */
+#define x86_read_instr_sal_rm1632_imm8 x86_read_instr_shl_rm1632_imm8
+
/* Décode une instruction de type 'sar' (8 bits). */
-asm_x86_instr *x86_read_instr_sar_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+asm_x86_instr *x86_read_instr_sar_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'sbb'. */
asm_x86_instr *x86_read_instr_sbb_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* 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' (8 bits). */
+asm_x86_instr *x86_read_instr_shl_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'shr' (8 bits). */
+asm_x86_instr *x86_read_instr_shr_rm1632_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'sub'. */
asm_x86_instr *x86_read_instr_sub_imm8_from_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'sub' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_sub_r1632_from_rm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+/* Décode une instruction de type 'sub' (16 ou 32 bits). */
+asm_x86_instr *x86_read_instr_sub_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
/* Décode une instruction de type 'test al, ...' (8 bits). */
asm_x86_instr *x86_read_instr_test_al(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
@@ -178,9 +220,6 @@ asm_x86_instr *x86_read_instr_xor_e_ax_with_imm1632(const uint8_t *, off_t *, of
/* Décode une instruction de type 'xor' (8 bits). */
asm_x86_instr *x86_read_instr_xor_rm8_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
-/* Décode une instruction de type 'xor' (16 ou 32 bits). */
-asm_x86_instr *x86_read_instr_xor_rm1632_with_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
-
/* Décode une instruction de type 'xor' (8 bits). */
asm_x86_instr *x86_read_instr_xor_r8_with_rm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
@@ -194,6 +233,9 @@ asm_x86_instr *x86_read_instr_xor_rm8_with_r8(const uint8_t *, off_t *, off_t, u
asm_x86_instr *x86_read_instr_xor_rm1632_with_imm8(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
/* Décode une instruction de type 'xor' (16 ou 32 bits). */
+asm_x86_instr *x86_read_instr_xor_rm1632_imm1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
+
+/* Décode une instruction de type 'xor' (16 ou 32 bits). */
asm_x86_instr *x86_read_instr_xor_rm1632_with_r1632(const uint8_t *, off_t *, off_t, uint64_t, const asm_x86_processor *);
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c
index 14f35bc..3fde754 100644
--- a/src/arch/x86/processor.c
+++ b/src/arch/x86/processor.c
@@ -41,11 +41,10 @@ typedef asm_x86_instr * (* read_instr) (const uint8_t *, off_t *, off_t, uint64_
/* Carte d'identité d'un opcode */
typedef struct _x86_opcode
{
- uint8_t prefix; /* préfixe eventuel */
+ X86Prefix prefix; /* Préfixe(s) eventuel(s) */
uint8_t opcode; /* Opcode seul */
uint8_t op_ext; /* Extension de l'opcode */
- bool opt_prefix; /* Préfixe optionnel ? */
bool has_op_ext; /* Ext. à prendre en compte ? */
const char *name; /* Désignation humaine */
@@ -57,27 +56,61 @@ typedef struct _x86_opcode
#define EXT_OPCODE_MASK 0x38
-#define register_opcode(target, _prefix, _opcode, _name, _read) \
+
+
+
+#define register_opcode(target, _opcode, _name, _read) \
+ do { \
+ target.prefix = X86_PRE_NONE; \
+ target.opcode = _opcode; \
+ target.has_op_ext = false; \
+ target.name = _name; \
+ target.read = _read; \
+ } while (0)
+
+#define register_opcode_1632(target, _opcode, _name, _read) \
do { \
- target.prefix = _prefix; \
+ target.prefix = X86_PRE_OPSIZE; \
target.opcode = _opcode; \
- target.opt_prefix = (_prefix != 0x00); \
target.has_op_ext = false; \
target.name = _name; \
target.read = _read; \
} while (0)
-#define register_opcode_with_ext(target, _prefix, _opcode, _ext, _name, _read) \
+#define register_opcode_with_ext(target, _opcode, _ext, _name, _read) \
do { \
- target.prefix = _prefix; \
+ target.prefix = X86_PRE_NONE; \
target.opcode = _opcode; \
target.op_ext = _ext << 3; \
- target.opt_prefix = (_prefix != 0x00); \
target.has_op_ext = true; \
target.name = _name; \
target.read = _read; \
} while (0)
+#define register_opcode_1632_with_ext(target, _opcode, _ext, _name, _read) \
+ do { \
+ target.prefix = X86_PRE_OPSIZE; \
+ target.opcode = _opcode; \
+ target.op_ext = _ext << 3; \
+ target.has_op_ext = true; \
+ target.name = _name; \
+ target.read = _read; \
+ } while (0)
+
+#define register_2b_opcode_1632(target, _opcode, _name, _read) \
+ do { \
+ target.prefix = X86_PRE_ESCAPE | X86_PRE_OPSIZE; \
+ target.opcode = _opcode; \
+ target.has_op_ext = false; \
+ target.name = _name; \
+ target.read = _read; \
+ } while (0)
+
+
+
+
+
+
@@ -205,127 +238,140 @@ 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);
- register_opcode(proc->opcodes[X86_OP_XOR_RM1632_R1632], 0x66, 0x31, "xor", x86_read_instr_xor_rm1632_with_r1632);
- register_opcode(proc->opcodes[X86_OP_XOR_R8_RM8], 0x00, 0x32, "xor", x86_read_instr_xor_r8_with_rm8);
- register_opcode(proc->opcodes[X86_OP_XOR_R1632_RM1632], 0x66, 0x33, "xor", x86_read_instr_xor_r1632_with_rm1632);
- register_opcode(proc->opcodes[X86_OP_XOR_AL_IMM8], 0x00, 0x34, "xor", x86_read_instr_xor_al_with_imm8);
- register_opcode(proc->opcodes[X86_OP_XOR_E_AX_IMM1632], 0x66, 0x35, "xor", x86_read_instr_xor_e_ax_with_imm1632);
-
- register_opcode(proc->opcodes[X86_OP_CMP_RM1632_R1632], 0x66, 0x39, "cmp", x86_read_instr_cmp_rm1632_with_r1632);
-
- register_opcode(proc->opcodes[X86_OP_INC_E_AX], 0x66, 0x40, "inc", x86_read_instr_inc_r1632);
- register_opcode(proc->opcodes[X86_OP_INC_E_CX], 0x66, 0x41, "inc", x86_read_instr_inc_r1632);
- register_opcode(proc->opcodes[X86_OP_INC_E_DX], 0x66, 0x42, "inc", x86_read_instr_inc_r1632);
- register_opcode(proc->opcodes[X86_OP_INC_E_BX], 0x66, 0x43, "inc", x86_read_instr_inc_r1632);
- register_opcode(proc->opcodes[X86_OP_INC_E_SP], 0x66, 0x44, "inc", x86_read_instr_inc_r1632);
- register_opcode(proc->opcodes[X86_OP_INC_E_BP], 0x66, 0x45, "inc", x86_read_instr_inc_r1632);
- register_opcode(proc->opcodes[X86_OP_INC_E_SI], 0x66, 0x46, "inc", x86_read_instr_inc_r1632);
- register_opcode(proc->opcodes[X86_OP_INC_E_DI], 0x66, 0x47, "inc", x86_read_instr_inc_r1632);
-
- register_opcode(proc->opcodes[X86_OP_DEC_E_AX], 0x66, 0x48, "dec", x86_read_instr_dec_r1632);
- register_opcode(proc->opcodes[X86_OP_DEC_E_CX], 0x66, 0x49, "dec", x86_read_instr_dec_r1632);
- register_opcode(proc->opcodes[X86_OP_DEC_E_DX], 0x66, 0x4a, "dec", x86_read_instr_dec_r1632);
- register_opcode(proc->opcodes[X86_OP_DEC_E_BX], 0x66, 0x4b, "dec", x86_read_instr_dec_r1632);
- register_opcode(proc->opcodes[X86_OP_DEC_E_SP], 0x66, 0x4c, "dec", x86_read_instr_dec_r1632);
- register_opcode(proc->opcodes[X86_OP_DEC_E_BP], 0x66, 0x4d, "dec", x86_read_instr_dec_r1632);
- register_opcode(proc->opcodes[X86_OP_DEC_E_SI], 0x66, 0x4e, "dec", x86_read_instr_dec_r1632);
- register_opcode(proc->opcodes[X86_OP_DEC_E_DI], 0x66, 0x4f, "dec", x86_read_instr_dec_r1632);
-
- register_opcode(proc->opcodes[X86_OP_PUSH_E_AX], 0x66, 0x50, "push", x86_read_instr_push_r1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_E_CX], 0x66, 0x51, "push", x86_read_instr_push_r1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_E_DX], 0x66, 0x52, "push", x86_read_instr_push_r1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_E_BX], 0x66, 0x53, "push", x86_read_instr_push_r1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_E_SP], 0x66, 0x54, "push", x86_read_instr_push_r1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_E_BP], 0x66, 0x55, "push", x86_read_instr_push_r1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_E_SI], 0x66, 0x56, "push", x86_read_instr_push_r1632);
- register_opcode(proc->opcodes[X86_OP_PUSH_E_DI], 0x66, 0x57, "push", x86_read_instr_push_r1632);
-
- register_opcode(proc->opcodes[X86_OP_POP_E_AX], 0x66, 0x58, "pop", x86_read_instr_pop_r1632);
- register_opcode(proc->opcodes[X86_OP_POP_E_CX], 0x66, 0x59, "pop", x86_read_instr_pop_r1632);
- register_opcode(proc->opcodes[X86_OP_POP_E_DX], 0x66, 0x5a, "pop", x86_read_instr_pop_r1632);
- register_opcode(proc->opcodes[X86_OP_POP_E_BX], 0x66, 0x5b, "pop", x86_read_instr_pop_r1632);
- register_opcode(proc->opcodes[X86_OP_POP_E_SP], 0x66, 0x5c, "pop", x86_read_instr_pop_r1632);
- register_opcode(proc->opcodes[X86_OP_POP_E_BP], 0x66, 0x5d, "pop", x86_read_instr_pop_r1632);
- register_opcode(proc->opcodes[X86_OP_POP_E_SI], 0x66, 0x5e, "pop", x86_read_instr_pop_r1632);
- register_opcode(proc->opcodes[X86_OP_POP_E_DI], 0x66, 0x5f, "pop", x86_read_instr_pop_r1632);
+ register_opcode(proc->opcodes[X86_OP_ADD_RM8_R8], 0x00, "add", x86_read_instr_add_rm8_r8);
+
+ register_opcode_1632(proc->opcodes[X86_OP_SUB_R1632_RM1632], 0x29, "sub", x86_read_instr_sub_r1632_from_rm1632);
+
+ register_opcode(proc->opcodes[X86_OP_XOR_RM8_R8], 0x30, "xor", x86_read_instr_xor_rm8_with_r8);
+ register_opcode_1632(proc->opcodes[X86_OP_XOR_RM1632_R1632], 0x31, "xor", x86_read_instr_xor_rm1632_with_r1632);
+ register_opcode(proc->opcodes[X86_OP_XOR_R8_RM8], 0x32, "xor", x86_read_instr_xor_r8_with_rm8);
+ register_opcode_1632(proc->opcodes[X86_OP_XOR_R1632_RM1632], 0x33, "xor", x86_read_instr_xor_r1632_with_rm1632);
+ register_opcode(proc->opcodes[X86_OP_XOR_AL_IMM8], 0x34, "xor", x86_read_instr_xor_al_with_imm8);
+ register_opcode_1632(proc->opcodes[X86_OP_XOR_E_AX_IMM1632], 0x35, "xor", x86_read_instr_xor_e_ax_with_imm1632);
+
+ register_opcode_1632(proc->opcodes[X86_OP_CMP_RM1632_R1632], 0x39, "cmp", x86_read_instr_cmp_rm1632_with_r1632);
+
+ register_opcode_1632(proc->opcodes[X86_OP_INC_E_AX], 0x40, "inc", x86_read_instr_inc_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_INC_E_CX], 0x41, "inc", x86_read_instr_inc_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_INC_E_DX], 0x42, "inc", x86_read_instr_inc_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_INC_E_BX], 0x43, "inc", x86_read_instr_inc_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_INC_E_SP], 0x44, "inc", x86_read_instr_inc_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_INC_E_BP], 0x45, "inc", x86_read_instr_inc_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_INC_E_SI], 0x46, "inc", x86_read_instr_inc_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_INC_E_DI], 0x47, "inc", x86_read_instr_inc_r1632);
+
+ register_opcode_1632(proc->opcodes[X86_OP_DEC_E_AX], 0x48, "dec", x86_read_instr_dec_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_DEC_E_CX], 0x49, "dec", x86_read_instr_dec_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_DEC_E_DX], 0x4a, "dec", x86_read_instr_dec_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_DEC_E_BX], 0x4b, "dec", x86_read_instr_dec_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_DEC_E_SP], 0x4c, "dec", x86_read_instr_dec_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_DEC_E_BP], 0x4d, "dec", x86_read_instr_dec_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_DEC_E_SI], 0x4e, "dec", x86_read_instr_dec_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_DEC_E_DI], 0x4f, "dec", x86_read_instr_dec_r1632);
+
+ register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_AX], 0x50, "push", x86_read_instr_push_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_CX], 0x51, "push", x86_read_instr_push_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_DX], 0x52, "push", x86_read_instr_push_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_BX], 0x53, "push", x86_read_instr_push_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_SP], 0x54, "push", x86_read_instr_push_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_BP], 0x55, "push", x86_read_instr_push_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_SI], 0x56, "push", x86_read_instr_push_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_PUSH_E_DI], 0x57, "push", x86_read_instr_push_r1632);
+
+ register_opcode_1632(proc->opcodes[X86_OP_POP_E_AX], 0x58, "pop", x86_read_instr_pop_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_POP_E_CX], 0x59, "pop", x86_read_instr_pop_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_POP_E_DX], 0x5a, "pop", x86_read_instr_pop_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_POP_E_BX], 0x5b, "pop", x86_read_instr_pop_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_POP_E_SP], 0x5c, "pop", x86_read_instr_pop_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_POP_E_BP], 0x5d, "pop", x86_read_instr_pop_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_POP_E_SI], 0x5e, "pop", x86_read_instr_pop_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_POP_E_DI], 0x5f, "pop", x86_read_instr_pop_r1632);
+
+ register_opcode_1632(proc->opcodes[X86_OP_PUSH_IMM1632], 0x68, "push", x86_read_instr_push_imm1632);
+
+ 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);
+
+ register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM8_IMM8], 0x80, 6, "xor", x86_read_instr_xor_rm8_with_imm8);
+ register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM8_IMM8], 0x80, 7, "cmp", x86_read_instr_cmp_rm8_with_imm8);
+
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM1632], 0x81, 0, "add", x86_read_instr_add_rm1632_imm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_OR_RM1632_IMM1632], 0x81, 1, "or", x86_read_instr_or_rm1632_imm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_ADC_RM1632_IMM1632], 0x81, 2, "adc", x86_read_instr_adc_rm1632_imm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_SBB_RM1632_IMM1632], 0x81, 3, "sbb", x86_read_instr_sbb_rm1632_imm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_AND_RM1632_IMM1632], 0x81, 4, "and", x86_read_instr_and_rm1632_imm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_SUB_RM1632_IMM1632], 0x81, 5, "sub", x86_read_instr_sub_rm1632_imm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM1632], 0x81, 6, "xor", x86_read_instr_xor_rm1632_imm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_CMP_RM1632_IMM1632], 0x81, 7, "cmp", x86_read_instr_cmp_rm1632_imm1632);
+
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM8], 0x83, 0, "add", x86_read_instr_add_imm8_to_rm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_OR_RM1632_IMM8], 0x83, 1, "or", x86_read_instr_or_rm1632_with_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_ADC_RM1632_IMM8], 0x83, 2, "adc", x86_read_instr_adc_imm8_to_rm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_SBB_RM1632_IMM8], 0x83, 3, "sbb", x86_read_instr_sbb_rm1632_with_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_AND_RM1632_IMM8], 0x83, 4, "and", x86_read_instr_and_rm1632_with_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_SUB_RM1632_IMM8], 0x83, 5, "sub", x86_read_instr_sub_imm8_from_rm1632);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM8], 0x83, 6, "xor", x86_read_instr_xor_rm1632_with_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_CMP_RM1632_IMM8], 0x83, 7, "cmp", x86_read_instr_cmp_rm1632_with_imm8);
+
+ 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_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);
+
+ register_opcode_1632(proc->opcodes[X86_OP_LEA], 0x8d, "lea", x86_read_instr_lea);
+
+ register_opcode(proc->opcodes[X86_OP_NOP], 0x90, "nop", x86_read_instr_nop);
+
+ register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_AL], 0xa0, "mov", x86_read_instr_mov_moffs8_to_al);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_MOFFS_TO_E_AX], 0xa1, "mov", x86_read_instr_mov_moffs1632_to_e_ax);
+ register_opcode(proc->opcodes[X86_OP_MOV_AL_TO_MOFFS], 0xa2, "mov", x86_read_instr_mov_al_to_moffs8);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_E_AX_TO_MOFFS], 0xa3, "mov", x86_read_instr_mov_e_ax_to_moffs1632);
+
+ register_opcode(proc->opcodes[X86_OP_TEST_AL], 0xa8, "test", x86_read_instr_test_al);
+ register_opcode_1632(proc->opcodes[X86_OP_TEST_E_AX], 0xa9, "test", x86_read_instr_test_e_ax);
+
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_E_AX], 0xb8, "mov", x86_read_instr_mov_imm1632_to_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_E_CX], 0xb9, "mov", x86_read_instr_mov_imm1632_to_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_E_DX], 0xba, "mov", x86_read_instr_mov_imm1632_to_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_E_BX], 0xbb, "mov", x86_read_instr_mov_imm1632_to_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_E_SP], 0xbc, "mov", x86_read_instr_mov_imm1632_to_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_E_BP], 0xbd, "mov", x86_read_instr_mov_imm1632_to_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_E_SI], 0xbe, "mov", x86_read_instr_mov_imm1632_to_r1632);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_E_DI], 0xbf, "mov", x86_read_instr_mov_imm1632_to_r1632);
+
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_ROL_RM1632_IMM8], 0xc1, 0, "rol", x86_read_instr_rol_rm1632_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_ROR_RM1632_IMM8], 0xc1, 1, "ror", x86_read_instr_ror_rm1632_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_RCL_RM1632_IMM8], 0xc1, 2, "rcl", x86_read_instr_rcl_rm1632_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_RCR_RM1632_IMM8], 0xc1, 3, "rcr", x86_read_instr_rcr_rm1632_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_SHL_RM1632_IMM8], 0xc1, 4, "shl", x86_read_instr_shl_rm1632_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_SHR_RM1632_IMM8], 0xc1, 5, "shr", x86_read_instr_shr_rm1632_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_SAL_RM1632_IMM8], 0xc1, 6, "sal", x86_read_instr_sal_rm1632_imm8);
+ register_opcode_1632_with_ext(proc->opcodes[X86_OP_SAR_RM1632_IMM8], 0xc1, 7, "sar", x86_read_instr_sar_rm1632_imm8);
+
+ register_opcode(proc->opcodes[X86_OP_RET], 0xc3, "ret", x86_read_instr_ret);
+
+ register_opcode(proc->opcodes[X86_OP_MOV_IMM8_TO_RM8], 0xc6, "mov", x86_read_instr_mov_imm8_to_rm8);
+ register_opcode_1632(proc->opcodes[X86_OP_MOV_IMM1632_TO_RM1632], 0xc7, "mov", x86_read_instr_mov_imm1632_to_rm1632);
+
+ register_opcode(proc->opcodes[X86_OP_LEAVE], 0xc9, "leave", x86_read_instr_leave);
+
+ register_opcode(proc->opcodes[X86_OP_INT], 0xcd, "int", x86_read_instr_int);
- register_opcode(proc->opcodes[X86_OP_PUSH_IMM1632], 0x66, 0x68, "push", x86_read_instr_push_imm1632);
- register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM8_IMM8], 0x00, 0x80, 6, "xor", x86_read_instr_xor_rm8_with_imm8);
- register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM8_IMM8], 0x00, 0x80, 7, "cmp", x86_read_instr_cmp_rm8_with_imm8);
+ 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);
- register_opcode_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM1632], 0x66, 0x81, 0, "add", x86_read_instr_add_imm1632_to_rm1632);
+ register_opcode(proc->opcodes[X86_OP_JMP_8], 0xeb, "jmp", x86_read_instr_jmp_8);
- register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM1632], 0x66, 0x81, 6, "xor", x86_read_instr_xor_rm1632_with_imm1632);
+ register_opcode(proc->opcodes[X86_OP_HLT], 0xf4, "hlt", x86_read_instr_hlt);
- register_opcode_with_ext(proc->opcodes[X86_OP_ADD_RM1632_IMM8], 0x66, 0x83, 0, "add", x86_read_instr_add_imm8_to_rm1632);
- register_opcode_with_ext(proc->opcodes[X86_OP_OR_RM1632_IMM8], 0x66, 0x83, 1, "or", x86_read_instr_or_rm1632_with_imm8);
- register_opcode_with_ext(proc->opcodes[X86_OP_ADC_RM1632_IMM8], 0x66, 0x83, 2, "adc", x86_read_instr_adc_imm8_to_rm1632);
- register_opcode_with_ext(proc->opcodes[X86_OP_SBB_RM1632_IMM8], 0x66, 0x83, 3, "sbb", x86_read_instr_sbb_rm1632_with_imm8);
- register_opcode_with_ext(proc->opcodes[X86_OP_AND_RM1632_IMM8], 0x66, 0x83, 4, "and", x86_read_instr_and_rm1632_with_imm8);
- register_opcode_with_ext(proc->opcodes[X86_OP_SUB_RM1632_IMM8], 0x66, 0x83, 5, "sub", x86_read_instr_sub_imm8_from_rm1632);
- register_opcode_with_ext(proc->opcodes[X86_OP_XOR_RM1632_IMM8], 0x66, 0x83, 6, "xor", x86_read_instr_xor_rm1632_with_imm8);
- register_opcode_with_ext(proc->opcodes[X86_OP_CMP_RM1632_IMM8], 0x66, 0x83, 7, "cmp", x86_read_instr_cmp_rm1632_with_imm8);
-
- register_opcode(proc->opcodes[X86_OP_JE_8], 0x00, 0x74, "je", x86_read_instr_je_8);
- register_opcode(proc->opcodes[X86_OP_JNE_8], 0x00, 0x75, "jne", x86_read_instr_jne_8);
-
- register_opcode(proc->opcodes[X86_OP_TEST_RM8_R8], 0x00, 0x84, "test", x86_read_instr_test_rm8_with_r8);
- register_opcode(proc->opcodes[X86_OP_TEST_RM1632_R1632], 0x66, 0x85, "test", x86_read_instr_test_rm1632_with_r1632);
-
- register_opcode(proc->opcodes[X86_OP_MOV_RM1632_R1632], 0x66, 0x89, "mov", x86_read_instr_mov_r1632_to_rm1632);
-
- register_opcode(proc->opcodes[X86_OP_MOV_R1632_RM1632], 0x66, 0x8b, "mov", x86_read_instr_mov_rm1632_to_r1632);
-
- register_opcode(proc->opcodes[X86_OP_LEA], 0x66, 0x8d, "lea", x86_read_instr_lea);
-
- register_opcode(proc->opcodes[X86_OP_NOP], 0x00, 0x90, "nop", x86_read_instr_nop);
-
- register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_AL], 0x00, 0xa0, "mov", x86_read_instr_mov_moffs8_to_al);
- register_opcode(proc->opcodes[X86_OP_MOV_MOFFS_TO_E_AX], 0x66, 0xa1, "mov", x86_read_instr_mov_moffs1632_to_e_ax);
- register_opcode(proc->opcodes[X86_OP_MOV_AL_TO_MOFFS], 0x00, 0xa2, "mov", x86_read_instr_mov_al_to_moffs8);
- register_opcode(proc->opcodes[X86_OP_MOV_E_AX_TO_MOFFS], 0x66, 0xa3, "mov", x86_read_instr_mov_e_ax_to_moffs1632);
-
- register_opcode(proc->opcodes[X86_OP_TEST_AL], 0x00, 0xa8, "test", x86_read_instr_test_al);
- register_opcode(proc->opcodes[X86_OP_TEST_E_AX], 0x66, 0xa9, "test", x86_read_instr_test_e_ax);
-
- register_opcode(proc->opcodes[X86_OP_MOV_E_AX], 0x66, 0xb8, "mov", x86_read_instr_mov_imm1632_to_r1632);
- register_opcode(proc->opcodes[X86_OP_MOV_E_CX], 0x66, 0xb9, "mov", x86_read_instr_mov_imm1632_to_r1632);
- register_opcode(proc->opcodes[X86_OP_MOV_E_DX], 0x66, 0xba, "mov", x86_read_instr_mov_imm1632_to_r1632);
- register_opcode(proc->opcodes[X86_OP_MOV_E_BX], 0x66, 0xbb, "mov", x86_read_instr_mov_imm1632_to_r1632);
- register_opcode(proc->opcodes[X86_OP_MOV_E_SP], 0x66, 0xbc, "mov", x86_read_instr_mov_imm1632_to_r1632);
- register_opcode(proc->opcodes[X86_OP_MOV_E_BP], 0x66, 0xbd, "mov", x86_read_instr_mov_imm1632_to_r1632);
- register_opcode(proc->opcodes[X86_OP_MOV_E_SI], 0x66, 0xbe, "mov", x86_read_instr_mov_imm1632_to_r1632);
- register_opcode(proc->opcodes[X86_OP_MOV_E_DI], 0x66, 0xbf, "mov", x86_read_instr_mov_imm1632_to_r1632);
-
- register_opcode_with_ext(proc->opcodes[X86_OP_SAR_RM1632_IMM8], 0x66, 0xc1, 7, "sar", x86_read_instr_sar_rm1632_with_imm8);
-
- register_opcode(proc->opcodes[X86_OP_RET], 0x00, 0xc3, "ret", x86_read_instr_ret);
-
- register_opcode(proc->opcodes[X86_OP_MOV_IMM8_TO_RM8], 0x00, 0xc6, "mov", x86_read_instr_mov_imm8_to_rm8);
- register_opcode(proc->opcodes[X86_OP_MOV_IMM1632_TO_RM1632], 0x66, 0xc7, "mov", x86_read_instr_mov_imm1632_to_rm1632);
-
- register_opcode(proc->opcodes[X86_OP_LEAVE], 0x00, 0xc9, "leave", x86_read_instr_leave);
-
- register_opcode(proc->opcodes[X86_OP_INT], 0x00, 0xcd, "int", x86_read_instr_int);
-
-
- 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);
+ 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);
}
@@ -351,48 +397,46 @@ void x86_register_instructions(asm_x86_processor *proc)
asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *data, off_t *pos, off_t len, uint64_t offset)
{
asm_x86_instr *result; /* Résultat à faire remonter */
+ X86Prefix prefix; /* Préfixe détecté */
X86Opcodes i; /* Boucle de parcours */
- off_t tmp; /* Tête de lecture */
- off_t old_pos; /* Sauvegarde de la position */
result = NULL;
- for (i = 0; i < X86_OP_COUNT; i++)
+ prefix = X86_PRE_NONE;
+
+ consume_prefix:
+
+ switch (data[*pos])
{
- if (proc->opcodes[i].prefix > 0 && data[*pos] == proc->opcodes[i].prefix && data[*pos + 1] == proc->opcodes[i].opcode)
- {
- tmp = *pos + 2;
- goto find_instr;
- }
+ case 0x66:
+ prefix |= X86_PRE_OPSIZE;
+ (*pos)++;
+ break;
- if (proc->opcodes[i].opt_prefix && data[*pos] == proc->opcodes[i].opcode)
- {
- tmp = *pos + 1;
- goto find_instr;
- }
+ case 0x0f:
+ prefix |= X86_PRE_ESCAPE;
+ (*pos)++;
+ break;
- if (proc->opcodes[i].prefix == 0x00 && data[*pos] == proc->opcodes[i].opcode)
- {
- tmp = *pos + 1;
- goto find_instr;
- }
+ default:
+ goto found_instr;
+ break;
+
+ }
- continue;
+ goto consume_prefix;
- find_instr:
+ found_instr:
- if (proc->opcodes[i].has_op_ext && (data[tmp] & EXT_OPCODE_MASK) != proc->opcodes[i].op_ext)
- continue;
+ for (i = 0; i < X86_OP_COUNT; i++)
+ {
+ if ((prefix & proc->opcodes[i].prefix) != prefix) continue;
- old_pos = *pos;
+ if (data[*pos] != proc->opcodes[i].opcode) continue;
result = proc->opcodes[i].read(data, pos, len, offset, proc);
if (result != NULL) result->type = i;
- else
- {
- *pos = old_pos;
- printf("err while x86 decoding at 0x%08llx :: [0x%02hhx] 0x%02hhx\n", offset, proc->opcodes[i].prefix, proc->opcodes[i].opcode);
- }
+
break;
}