From e8d2795d9ec2c8845641863fc42ce39f9e92906b Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 5 Oct 2011 19:34:00 +0000
Subject: Supported a few more Dalvik opcodes.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@211 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                          | 24 ++++++++++++++++++
 src/analysis/disass/disassembler.c | 28 ++++++++++++++++++++
 src/analysis/disass/fetch.c        | 20 +++++++++++++++
 src/arch/dalvik/instruction.c      |  4 +++
 src/arch/dalvik/instruction.h      |  2 ++
 src/arch/dalvik/op_array.c         | 36 ++++++++++++++++++++++++++
 src/arch/dalvik/op_move.c          | 36 ++++++++++++++++++++++++++
 src/arch/dalvik/opcodes.h          |  6 +++++
 src/arch/dalvik/operand.c          | 23 +++++++++++++++++
 src/arch/dalvik/operand.h          |  2 ++
 src/arch/dalvik/processor.c        |  3 +++
 src/format/part.c                  | 52 ++++++++++++++++++++++++++++++++++++++
 src/format/part.h                  | 10 ++++++++
 13 files changed, 246 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index b2b399e..227acaf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+11-10-05  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/disassembler.c:
+	* src/analysis/disass/fetch.c:
+	Count and print the quantity of decoded instruction in DEBUG mode.
+
+	* src/arch/dalvik/instruction.c:
+	* src/arch/dalvik/instruction.h:
+	* src/arch/dalvik/op_array.c:
+	* src/arch/dalvik/opcodes.h:
+	Support a few more Dalvik opcodes.
+
+	* src/arch/dalvik/operand.c:
+	* src/arch/dalvik/operand.h:
+	Support two extra operand format: 22x and 31t.
+
+	* src/arch/dalvik/op_move.c:
+	* src/arch/dalvik/processor.c:
+	Support a few more Dalvik opcodes.
+
+	* src/format/part.c:
+	* src/format/part.h:
+	Store and provide the quantity of decoded instruction in DEBUG mode.
+
 11-10-01  Cyrille Bagard <nocbos@gmail.com>
 
 	* plugins/pyoida/plugin.c:
diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c
index 283914e..046f936 100644
--- a/src/analysis/disass/disassembler.c
+++ b/src/analysis/disass/disassembler.c
@@ -38,6 +38,9 @@
 #include "../../decomp/lang/asm.h"
 #include "../../format/format.h"
 #include "../../glibext/delayed-int.h"
+#ifdef DEBUG
+#   include "../../panels/log.h"
+#endif
 
 
 
@@ -196,6 +199,13 @@ static GDelayedDisassembly *g_delayed_disassembly_new(const GOpenidaBinary *bina
 
 static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar)
 {
+#ifdef DEBUG
+    unsigned int valid;                     /* Instructions traduites      */
+    unsigned int db;                        /* Instructions non décodées   */
+    unsigned int valid_sum;                 /* Instructions traduites      */
+    unsigned int instr_sum;                 /* Instructions totales        */
+    size_t i;                               /* Boucle de parcours          */
+#endif
     GBinRoutine **routines;                 /* Liste des routines trouvées */
     size_t routines_count;                  /* Nombre de ces routines      */
     guint id;                               /* Identifiant de statut       */
@@ -211,6 +221,24 @@ static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtSta
 
     gtk_extended_status_bar_remove(statusbar, id);
 
+#ifdef DEBUG
+
+    valid_sum = 0;
+    instr_sum = 0;
+
+    for (i = 0; i < disass->count; i++)
+    {
+        g_binary_part_get_checkup(disass->parts[i], &valid, &db);
+        valid_sum += valid;
+        instr_sum += (valid + db);
+    }
+
+    log_variadic_message(LMT_WARNING, _("Disassembled instructions : %u %% (%u / %d)"),
+                         (valid_sum * 100) / instr_sum,
+                         valid_sum, instr_sum);
+
+#endif
+
     /* Seconde étape */
 
     id = gtk_extended_status_bar_push(statusbar, _("Establishing links..."), true);
diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c
index 575eb06..5f93eba 100644
--- a/src/analysis/disass/fetch.c
+++ b/src/analysis/disass/fetch.c
@@ -23,6 +23,10 @@
 
 #include "fetch.h"
 
+#ifdef DEBUG
+#   include "../../arch/artificial.h"
+#endif
+
 
 
 /******************************************************************************
@@ -50,6 +54,10 @@ GArchInstruction *disassemble_binary_parts(const GOpenidaBinary *binary, GBinPar
     size_t i;                               /* Boucle de parcours #1       */
     off_t sum;                              /* Somme de toutes les tailles */
     off_t done;                             /* Quantité déjà traitée       */
+#ifdef DEBUG
+    unsigned int valid;                     /* Instructions traduites      */
+    unsigned int db;                        /* Instructions non décodées   */
+#endif
     off_t pos;                              /* Début d'une zone binaire    */
     off_t len;                              /* Taille de cette même zone   */
     vmpa_t base;                            /* Adresse de la zone binaire  */
@@ -83,6 +91,11 @@ GArchInstruction *disassemble_binary_parts(const GOpenidaBinary *binary, GBinPar
 
         /* Décodage des instructions */
 
+#ifdef DEBUG
+        valid = 0;
+        db = 0;
+#endif
+
         start = pos;
         pos = 0;
 
@@ -94,11 +107,18 @@ GArchInstruction *disassemble_binary_parts(const GOpenidaBinary *binary, GBinPar
                                                         &pos, len, start, addr);
             g_arch_instruction_add_to_list(&result, instr);
 
+#ifdef DEBUG
+            if (G_IS_DB_INSTRUCTION(instr)) db++;
+            else valid++;
+#endif
+
             if (pos < len)
                 gtk_extended_status_bar_update_activity(statusbar, id, (done + pos) * 1.0 / sum);
 
         }
 
+        g_binary_part_set_checkup(parts[i], valid, db);
+
         done += len;
         gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / sum);
 
diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c
index 051bbe2..4595193 100644
--- a/src/arch/dalvik/instruction.c
+++ b/src/arch/dalvik/instruction.c
@@ -73,6 +73,7 @@ static dalvik_instruction _instructions[DOP_COUNT] = {
 
     [DOP_NOP]                   = { 0x00, "nop" },
     [DOP_MOVE]                  = { 0x01, "move" },
+    [DOP_MOVE_FROM_16]          = { 0x02, "move/from16" },
 
     [DOP_MOVE_OBJECT]           = { 0x07, "move-object" },
 
@@ -101,6 +102,9 @@ static dalvik_instruction _instructions[DOP_COUNT] = {
     [DOP_NEW_INSTANCE]          = { 0x22, "new-instance" },
     [DOP_NEW_ARRAY]             = { 0x23, "new-array" },
 
+
+    [DOP_FILL_ARRAY_DATA]       = { 0x26, "fill-array-data" },
+
     [DOP_GOTO]                  = { 0x28, "goto" },
     [DOP_GOTO_16]               = { 0x29, "goto/16" },
     [DOP_GOTO_32]               = { 0x2a, "goto/32" },
diff --git a/src/arch/dalvik/instruction.h b/src/arch/dalvik/instruction.h
index 8eaed17..c359c66 100644
--- a/src/arch/dalvik/instruction.h
+++ b/src/arch/dalvik/instruction.h
@@ -34,6 +34,7 @@ typedef enum _DalvikOpcodes
 {
     DOP_NOP,                                /* nop (0x00)                  */
     DOP_MOVE,                               /* move (0x01)                 */
+    DOP_MOVE_FROM_16,                       /* move/from16 (0x02)          */
 
     DOP_MOVE_OBJECT,                        /* move-object (0x07)          */
 
@@ -62,6 +63,7 @@ typedef enum _DalvikOpcodes
     DOP_NEW_INSTANCE,                       /* new-instance (0x22)         */
     DOP_NEW_ARRAY,                          /* new-array (0x23)            */
 
+    DOP_FILL_ARRAY_DATA,                    /* fill-array-data (0x26)      */
 
     DOP_GOTO,                               /* goto (0x28)                 */
     DOP_GOTO_16,                            /* goto/16 (0x29)              */
diff --git a/src/arch/dalvik/op_array.c b/src/arch/dalvik/op_array.c
index 90c61e8..3eecc85 100644
--- a/src/arch/dalvik/op_array.c
+++ b/src/arch/dalvik/op_array.c
@@ -63,3 +63,39 @@ GArchInstruction *dalvik_read_instr_array_length(const bin_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.                 *
+*                addr = adresse virtuelle de l'instruction.                   *
+*                proc = architecture ciblée par le désassemblage.             *
+*                                                                             *
+*  Description : Décode une instruction de type 'fill-array-data'.            *
+*                                                                             *
+*  Retour      : Instruction mise en place ou NULL.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *dalvik_read_instr_fill_array_data(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc)
+{
+    GArchInstruction *result;               /* Instruction à retourner     */
+    SourceEndian endian;                    /* Boutisme lié au binaire     */
+
+    result = g_dalvik_instruction_new(DOP_FILL_ARRAY_DATA);
+
+    endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc));
+
+    if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_31T))
+    {
+        g_object_unref(G_OBJECT(result));
+        return NULL;
+    }
+
+    return result;
+
+}
diff --git a/src/arch/dalvik/op_move.c b/src/arch/dalvik/op_move.c
index de4da28..0462fdb 100644
--- a/src/arch/dalvik/op_move.c
+++ b/src/arch/dalvik/op_move.c
@@ -109,6 +109,42 @@ GArchInstruction *dalvik_read_instr_move_exception(const bin_t *data, off_t *pos
 *                addr = adresse virtuelle de l'instruction.                   *
 *                proc = architecture ciblée par le désassemblage.             *
 *                                                                             *
+*  Description : Décode une instruction de type 'move/from16'.                *
+*                                                                             *
+*  Retour      : Instruction mise en place ou NULL.                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GArchInstruction *dalvik_read_instr_move_from_16(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GDalvikProcessor *proc)
+{
+    GArchInstruction *result;               /* Instruction à retourner     */
+    SourceEndian endian;                    /* Boutisme lié au binaire     */
+
+    result = g_dalvik_instruction_new(DOP_MOVE_FROM_16);
+
+    endian = g_arch_processor_get_endianness(G_ARCH_PROCESSOR(proc));
+
+    if (!dalvik_read_operands(result, data, pos, len, endian, DALVIK_OPT_22X))
+    {
+        g_object_unref(G_OBJECT(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 'move-object'.                *
 *                                                                             *
 *  Retour      : Instruction mise en place ou NULL.                           *
diff --git a/src/arch/dalvik/opcodes.h b/src/arch/dalvik/opcodes.h
index 7d4b42e..d8d3616 100644
--- a/src/arch/dalvik/opcodes.h
+++ b/src/arch/dalvik/opcodes.h
@@ -183,6 +183,9 @@ GArchInstruction *dalvik_read_instr_div_int_lit8(const bin_t *, off_t *, off_t,
 GArchInstruction *dalvik_read_instr_div_int_lit16(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *);
 
 
+/* Décode une instruction de type 'fill-array-data'. */
+GArchInstruction *dalvik_read_instr_fill_array_data(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *);
+
 
 /* Décode une instruction de type 'goto'. */
 GArchInstruction *dalvik_read_instr_goto(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *);
@@ -308,6 +311,9 @@ GArchInstruction *dalvik_read_instr_move(const bin_t *, off_t *, off_t, vmpa_t,
 /* Décode une instruction de type 'move-exception'. */
 GArchInstruction *dalvik_read_instr_move_exception(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *);
 
+/* Décode une instruction de type 'move/from16'. */
+GArchInstruction *dalvik_read_instr_move_from_16(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *);
+
 /* Décode une instruction de type 'move-object'. */
 GArchInstruction *dalvik_read_instr_move_object(const bin_t *, off_t *, off_t, vmpa_t, const GDalvikProcessor *);
 
diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c
index f6392b3..7c245d8 100644
--- a/src/arch/dalvik/operand.c
+++ b/src/arch/dalvik/operand.c
@@ -36,6 +36,7 @@ typedef enum _DalvikOperandID
 
     DOI_REGISTER_4,
     DOI_REGISTER_8,
+    DOI_REGISTER_16,
 
     DOI_IMMEDIATE_4,
     DOI_IMMEDIATE_8,
@@ -199,6 +200,14 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat
             };
             break;
 
+        case DALVIK_OPT_22X:
+            types = (DalvikOperandID []) {
+                DOI_REGISTER_8,
+                DOI_REGISTER_16,
+                DOI_INVALID
+            };
+            break;
+
         case DALVIK_OPT_23X:
             types = (DalvikOperandID []) {
                 DOI_REGISTER_8,
@@ -223,6 +232,14 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat
             };
             break;
 
+        case DALVIK_OPT_31T:
+            types = (DalvikOperandID []) {
+                DOI_REGISTER_8,
+                DOI_TARGET_32,
+                DOI_INVALID
+            };
+            break;
+
         case DALVIK_OPT_51L:
             types = (DalvikOperandID []) {
                 DOI_REGISTER_8,
@@ -253,6 +270,10 @@ static bool dalvik_read_basic_operands(GArchInstruction *instr, const bin_t *dat
                 op = g_dalvik_register_operand_new(data, pos, len, NULL, MDS_8_BITS, endian);
                 break;
 
+            case DOI_REGISTER_16:
+                op = g_dalvik_register_operand_new(data, pos, len, NULL, MDS_16_BITS, endian);
+                break;
+
             case DOI_IMMEDIATE_4:
                 op = _g_imm_operand_new_from_data(MDS_4_BITS, data, pos, len, low, endian);
                 break;
@@ -474,9 +495,11 @@ bool dalvik_read_operands(GArchInstruction *instr, const bin_t *data, off_t *pos
         case DALVIK_OPT_22C:
         case DALVIK_OPT_22S:
         case DALVIK_OPT_22T:
+        case DALVIK_OPT_22X:
         case DALVIK_OPT_23X:
         case DALVIK_OPT_30T:
         case DALVIK_OPT_31I:
+        case DALVIK_OPT_31T:
         case DALVIK_OPT_51L:
             va_start(ap, model);
             result = dalvik_read_basic_operands(instr, data, pos, len, &low, endian, model, ap);
diff --git a/src/arch/dalvik/operand.h b/src/arch/dalvik/operand.h
index a596225..636d7ec 100644
--- a/src/arch/dalvik/operand.h
+++ b/src/arch/dalvik/operand.h
@@ -86,12 +86,14 @@ typedef enum _DalvikOperandType
     DALVIK_OPT_22C      = DALVIK_OP_LEN(2) | DALVIK_OP_REG(2) | 'C',
     DALVIK_OPT_22S      = DALVIK_OP_LEN(2) | DALVIK_OP_REG(2) | 'S',
     DALVIK_OPT_22T      = DALVIK_OP_LEN(2) | DALVIK_OP_REG(2) | 'T',
+    DALVIK_OPT_22X      = DALVIK_OP_LEN(2) | DALVIK_OP_REG(2) | 'X',
 
     DALVIK_OPT_23X      = DALVIK_OP_LEN(2) | DALVIK_OP_REG(3) | 'X',
 
     DALVIK_OPT_30T      = DALVIK_OP_LEN(3) | DALVIK_OP_REG(0) | 'T',
 
     DALVIK_OPT_31I      = DALVIK_OP_LEN(3) | DALVIK_OP_REG(1) | 'I',
+    DALVIK_OPT_31T      = DALVIK_OP_LEN(3) | DALVIK_OP_REG(1) | 'T',
 
     DALVIK_OPT_35C      = DALVIK_OP_LEN(3) | DALVIK_OP_REG(5) | 'C',
 
diff --git a/src/arch/dalvik/processor.c b/src/arch/dalvik/processor.c
index 379fc98..4fd8a2f 100644
--- a/src/arch/dalvik/processor.c
+++ b/src/arch/dalvik/processor.c
@@ -154,6 +154,7 @@ static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProc
 
         [DOP_NOP]                   = dalvik_read_instr_nop,
         [DOP_MOVE]                  = dalvik_read_instr_move,
+        [DOP_MOVE_FROM_16]          = dalvik_read_instr_move_from_16,
 
         [DOP_MOVE_OBJECT]           = dalvik_read_instr_move_object,
 
@@ -182,6 +183,8 @@ static GArchInstruction *g_dalvik_processor_decode_instruction(const GDalvikProc
         [DOP_NEW_INSTANCE]          = dalvik_read_instr_new_instance,
         [DOP_NEW_ARRAY]             = dalvik_read_instr_new_array,
 
+        [DOP_FILL_ARRAY_DATA]       = dalvik_read_instr_fill_array_data,
+
         [DOP_GOTO]                  = dalvik_read_instr_goto,
         [DOP_GOTO_16]               = dalvik_read_instr_goto_16,
         [DOP_GOTO_32]               = dalvik_read_instr_goto_32,
diff --git a/src/format/part.c b/src/format/part.c
index 371c1ef..e42b8d2 100644
--- a/src/format/part.c
+++ b/src/format/part.c
@@ -41,6 +41,11 @@ struct _GBinPart
     off_t size;                             /* Taille de la partie         */
     vmpa_t addr;                            /* Adresse associée            */
 
+#ifdef DEBUG
+    unsigned int valid;                     /* Instructions reconnues      */
+    unsigned int db;                        /* Instructions non traduites  */
+#endif
+
 };
 
 /* Bloc de données binaires quelconques (classe) */
@@ -362,3 +367,50 @@ int g_binary_part_compare(const GBinPart **a, const GBinPart **b)
     return result;
 
 }
+
+#ifdef DEBUG
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : part  = description de partie à mettre à jour.               *
+*                valid = quantité d'instructions décodées pour cette partie.  *
+*                db    = quantité d'instructions non traduites ici.           *
+*                                                                             *
+*  Description : Mémorise un bilan de désassemblage.                          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_part_set_checkup(GBinPart *part, unsigned int valid, unsigned int db)
+{
+    part->valid = valid;
+    part->db = db;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : part  = description de partie à mettre à jour.               *
+*                valid = quantité d'instructions décodées ici. [OUT]          *
+*                db    = quantité d'instructions non traduites ici. [OUT]     *
+*                                                                             *
+*  Description : Mémorise un bilan de désassemblage.                          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_binary_part_get_checkup(const GBinPart *part, unsigned int *valid, unsigned int *db)
+{
+    *valid = part->valid;
+    *db = part->db;
+
+}
+
+#endif
diff --git a/src/format/part.h b/src/format/part.h
index 32d1903..5adeb2b 100644
--- a/src/format/part.h
+++ b/src/format/part.h
@@ -82,6 +82,16 @@ void g_binary_part_get_values(const GBinPart *, off_t *, off_t *, vmpa_t *);
 /* Etablit la comparaison entre deux blocs binaires. */
 int g_binary_part_compare(const GBinPart **, const GBinPart **);
 
+#ifdef DEBUG
+
+/* Mémorise un bilan de désassemblage. */
+void g_binary_part_set_checkup(GBinPart *, unsigned int, unsigned int);
+
+/* Mémorise un bilan de désassemblage. */
+void g_binary_part_get_checkup(const GBinPart *, unsigned int *, unsigned int *);
+
+#endif
+
 
 
 #endif  /* _FORMAT_PART_H */
-- 
cgit v0.11.2-87-g4458