From 2e5893f9261ba59e06fadcc6ddfa9a1253e286b3 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 27 Oct 2008 20:00:09 +0000
Subject: Extended the current opcode support (0x01, 0x72, 0x73, 0x88, 0xd3,
 0xf7, 0xfc, 0xb6 and 0xbe).

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@38 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                  | 41 +++++++++++++++++++++++++
 src/arch/x86/Makefile.am   |  5 +++-
 src/arch/x86/instruction.h | 29 +++++++++++++-----
 src/arch/x86/op_add.c      | 38 ++++++++++++++++++++++++
 src/arch/x86/op_cld.c      | 58 ++++++++++++++++++++++++++++++++++++
 src/arch/x86/op_jump.c     | 74 ++++++++++++++++++++++++++++++++++++++++++++++
 src/arch/x86/op_mov.c      | 35 ++++++++++++++++++++++
 src/arch/x86/op_movsx.c    | 71 ++++++++++++++++++++++++++++++++++++++++++++
 src/arch/x86/op_movzx.c    |  3 ++
 src/arch/x86/op_not.c      | 68 ++++++++++++++++++++++++++++++++++++++++++
 src/arch/x86/op_shl.c      | 38 ++++++++++++++++++++++++
 src/arch/x86/opcodes.h     | 30 +++++++++++++++++--
 src/arch/x86/operand.c     | 12 ++++++++
 src/arch/x86/operand.h     |  1 +
 src/arch/x86/processor.c   | 49 ++++++++++++++++++------------
 15 files changed, 521 insertions(+), 31 deletions(-)
 create mode 100644 src/arch/x86/op_cld.c
 create mode 100644 src/arch/x86/op_movsx.c
 create mode 100644 src/arch/x86/op_not.c

diff --git a/ChangeLog b/ChangeLog
index c251af9..e4d24d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,46 @@
 2008-10-27  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/arch/x86/instruction.h:
+	Register some new instructions.
+
+	* src/arch/x86/Makefile.am:
+	Add op_cld, op_movsx and op_not to libarchx86_a_SOURCES.
+
+	* src/arch/x86/op_add.c:
+	Extend the current opcode support.
+
+	* rc/arch/x86/op_cld.c:
+	New entry: handle a new opcode.
+
+	* src/arch/x86/opcodes.h:
+	Register some new instructions.
+
+	* src/arch/x86/operand.c:
+	* src/arch/x86/operand.h:
+	Accept the 'cl' register as operand.
+
+	* src/arch/x86/op_jump.c:
+	* src/arch/x86/op_mov.c:
+	Extend the current opcode support.
+
+	* src/arch/x86/op_movsx.c:
+	New entry: handle a new opcode.
+
+	* src/arch/x86/op_movzx.c:
+	Extend the current opcode support.
+
+	* src/arch/x86/op_not.c:
+	New entry: handle a new opcode.
+
+	* src/arch/x86/op_shl.c:
+	Extend the current opcode support.
+
+	* src/arch/x86/processor.c:
+	Extend the current opcode support (0x01, 0x72, 0x73, 0x88, 0xd3, 0xf7,
+	0xfc, 0xb6 and 0xbe).
+
+2008-10-27  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/arch/processor.c:
 	Take care here of decoding failures.
 
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;
-- 
cgit v0.11.2-87-g4458