summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-07-23 07:45:44 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-07-23 07:45:44 (GMT)
commit53213051036151645ae287436ad94dff92c7fa20 (patch)
tree874679c64017fcc7eafa8c5af447c9e15fcbaa5d
parente335c19df11cf013c8e515105ca2a13afa2b97de (diff)
Changed the way Dex methods are loaded and displayed.
-rw-r--r--plugins/dalvik/operands/pool.c6
-rw-r--r--plugins/dex/dex-int.h1
-rw-r--r--plugins/dex/format.c3
-rw-r--r--plugins/dex/method.c18
-rw-r--r--plugins/dex/pool.c122
-rw-r--r--plugins/dex/pool.h3
6 files changed, 129 insertions, 24 deletions
diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c
index 6e4229b..f4fe1fa 100644
--- a/plugins/dalvik/operands/pool.c
+++ b/plugins/dalvik/operands/pool.c
@@ -377,12 +377,10 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff
if (routine != NULL)
{
- tmp = g_binary_routine_to_string(routine, true);
+ tmp = g_binary_symbol_get_label(G_BIN_SYMBOL(routine));
g_object_unref(G_OBJECT(routine));
- g_buffer_line_append_text(line, BLC_ASSEMBLY, "<", 1, RTT_HOOK, NULL);
- g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_VAR_NAME, G_OBJECT(operand));
- g_buffer_line_append_text(line, BLC_ASSEMBLY, ">", 1, RTT_HOOK, NULL);
+ g_buffer_line_append_text(line, BLC_ASSEMBLY, tmp, strlen(tmp), RTT_LABEL, G_OBJECT(operand));
}
else
diff --git a/plugins/dex/dex-int.h b/plugins/dex/dex-int.h
index 5180b58..48a920c 100644
--- a/plugins/dex/dex-int.h
+++ b/plugins/dex/dex-int.h
@@ -44,6 +44,7 @@ struct _GDexFormat
GBinSymbol **strings; /* Symboles pour les chaînes */
GDataType **types; /* Types partagés pour Dalvik */
GBinVariable **fields; /* Champs de données partagés */
+ GDexMethod **methods; /* Méthodes déclarées */
GDexClass **classes; /* Classes retrouvées */
};
diff --git a/plugins/dex/format.c b/plugins/dex/format.c
index af005e6..d354ad0 100644
--- a/plugins/dex/format.c
+++ b/plugins/dex/format.c
@@ -405,6 +405,9 @@ static bool g_dex_format_analyze(GDexFormat *format, wgroup_id_t gid, GtkStatusS
if (!load_all_dex_fields(format, gid, status))
goto gdfa_error;
+ if (!load_all_dex_methods(format, gid, status))
+ goto gdfa_error;
+
if (!load_all_dex_classes(format, gid, status))
goto gdfa_error;
diff --git a/plugins/dex/method.c b/plugins/dex/method.c
index 5b7b30e..e5f6273 100644
--- a/plugins/dex/method.c
+++ b/plugins/dex/method.c
@@ -49,6 +49,10 @@ struct _GDexMethod
* en place à partir du constructeur g_dex_method_new_defined().
*/
+#ifndef NDEBUG
+ bool already_defined; /* Vérofication d'unicité */
+#endif
+
encoded_method info; /* Propriétés de la méthode */
bool has_body; /* Indication de présence */
code_item body; /* Corps de la méthode */
@@ -120,6 +124,9 @@ static void g_dex_method_class_init(GDexMethodClass *class)
static void g_dex_method_init(GDexMethod *method)
{
+#ifndef NDEBUG
+ method->already_defined = false;
+#endif
}
@@ -197,6 +204,11 @@ GDexMethod *g_dex_method_new_defined(GDexFormat *format, const encoded_method *s
if (result == NULL)
return NULL;
+#ifndef NDEBUG
+ assert(!result->already_defined);
+ result->already_defined = true;
+#endif
+
result->info = *seed;
result->has_body = (seed->code_off > 0);
@@ -253,17 +265,23 @@ GDexMethod *g_dex_method_new_defined(GDexFormat *format, const encoded_method *s
GDexMethod *g_dex_method_new_callable(GDexFormat *format, const method_id_item *method_id)
{
GDexMethod *result; /* Composant à retourner */
+ GDataType *ns; /* Espace d'appartenance */
const char *name; /* Nom de la routine finale */
GBinRoutine *routine; /* Routine représentée */
result = NULL;
+ ns = get_type_from_dex_pool(format, method_id->class_idx);
+
name = get_string_from_dex_pool(format, method_id->name_idx, NULL);
if (name == NULL) goto gdmne_exit;
routine = get_prototype_from_dex_pool(format, method_id->proto_idx);
if (routine == NULL) goto gdmne_exit;
+ if (ns != NULL)
+ g_binary_routine_set_namespace(routine, ns, strdup("."));
+
g_binary_routine_set_name(routine, strdup(name));
result = g_object_new(G_TYPE_DEX_METHOD, NULL);
diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c
index 8a421b2..75841df 100644
--- a/plugins/dex/pool.c
+++ b/plugins/dex/pool.c
@@ -711,6 +711,93 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)
/******************************************************************************
* *
+* Paramètres : format = représentation interne du format DEX à compléter. *
+* gid = groupe de travail impliqué. *
+ status = barre de statut à tenir informée. *
+* *
+* Description : Charge toutes les classes listées dans le contenu binaire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_all_dex_methods(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status)
+{
+ bool result; /* Bilan à retourner */
+ guint runs_count; /* Qté d'exécutions parallèles */
+ uint32_t run_size; /* Volume réparti par exécution*/
+ GWorkQueue *queue; /* Gestionnaire de différés */
+ activity_id_t msg; /* Message de progression */
+ guint i; /* Boucle de parcours */
+ uint32_t begin; /* Début de bloc de traitement */
+ uint32_t end; /* Fin d'un bloc de traitement */
+ GDexLoading *loading; /* Tâche de chargement à lancer*/
+
+ /**
+ * Il existe deux voies pour récupérer une méthode :
+ *
+ * - depuis 'method_id_item', qui précise classe d'appartenance, prototype
+ * et nom.
+ *
+ * - depuis 'encoded_method', qui contient une définition 'method_id_item',
+ * ainsi que des attributs propres à la méthode visée.
+ *
+ * Techniquement, il peut donc y avoir plusieurs variations d'un même
+ * 'method_id_item' selon différents 'encoded_method'.
+ *
+ * Dans la pratique, c'est hautement improbable : une méthode ne peut pas
+ * être privée et publique par exemple, ou renvoyer vers différents code.
+ *
+ * Donc on se permet d'associer une unique méthode par 'method_id_item',
+ * et de précharger le tout.
+ */
+
+ result = true;
+
+ /* Préparation du réceptacle */
+
+ format->methods = (GDexMethod **)calloc(format->header.method_ids_size, sizeof(GDexMethod *));
+
+ /* Lancement des chargements */
+
+ runs_count = get_max_online_threads();
+
+ run_size = format->header.method_ids_size / runs_count;
+
+ queue = get_work_queue();
+
+ msg = gtk_status_stack_add_activity(status, _("Loading all methods from the Dex pool..."),
+ format->header.method_ids_size);
+
+ for (i = 0; i < runs_count; i++)
+ {
+ begin = i * run_size;
+
+ if ((i + 1) == runs_count)
+ end = format->header.method_ids_size;
+ else
+ end = begin + run_size;
+
+ loading = g_dex_loading_new(format, begin, end, msg,
+ (dex_loading_cb)get_method_from_dex_pool, &result);
+
+ g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid);
+
+ }
+
+ g_work_queue_wait_for_completion(queue, gid);
+
+ gtk_status_stack_remove_activity(status, msg);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = représentation interne du format DEX à consulter. *
* *
* Description : Compte le nombre de méthodes dans une table DEX. *
@@ -735,7 +822,7 @@ uint32_t count_methods_in_dex_pool(const GDexFormat *format)
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
-* index = index de la classe recherchée. *
+* index = index de la méthode recherchée. *
* *
* Description : Extrait une représentation de méthode d'une table DEX. *
* *
@@ -748,36 +835,31 @@ uint32_t count_methods_in_dex_pool(const GDexFormat *format)
GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index)
{
GDexMethod *result; /* Instance à retourner */
- uint32_t count; /* Nombre d'éléments présents */
phys_t pos; /* Tête de lecture */
vmpa2t addr; /* Tête de lecture générique */
method_id_item method_id; /* Définition de la méthode */
result = NULL;
- count = count_methods_in_dex_pool(format);
-
- if (index >= count)
+ if (index >= format->header.method_ids_size)
goto gmfdp_error;
- /**
- * On charge ici une méthode à partir de la définition de 'method_id_item'.
- *
- * C'est l'élément 'encoded_method' qui référence cette cette définition et qui
- * applique ensuite les attributs finaux de la méthode. La classe parente est
- * précisée en outre bien en amont.
- *
- * Comme une même définition peut donc servir à plusieurs instances,
- * on ne peut pas conserver un tableau d'allocations communes.
- */
+ if (format->methods[index] == NULL)
+ {
+ pos = format->header.method_ids_off + index * sizeof(method_id_item);
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- pos = format->header.method_ids_off + index * sizeof(method_id_item);
- init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
+ if (!read_dex_method_id_item(format, &addr, &method_id))
+ goto gmfdp_error;
- if (!read_dex_method_id_item(format, &addr, &method_id))
- goto gmfdp_error;
+ format->methods[index] = g_dex_method_new_callable(format, &method_id);
- result = g_dex_method_new_callable(format, &method_id);
+ }
+
+ result = format->methods[index];
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
gmfdp_error:
diff --git a/plugins/dex/pool.h b/plugins/dex/pool.h
index ac7db60..dd27f94 100644
--- a/plugins/dex/pool.h
+++ b/plugins/dex/pool.h
@@ -71,6 +71,9 @@ uint32_t count_prototypes_in_dex_pool(const GDexFormat *);
/* Extrait une représentation de routine d'une table DEX. */
GBinRoutine *get_prototype_from_dex_pool(GDexFormat *, uint32_t);
+/* Charge toutes les classes listées dans le contenu binaire. */
+bool load_all_dex_methods(GDexFormat *, wgroup_id_t, GtkStatusStack *);
+
/* Compte le nombre de méthodes dans une table DEX. */
uint32_t count_methods_in_dex_pool(const GDexFormat *);