From 0b7d7f26c745ff0f52e9e483a0980351368ca824 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 24 May 2009 22:34:42 +0000
Subject: Supported nine extra x86 opcodes.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@66 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                  | 21 +++++++++++++++++++++
 src/analysis/binary.c      |  4 ++--
 src/arch/immediate.c       | 39 +++++++++++++++++++++++++++++++++++++++
 src/arch/x86/Makefile.am   |  1 +
 src/arch/x86/instruction.h | 22 ++++++++++++++++++++--
 src/arch/x86/op_mov.c      | 36 ++++++++++++++++++++++++++++++++++++
 src/arch/x86/opcodes.h     |  6 ++++++
 src/arch/x86/operand.c     | 10 ++++++++++
 src/arch/x86/operand.h     |  3 ++-
 src/arch/x86/processor.c   | 17 +++++++++++++++++
 10 files changed, 154 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 48162e8..48619cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+09-05-25  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/binary.c:
+	Restore the entry point mark.
+
+	* src/arch/immediate.c:
+	Print extra information about the values when possible.
+
+	* src/arch/x86/instruction.h:
+	Support nine extra opcodes.
+
+	* src/arch/x86/Makefile.am:
+	Add op_scas.c to libarchx86_la_SOURCES.
+
+	* src/arch/x86/opcodes.h:
+	* src/arch/x86/operand.c:
+	* src/arch/x86/operand.h:
+	* src/arch/x86/op_mov.c:
+	* src/arch/x86/processor.c:
+	Support nine extra opcodes.
+
 09-05-19  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/arch/immediate.c:
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index fbc9259..2c9166c 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -662,10 +662,10 @@ void disassemble_openida_binary(openida_binary *binary)
     }
 
 
-    /*
+
     line = g_rendering_line_find_by_offset(binary->lines, get_exe_entry_point(binary->format));
     if (line != NULL) g_rendering_line_add_flag(line, RLF_ENTRY_POINT);
-    */
+
 
 
 
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index dde5f02..7ef1220 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -30,6 +30,7 @@
 
 
 #include "operand-int.h"
+#include "../common/extstr.h"
 
 
 
@@ -339,6 +340,12 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
 static char *g_imm_operand_get_text(const GImmOperand *operand, const exe_format *format, AsmSyntax syntax)
 {
     char *result;                           /* Chaîne à retourner          */
+    char *label;                            /* Etiquette de symbole        */
+    SymbolType symtype;                     /* Type de symbole             */
+    vmpa_t offset;                          /* Décallage final constaté    */
+    char buffer[256];                       /* Complément d'information    */
+
+    /* Valeur brute */
 
     result = (char *)calloc(19, sizeof(char));
 
@@ -412,6 +419,38 @@ static char *g_imm_operand_get_text(const GImmOperand *operand, const exe_format
 
     }
 
+    /* Complément d'information */
+
+    if (operand->size == AOS_32_BITS_SIGNED || operand->size == AOS_32_BITS_UNSIGNED)   /* FIXME */
+    {
+        offset = operand->unsigned_imm.val32; /* FIXME !!! */
+
+        if (resolve_exe_symbol(format, &label, &symtype, &offset))
+        {
+            switch (symtype)
+            {
+                case STP_SECTION:
+                    if (offset == 0) snprintf(buffer, 256, " &lt;%s&gt;", label);
+                    else snprintf(buffer, 256, " &lt;%s+0x%llx&gt;", label, offset);
+                    result = stradd(result, buffer);
+                    break;
+
+                case STP_STRING:
+                    label = escape_crlf(label);
+                    label = strrpl(label, "<", "&lt;");
+                    label = strrpl(label, ">", "&gt;");
+                    snprintf(buffer, 256, " \"%s\"", label);
+                    result = stradd(result, buffer);
+                    break;
+
+            }
+
+            free(label);
+
+        }
+
+    }
+
     return result;
 
 }
diff --git a/src/arch/x86/Makefile.am b/src/arch/x86/Makefile.am
index 063a7ce..3b36490 100644
--- a/src/arch/x86/Makefile.am
+++ b/src/arch/x86/Makefile.am
@@ -29,6 +29,7 @@ libarchx86_la_SOURCES =					\
 	op_ror.c							\
 	op_sar.c							\
 	op_sbb.c							\
+	op_scas.c							\
 	op_shl.c							\
 	op_shr.c							\
 	op_sub.c							\
diff --git a/src/arch/x86/instruction.h b/src/arch/x86/instruction.h
index 1a65066..6186e96 100644
--- a/src/arch/x86/instruction.h
+++ b/src/arch/x86/instruction.h
@@ -28,6 +28,9 @@
 #include "../instruction.h"
 
 
+/* Types de préfixes pour x86 */
+typedef enum _X86Prefix X86Prefix;
+
 
 /* Enumération de tous les opcodes */
 typedef enum _X86Opcodes
@@ -181,7 +184,17 @@ typedef enum _X86Opcodes
     XOP_TEST_AL_IMM8,                       /* test (0xa8)                 */
     XOP_TEST_E_AX_IMM1632,                  /* test ([0x66] 0xa9)          */
 
+    XOP_SCAS_AL_M8,                         /* scas (0xae)                 */
+
 
+    XOP_MOV_AL_IMM8,                        /* mov (0xb0)                  */
+    XOP_MOV_CL_IMM8,                        /* mov (0xb1)                  */
+    XOP_MOV_DL_IMM8,                        /* mov (0xb2)                  */
+    XOP_MOV_BL_IMM8,                        /* mov (0xb3)                  */
+    XOP_MOV_AH_IMM8,                        /* mov (0xb4)                  */
+    XOP_MOV_CH_IMM8,                        /* mov (0xb5)                  */
+    XOP_MOV_DH_IMM8,                        /* mov (0xb6)                  */
+    XOP_MOV_BH_IMM8,                        /* mov (0xb7)                  */
     XOP_MOV_E_AX_IMM1632,                   /* mov ([0x66] 0xb8)           */
     XOP_MOV_E_CX_IMM1632,                   /* mov ([0x66] 0xb9)           */
     XOP_MOV_E_DX_IMM1632,                   /* mov ([0x66] 0xba)           */
@@ -253,19 +266,24 @@ GType g_x86_instruction_get_type(void);
 /* Crée une instruction pour l'architecture x86. */
 GArchInstruction *g_x86_instruction_new(X86Opcodes);
 
+/* Attache à une instructions ses préfixes associés. */
+void g_x86_instruction_set_prefixes(GX86Instruction *, X86Prefix);
+
 
 
 /* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */
 
 
 /* Types de préfixes pour x86 */
-typedef enum _X86Prefix
+enum _X86Prefix
 {
     XPX_NONE                    = (0 << 0), /* Code d'instruction pur      */
 
     XPX_OPERAND_SIZE_OVERRIDE   = (1 << 0), /* Taille des opérandes        */
 
-} X86Prefix;
+    XPX_REPEAT_STRING_OPERATION = (1 << 2)  /* Boucle pour les chaînes     */
+
+};
 
 
 /* Recherche l'identifiant de la prochaine instruction. */
diff --git a/src/arch/x86/op_mov.c b/src/arch/x86/op_mov.c
index 4828ba1..4532e90 100644
--- a/src/arch/x86/op_mov.c
+++ b/src/arch/x86/op_mov.c
@@ -176,6 +176,42 @@ GArchInstruction *x86_read_instr_mov_moffs1632_e_ax(const bin_t *data, off_t *po
 *                addr = 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   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *x86_read_instr_mov_r8_imm8(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
+{
+    GArchInstruction *result;               /* Instruction à retourner     */
+    X86Opcodes opcode;                      /* Instruction effective       */
+
+    opcode = XOP_MOV_AL_IMM8 + (data[*pos] - 0xb0);
+
+    result = g_x86_instruction_new(opcode);
+
+    if (!x86_read_two_operands(result, data, pos, len, X86_OTP_OP_R8, X86_OTP_IMM8, 0xb0))
+    {
+        /* TODO 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.                 *
+*                addr = adresse virtuelle de l'instruction.                   *
+*                proc = architecture ciblée par le désassemblage.             *
+*                                                                             *
 *  Description : Décode une instruction de type 'mov' (16 ou 32 bits).        *
 *                                                                             *
 *  Retour      : Instruction mise en place ou NULL.                           *
diff --git a/src/arch/x86/opcodes.h b/src/arch/x86/opcodes.h
index f0bbc17..67858b0 100644
--- a/src/arch/x86/opcodes.h
+++ b/src/arch/x86/opcodes.h
@@ -192,6 +192,9 @@ GArchInstruction *x86_read_instr_mov_moffs8_al(const bin_t *, off_t *, off_t, vm
 /* Décode une instruction de type 'mov ..., [e]ax' (16/32 bits). */
 GArchInstruction *x86_read_instr_mov_moffs1632_e_ax(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
 
+/* Décode une instruction de type 'mov' (8 bits). */
+GArchInstruction *x86_read_instr_mov_r8_imm8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+
 /* Décode une instruction de type 'mov' (16 ou 32 bits). */
 GArchInstruction *x86_read_instr_mov_r1632_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
 
@@ -273,6 +276,9 @@ GArchInstruction *x86_read_instr_sbb_rm1632_imm8(const bin_t *, off_t *, off_t,
 /* Décode une instruction de type 'sbb' (16 ou 32 bits). */
 GArchInstruction *x86_read_instr_sbb_rm1632_imm1632(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
 
+/* Décode une instruction de type 'scas al, ...' (8 bits). */
+GArchInstruction *x86_read_instr_scas_al_m8(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
+
 /* Décode une instruction de type 'shl' (16 ou 32 bits). */
 GArchInstruction *x86_read_instr_shl_rm1632_cl(const bin_t *, off_t *, off_t, vmpa_t, X86Prefix, const GX86Processor *);
 
diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c
index bb152f8..e916541 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -966,6 +966,11 @@ bool x86_read_one_operand(GArchInstruction *instr, const bin_t *data, off_t *pos
             op = g_x86_register_operand_new_from_mod_rm(data, pos, len, oprsize, true);
             break;
 
+        case X86_OTP_OP_R8:
+            base = (bin_t)va_arg(ap, int);
+            op = g_x86_register_operand_new_from_opcode(data, pos, len, AOS_8_BITS, base);
+            break;
+
         case X86_OTP_OP_R1632:
             oprsize = va_arg(ap, AsmOperandSize);
             base = (bin_t)va_arg(ap, int);
@@ -1090,6 +1095,11 @@ bool x86_read_two_operands(GArchInstruction *instr, const bin_t *data, off_t *po
             op1 = g_x86_register_operand_new_from_mod_rm(data, &op1_pos, len, oprsize, op1_first);
             break;
 
+        case X86_OTP_OP_R8:
+            base = (bin_t)va_arg(ap, int);
+            op1 = g_x86_register_operand_new_from_opcode(data, &op1_pos, len, AOS_8_BITS, base);
+            break;
+
         case X86_OTP_OP_R1632:
             oprsize = va_arg(ap, AsmOperandSize);
             base = (bin_t)va_arg(ap, int);
diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h
index bc495a0..ebab200 100644
--- a/src/arch/x86/operand.h
+++ b/src/arch/x86/operand.h
@@ -180,7 +180,8 @@ typedef enum _X86OperandType
 
     X86_OTP_R8          = X86_OTP_REG(1),   /* Registre 8 bits             */
     X86_OTP_R1632       = X86_OTP_REG(2),   /* Registre 16 ou 32 bits      */
-    X86_OTP_OP_R1632    = X86_OTP_REG(3),   /* Registre 16 ou 32 bits      */
+    X86_OTP_OP_R8       = X86_OTP_REG(3),   /* Registre 8 bits             */
+    X86_OTP_OP_R1632    = X86_OTP_REG(4),   /* Registre 16 ou 32 bits      */
 
     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  */
diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c
index 5bf6d9f..aae4fe3 100644
--- a/src/arch/x86/processor.c
+++ b/src/arch/x86/processor.c
@@ -570,7 +570,21 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor
             break;
 
 
+        case XOP_SCAS_AL_M8:
+            result = x86_read_instr_scas_al_m8(data, pos, len, addr, prefix, proc);
+            break;
+
 
+        case XOP_MOV_AL_IMM8:
+        case XOP_MOV_CL_IMM8:
+        case XOP_MOV_DL_IMM8:
+        case XOP_MOV_BL_IMM8:
+        case XOP_MOV_AH_IMM8:
+        case XOP_MOV_CH_IMM8:
+        case XOP_MOV_DH_IMM8:
+        case XOP_MOV_BH_IMM8:
+            result = x86_read_instr_mov_r8_imm8(data, pos, len, addr, prefix, proc);
+            break;
 
         case XOP_MOV_E_AX_IMM1632:
         case XOP_MOV_E_CX_IMM1632:
@@ -709,6 +723,9 @@ static GArchInstruction *g_x86_processor_decode_instruction(const GX86Processor
 
     }
 
+    if (result != NULL)
+        g_x86_instruction_set_prefixes(G_X86_INSTRUCTION(result), prefix);
+
     return result;
 
 }
-- 
cgit v0.11.2-87-g4458