From 2245e2b3c4f4ff96cf462e76e24c04d4d0941996 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 28 Feb 2016 18:39:48 +0100
Subject: Dealt with the prototypes from the Dex pool.

---
 ChangeLog                          |  21 +++++++
 plugins/androhelpers/params.c      |   2 +
 plugins/androhelpers/switch.c      |   2 +
 plugins/androhelpers/try_n_catch.c |   2 +
 src/analysis/variable.c            |   4 +-
 src/arch/dalvik/operands/pool.c    |  15 ++++-
 src/format/dex/dex-int.h           |   1 -
 src/format/dex/dex.c               |   3 -
 src/format/dex/method.c            |  27 ++++++++-
 src/format/dex/method.h            |   2 +-
 src/format/dex/pool.c              | 114 +++++++++++++++----------------------
 src/format/dex/pool.h              |   3 -
 12 files changed, 115 insertions(+), 81 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b75257d..0846995 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
 16-02-28  Cyrille Bagard <nocbos@gmail.com>
 
+	* plugins/androhelpers/params.c:
+	* plugins/androhelpers/switch.c:
+	* plugins/androhelpers/try_n_catch.c:
+	Update code.
+
+	* src/analysis/variable.c:
+	Translate variables into strings again.
+
+	* src/arch/dalvik/operands/pool.c:
+	Print prototypes from the pool when needed.
+
+	* src/format/dex/dex-int.h:
+	* src/format/dex/dex.c:
+	* src/format/dex/method.c:
+	* src/format/dex/method.h:
+	* src/format/dex/pool.c:
+	* src/format/dex/pool.h:
+	Deal with the prototypes from the Dex pool.
+
+16-02-28  Cyrille Bagard <nocbos@gmail.com>
+
 	* plugins/readelf/reader.c:
 	* plugins/readelf/reader.h:
 	Be sure to process relevant only file formats (ELF here).
diff --git a/plugins/androhelpers/params.c b/plugins/androhelpers/params.c
index df56fca..4bf2f6b 100644
--- a/plugins/androhelpers/params.c
+++ b/plugins/androhelpers/params.c
@@ -143,6 +143,8 @@ static void visit_all_method_operands(const GDexMethod *method, GArchInstruction
     start = g_binary_routine_get_address(routine);
     end = start + g_binary_routine_get_size(routine);
 
+    g_object_unref(G_OBJECT(routine));
+
     for (iter = g_arch_instruction_find_by_address(instrs, start, true);
          iter != NULL;
          iter = g_arch_instruction_get_next_iter(instrs, iter, end))
diff --git a/plugins/androhelpers/switch.c b/plugins/androhelpers/switch.c
index a5a8a75..8387962 100644
--- a/plugins/androhelpers/switch.c
+++ b/plugins/androhelpers/switch.c
@@ -341,6 +341,8 @@ static void look_for_switch_instructions(const GDexMethod *method, GArchInstruct
     start = g_binary_routine_get_address(routine);
     end = start + g_binary_routine_get_size(routine);
 
+    g_object_unref(G_OBJECT(routine));
+
     for (iter = g_arch_instruction_find_by_address(instrs, start, true);
          iter != NULL;
          iter = g_arch_instruction_get_next_iter(instrs, iter, end))
diff --git a/plugins/androhelpers/try_n_catch.c b/plugins/androhelpers/try_n_catch.c
index d2c6043..83be896 100644
--- a/plugins/androhelpers/try_n_catch.c
+++ b/plugins/androhelpers/try_n_catch.c
@@ -394,6 +394,8 @@ static void look_for_exception_handlers(const GLoadedBinary *binary, const GDexF
     if (handlers != NULL) free(handlers);
     if (count != NULL) free(count);
 
+    g_object_unref(G_OBJECT(routine));
+
 }
 
 
diff --git a/src/analysis/variable.c b/src/analysis/variable.c
index a8f1ba5..d547281 100644
--- a/src/analysis/variable.c
+++ b/src/analysis/variable.c
@@ -254,9 +254,9 @@ char *g_binary_variable_to_string(const GBinVariable *var, bool simple)
     char *result;                           /* Valeur à retourner          */
 
     /* FIXME : décompilation sans type ! */
-    //result = _g_data_type_to_string(var->type, simple);
+    result = _g_data_type_to_string(var->type, simple);
 
-    result = strdup("");
+    //result = strdup("");
 
     if (var->name != NULL)
     {
diff --git a/src/arch/dalvik/operands/pool.c b/src/arch/dalvik/operands/pool.c
index 0d88242..7de8c37 100644
--- a/src/arch/dalvik/operands/pool.c
+++ b/src/arch/dalvik/operands/pool.c
@@ -237,6 +237,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff
     size_t len;                             /* Taille du texte à créer     */
     char *tmp;                              /* Chaîne de caractères #2     */
     GBinVariable *field;                    /* Champ à représenter         */
+    GDexMethod *method;                     /* Méthode à retrouver         */
     GBinRoutine *routine;                   /* Routine à représenter       */
 
     switch (operand->type)
@@ -246,6 +247,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff
             break;
 
         case DPT_STRING:
+
             string = get_string_from_dex_pool(operand->format, operand->index);
 
             if (string != NULL)
@@ -269,6 +271,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff
             break;
 
         case DPT_TYPE:
+
             type = get_type_from_dex_pool(operand->format, operand->index);
 
             if (type != NULL)
@@ -300,6 +303,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff
             break;
 
         case DPT_FIELD:
+
             field = get_field_from_dex_pool(operand->format, operand->index);
 
             if (field != NULL)
@@ -327,7 +331,13 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff
             break;
 
         case DPT_METHOD:
-            routine = NULL;//get_routine_from_dex_pool(operand->format, operand->index);
+
+            method = get_method_from_dex_pool(operand->format, operand->index);
+
+            if (method != NULL)
+                routine = g_dex_method_get_routine(method);
+            else
+                routine = NULL;
 
             if (routine != NULL)
             {
@@ -351,6 +361,9 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff
 
             free(tmp);
 
+            if (method != NULL)
+                g_object_unref(G_OBJECT(method));
+
             break;
 
     }
diff --git a/src/format/dex/dex-int.h b/src/format/dex/dex-int.h
index 28aadd5..a5f39a6 100755
--- a/src/format/dex/dex-int.h
+++ b/src/format/dex/dex-int.h
@@ -43,7 +43,6 @@ struct _GDexFormat
 
     GDataType **types;                      /* Types partagés pour Dalvik  */
     GBinVariable **fields;                  /* Champs de données partagés  */
-    GBinRoutine **prototypes;               /* Routines vierges à décorer  */
     GDexMethod **methods;                   /* Méthodes retrouvées         */
     GDexClass **classes;                    /* Classes retrouvées          */
 
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index 764b6dc..a918c31 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -267,9 +267,6 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent)
     if (!load_all_dex_fields(result))
         goto gdfn_error;
 
-    if (!load_all_dex_prototypes(result))
-        goto gdfn_error;
-
     if (!load_all_dex_methods(result))
         goto gdfn_error;
 
diff --git a/src/format/dex/method.c b/src/format/dex/method.c
index 316f094..bc4a063 100644
--- a/src/format/dex/method.c
+++ b/src/format/dex/method.c
@@ -24,6 +24,9 @@
 #include "method.h"
 
 
+#include <string.h>
+
+
 #include <i18n.h>
 
 
@@ -40,6 +43,7 @@ struct _GDexMethod
 
     GBinRoutine *routine;                   /* Représentation interne      */
 
+    /* FIXME : méthode interne seulement */
     encoded_method info;                    /* Propriétés de la méthode    */
     code_item body;                         /* Corps de la méthode         */
     off_t offset;                           /* Position du code            */
@@ -220,14 +224,27 @@ GDexMethod *g_dex_method_new(GDexFormat *format, const encoded_method *seed, ule
 *                                                                             *
 ******************************************************************************/
 
-GDexMethod *g_dex_method_new_empty(const GDexFormat *format, const method_id_item *method_id)
+GDexMethod *g_dex_method_new_empty(GDexFormat *format, const method_id_item *method_id)
 {
     GDexMethod *result;                     /* Composant à retourner       */
+    const char *name;                       /* Nom de la routine finale    */
+    GBinRoutine *routine;                   /* Routine représentée         */
 
+    result = NULL;
 
+    name = get_string_from_dex_pool(format, method_id->name_idx);
+    if (name == NULL) goto gdmne_exit;
+
+    routine = get_prototype_from_dex_pool(format, method_id->proto_idx);
+    if (routine == NULL) goto gdmne_exit;
+
+    g_binary_routine_set_name(routine, strdup(name));
 
     result = g_object_new(G_TYPE_DEX_METHOD, NULL);
 
+    result->routine = routine;
+
+ gdmne_exit:
 
     return result;
 
@@ -286,7 +303,13 @@ const code_item *g_dex_method_get_dex_body(const GDexMethod *method)
 
 GBinRoutine *g_dex_method_get_routine(const GDexMethod *method)
 {
-    return method->routine;
+    GBinRoutine *result;                    /* Instance à retourner        */
+
+    result = method->routine;
+
+    g_object_ref(G_OBJECT(result));
+
+    return result;
 
 }
 
diff --git a/src/format/dex/method.h b/src/format/dex/method.h
index 4ed3960..cb85bc6 100644
--- a/src/format/dex/method.h
+++ b/src/format/dex/method.h
@@ -70,7 +70,7 @@ GType g_dex_method_get_type(void);
 GDexMethod *g_dex_method_new(GDexFormat *, const encoded_method *, uleb128_t *);
 
 /* Crée une nouvelle représentation de methode vide. */
-GDexMethod *g_dex_method_new_empty(const GDexFormat *, const method_id_item *);
+GDexMethod *g_dex_method_new_empty(GDexFormat *, const method_id_item *);
 
 /* Fournit les indications Dex concernant la méthode. */
 const encoded_method *g_dex_method_get_dex_info(const GDexMethod *);
diff --git a/src/format/dex/pool.c b/src/format/dex/pool.c
index 1724dd9..056443e 100644
--- a/src/format/dex/pool.c
+++ b/src/format/dex/pool.c
@@ -342,44 +342,6 @@ GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : format = représentation interne du format DEX à compléter.   *
-*                                                                             *
-*  Description : Charge tous les prototypes listés dans le contenu binaire.   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool load_all_dex_prototypes(GDexFormat *format)
-{
-    bool result;                            /* Bilan à retourner           */
-    uint32_t i;                             /* Boucle de parcours          */
-    GBinRoutine *proto;                     /* Prototype récupéré          */
-
-    result = true;
-
-    format->prototypes = (GBinRoutine **)calloc(format->header.proto_ids_size, sizeof(GBinRoutine *));
-
-    for (i = 0; i < format->header.proto_ids_size && result; i++)
-    {
-        proto = get_prototype_from_dex_pool(format, i);
-
-        if (proto != NULL)
-            g_object_unref(G_OBJECT(proto));
-        else
-            result = false;
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
 *  Paramètres  : format = représentation interne du format DEX à consulter.   *
 *                index  = index de la routine recherchée.                     *
 *                                                                             *
@@ -405,56 +367,72 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)
 
     result = NULL;
 
-    if (index >= format->header.method_ids_size)
+    /**
+     * Les prototypes sont personnalisés après chargement.
+     * Donc on ne peut pas conserver de version globale comme pour
+     * les autres éléments de la table des constantes.
+     */
+
+    if (index >= format->header.proto_ids_size)
         goto grfdp_error;
 
-    if (format->prototypes[index] == NULL)
-    {
-        pos = format->header.proto_ids_off + index * sizeof(proto_id_item);
-        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
+    pos = format->header.proto_ids_off + index * sizeof(proto_id_item);
+    init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
 
-        if (!read_dex_proto_id_item(format, &addr, &proto_id))
-            goto grfdp_error;
+    if (!read_dex_proto_id_item(format, &addr, &proto_id))
+        goto grfdp_error;
 
-        /* Type de retour */
+    /* Type de retour */
 
-        type = get_type_from_dex_pool(format, proto_id.return_type_idx);
+    type = get_type_from_dex_pool(format, proto_id.return_type_idx);
 
-        /* Nom de la méthode */
+    /* Nom de la méthode */
 
-        name = get_string_from_dex_pool(format, proto_id.shorty_idx);
+    name = get_string_from_dex_pool(format, proto_id.shorty_idx);
 
-        /* Liste des arguments */
+    /* Liste des arguments */
 
-        pos = proto_id.parameters_off;
-        init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
+    pos = proto_id.parameters_off;
+    init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
 
-        if (read_dex_type_list(format, &addr, &args))
-            for (i = 0; i < args.size; i++)
-            {
-                type = get_type_from_dex_pool(format, args.list[i].type_idx);
-                if (type == NULL) continue;
+    result = g_binary_routine_new();///////////////////////
 
-                arg = g_binary_variable_new(type);
-                //g_binary_routine_add_arg(result, arg);
+    if (read_dex_type_list(format, &addr, &args))
+        for (i = 0; i < args.size; i++)
+        {
+            type = get_type_from_dex_pool(format, args.list[i].type_idx);
+            if (type == NULL) continue;
 
-            }
+            printf(" ++ PROTO POOL ++ type '%s'\n", g_data_type_to_string(type));
 
-        /* Mise en place finale */
+            arg = g_binary_variable_new(type);
+            g_binary_routine_add_arg(result, arg);///////////////////////
 
-        format->prototypes[index] = demangle_routine(G_TYPE_DEX_DEMANGLER, name);
+            printf(" ++ PROTO POOL ++ arg '%s'\n", g_binary_variable_to_string(arg, true));
 
-#if 0
-        if (format->prototypes[index] != NULL)
-            g_binary_routine_set_return_type(format->prototypes[index], type);
-#endif
+        }
 
-    }
+    /* Mise en place finale */
 
-    result = format->prototypes[index];
+    ///////result = demangle_routine(G_TYPE_DEX_DEMANGLER, name);
+
+    g_binary_routine_set_name(result, strdup("..."));
+
+    printf(" PROTO POOL //    from   %s   to   %s\n",
+           name,
+           result == NULL ? NULL :
+           g_binary_routine_to_string(result));
+
+
+#if 1
+    if (result != NULL)///////////////////////
+        g_binary_routine_set_return_type(result, type);
+#endif
 
+    /*
     if (result != NULL)
         g_object_ref(G_OBJECT(result));
+    */
 
  grfdp_error:
 
diff --git a/src/format/dex/pool.h b/src/format/dex/pool.h
index df02ed8..8043153 100644
--- a/src/format/dex/pool.h
+++ b/src/format/dex/pool.h
@@ -54,9 +54,6 @@ bool load_all_dex_fields(GDexFormat *);
 /* Extrait une représentation de champ d'une table DEX. */
 GBinVariable *get_field_from_dex_pool(GDexFormat *, uint32_t);
 
-/* Charge tous les prototypes listés dans le contenu binaire. */
-bool load_all_dex_prototypes(GDexFormat *);
-
 /* Extrait une représentation de routine d'une table DEX. */
 GBinRoutine *get_prototype_from_dex_pool(GDexFormat *, uint32_t);
 
-- 
cgit v0.11.2-87-g4458