summaryrefslogtreecommitdiff
path: root/src/format/dex
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/dex')
-rwxr-xr-xsrc/format/dex/Makefile.am1
-rwxr-xr-xsrc/format/dex/dex.c9
-rw-r--r--src/format/dex/loading.c240
-rw-r--r--src/format/dex/loading.h61
-rw-r--r--src/format/dex/pool.c120
-rw-r--r--src/format/dex/pool.h6
6 files changed, 403 insertions, 34 deletions
diff --git a/src/format/dex/Makefile.am b/src/format/dex/Makefile.am
index 7a2416f..28f8e73 100755
--- a/src/format/dex/Makefile.am
+++ b/src/format/dex/Makefile.am
@@ -6,6 +6,7 @@ libformatdex_la_SOURCES = \
dex-int.h dex-int.c \
dex.h dex.c \
dex_def.h \
+ loading.h loading.c \
method.h method.c \
pool.h pool.c
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index 582390a..d02111c 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -248,6 +248,7 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus
GDexFormat *result; /* Structure à retourner */
GBinFormat *base; /* Version basique du format */
vmpa2t pos; /* Position de tête de lecture */
+ wgroup_id_t gid; /* Identifiant pour les tâches */
result = g_object_new(G_TYPE_DEX_FORMAT, NULL);
@@ -265,13 +266,15 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus
/* TODO : vérifier que les *_id ne se chevauchent pas */
- if (!load_all_dex_types(result, status))
+ gid = g_work_queue_define_work_group(get_work_queue());
+
+ if (!load_all_dex_types(result, gid, status))
goto gdfn_error;
- if (!load_all_dex_fields(result, status))
+ if (!load_all_dex_fields(result, gid, status))
goto gdfn_error;
- if (!load_all_dex_classes(result, status))
+ if (!load_all_dex_classes(result, gid, status))
goto gdfn_error;
if (!g_binary_format_complete_loading(base, status))
diff --git a/src/format/dex/loading.c b/src/format/dex/loading.c
new file mode 100644
index 0000000..a5b675d
--- /dev/null
+++ b/src/format/dex/loading.c
@@ -0,0 +1,240 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loading.c - chargements parallèles des éléments de la table globale du format Dex
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * 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 "loading.h"
+
+
+#include <i18n.h>
+
+
+#include "pool.h"
+#include "../../glibext/delayed-int.h"
+#include "../../gui/panels/log.h"
+
+
+
+/* Fraction de routines à limiter (instance) */
+struct _GDexLoading
+{
+ GDelayedWork parent; /* A laisser en premier */
+
+ GDexFormat *format; /* Format à faire évoluer */
+
+ dex_loading_cb callback; /* Routine de traitement finale*/
+ uint32_t begin; /* Point de départ du parcours */
+ uint32_t end; /* Point d'arrivée exclu */
+
+ activity_id_t id; /* Identifiant pour messages */
+
+ bool *status; /* Bilan global constitué */
+
+};
+
+/* Fraction de routines à limiter (classe) */
+struct _GDexLoadingClass
+{
+ GDelayedWorkClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des tâches des chargements pour DEX. */
+static void g_dex_loading_class_init(GDexLoadingClass *);
+
+/* Initialise une tâche de chargements pour DEX. */
+static void g_dex_loading_init(GDexLoading *);
+
+/* Supprime toutes les références externes. */
+static void g_dex_loading_dispose(GDexLoading *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_dex_loading_finalize(GDexLoading *);
+
+/* Assure le chargement pour un format DEX en différé. */
+static void g_dex_loading_process(GDexLoading *, GtkStatusStack *);
+
+
+
+/* Indique le type défini pour les tâches de chargements pour format DEX. */
+G_DEFINE_TYPE(GDexLoading, g_dex_loading, G_TYPE_DELAYED_WORK);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des tâches des chargements pour DEX. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_loading_class_init(GDexLoadingClass *klass)
+{
+ GObjectClass *object; /* Autre version de la classe */
+ GDelayedWorkClass *work; /* Version en classe parente */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_loading_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dex_loading_finalize;
+
+ work = G_DELAYED_WORK_CLASS(klass);
+
+ work->run = (run_task_fc)g_dex_loading_process;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = instance à initialiser. *
+* *
+* Description : Initialise une tâche de chargements pour DEX. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_loading_init(GDexLoading *loading)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_loading_dispose(GDexLoading *loading)
+{
+ G_OBJECT_CLASS(g_dex_loading_parent_class)->dispose(G_OBJECT(loading));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : loading = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_loading_finalize(GDexLoading *loading)
+{
+ G_OBJECT_CLASS(g_dex_loading_parent_class)->finalize(G_OBJECT(loading));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = = ensemble d'instructions désassemblées. *
+* begin = point de départ du parcours de liste. *
+* end = point d'arrivée exclu du parcours. *
+* id = identifiant du message affiché à l'utilisateur. *
+* callback = routine de traitements particuliers. *
+* status = bilan final à constituer. [OUT] *
+* *
+* Description : Crée une tâche de chargement pour DEX différée. *
+* *
+* Retour : Tâche créée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDexLoading *g_dex_loading_new(GDexFormat *format, uint32_t begin, uint32_t end, activity_id_t id, dex_loading_cb callback, bool *status)
+{
+ GDexLoading *result; /* Tâche à retourner */
+
+ result = g_object_new(G_TYPE_DEX_LOADING, NULL);
+
+ result->format = format;
+
+ result->callback = callback;
+ result->begin = begin;
+ result->end = end;
+
+ result->id = id;
+
+ result->status = status;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : study = étude de routines à mener. *
+* status = barre de statut à tenir informée. *
+* *
+* Description : Assure le chargement pour un format DEX en différé. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_loading_process(GDexLoading *loading, GtkStatusStack *status)
+{
+ uint32_t i; /* Boucle de parcours */
+ GObject *obj; /* Object chargé en mémoire */
+
+ for (i = loading->begin; i < loading->end && *(loading->status); i++)
+ {
+ obj = loading->callback(loading->format, i);
+
+ if (obj != NULL)
+ g_object_unref(obj);
+
+ else
+ {
+ *(loading->status) = false;
+ log_variadic_message(LMT_ERROR, _("Error while loading Dex pool item #%u!"), i);
+ }
+
+ gtk_status_stack_update_activity_value(status, loading->id, 1);
+
+ }
+
+}
diff --git a/src/format/dex/loading.h b/src/format/dex/loading.h
new file mode 100644
index 0000000..4c055ce
--- /dev/null
+++ b/src/format/dex/loading.h
@@ -0,0 +1,61 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * loading.h - prototypes pour les chargements parallèles des éléments de la table globale du format Dex
+ *
+ * Copyright (C) 2016 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * 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/>.
+ */
+
+
+#ifndef _FORMAT_DEX_LOADING_H
+#define _FORMAT_DEX_LOADING_H
+
+
+#include "dex.h"
+#include "../../gtkext/gtkstatusstack.h"
+
+
+
+#define G_TYPE_DEX_LOADING g_dex_loading_get_type()
+#define G_DEX_LOADING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dex_loading_get_type(), GDexLoading))
+#define G_IS_DEX_LOADING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dex_loading_get_type()))
+#define G_DEX_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_LOADING, GDexLoadingClass))
+#define G_IS_DEX_LOADING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_LOADING))
+#define G_DEX_LOADING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_LOADING, GDexLoadingClass))
+
+
+/* Fraction de loading à limiter (instance) */
+typedef struct _GDexLoading GDexLoading;
+
+/* Fraction de loading à limiter (classe) */
+typedef struct _GDexLoadingClass GDexLoadingClass;
+
+
+
+/* Extrait une représentation générique d'une table Dex. */
+typedef GObject * (* dex_loading_cb) (GDexFormat *, uint32_t);
+
+
+/* Indique le type défini pour les tâches de chargements pour format DEX. */
+GType g_dex_loading_get_type(void);
+
+/* Crée une tâche de chargement pour DEX différée. */
+GDexLoading *g_dex_loading_new(GDexFormat *, uint32_t, uint32_t, activity_id_t, dex_loading_cb, bool *);
+
+
+
+#endif /* _FORMAT_DEX_LOADING_H */
diff --git a/src/format/dex/pool.c b/src/format/dex/pool.c
index 7574638..769a4f1 100644
--- a/src/format/dex/pool.c
+++ b/src/format/dex/pool.c
@@ -32,6 +32,7 @@
#include "dex-int.h"
+#include "loading.h"
#include "../mangling/demangler.h"
#include "../mangling/dex/context.h"
@@ -125,6 +126,7 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* gid = groupe de travail impliqué. *
status = barre de statut à tenir informée. *
* *
* Description : Charge en mémoire l'ensemble des types du format DEX. *
@@ -135,33 +137,53 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)
* *
******************************************************************************/
-bool load_all_dex_types(GDexFormat *format, GtkStatusStack *status)
+bool load_all_dex_types(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 */
- uint32_t i; /* Boucle de parcours */
- GDataType *type; /* Type récupéré */
+ 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*/
result = true;
+ /* Préparation du réceptacle */
+
format->types = (GDataType **)calloc(format->header.type_ids_size, sizeof(GDataType *));
+ /* Lancement des chargements */
+
+ runs_count = g_get_num_processors();
+
+ run_size = format->header.type_ids_size / runs_count;
+
+ queue = get_work_queue();
+
msg = gtk_status_stack_add_activity(status, _("Loading all types from the Dex pool..."),
format->header.type_ids_size);
- for (i = 0; i < format->header.type_ids_size && result; i++)
+ for (i = 0; i < runs_count; i++)
{
- type = get_type_from_dex_pool(format, i);
+ begin = i * run_size;
- if (type != NULL)
- g_object_unref(G_OBJECT(type));
+ if ((i + 1) == runs_count)
+ end = format->header.type_ids_size;
else
- result = false;
+ end = begin + run_size;
+
+ loading = g_dex_loading_new(format, begin, end, msg,
+ (dex_loading_cb)get_type_from_dex_pool, &result);
- gtk_status_stack_update_activity_value(status, msg, 1);
+ 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;
@@ -235,6 +257,7 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
+* gid = groupe de travail impliqué. *
* status = barre de statut à tenir informée. *
* *
* Description : Charge en mémoire l'ensemble des champs du format DEX. *
@@ -245,33 +268,53 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)
* *
******************************************************************************/
-bool load_all_dex_fields(GDexFormat *format, GtkStatusStack *status)
+bool load_all_dex_fields(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 */
- uint32_t i; /* Boucle de parcours */
- GBinVariable *field; /* Champ récupéré */
+ 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*/
result = true;
+ /* Préparation du réceptacle */
+
format->fields = (GBinVariable **)calloc(format->header.field_ids_size, sizeof(GBinVariable *));
+ /* Lancement des chargements */
+
+ runs_count = g_get_num_processors();
+
+ run_size = format->header.field_ids_size / runs_count;
+
+ queue = get_work_queue();
+
msg = gtk_status_stack_add_activity(status, _("Loading all fields from the Dex pool..."),
format->header.field_ids_size);
- for (i = 0; i < format->header.field_ids_size && result; i++)
+ for (i = 0; i < runs_count; i++)
{
- field = get_field_from_dex_pool(format, i);
+ begin = i * run_size;
- if (field != NULL)
- g_object_unref(G_OBJECT(field));
+ if ((i + 1) == runs_count)
+ end = format->header.field_ids_size;
else
- result = false;
+ end = begin + run_size;
+
+ loading = g_dex_loading_new(format, begin, end, msg,
+ (dex_loading_cb)get_field_from_dex_pool, &result);
- gtk_status_stack_update_activity_value(status, msg, 1);
+ 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;
@@ -506,7 +549,8 @@ GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index)
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à compléter. *
-* status = barre de statut à tenir informée. *
+* gid = groupe de travail impliqué. *
+ status = barre de statut à tenir informée. *
* *
* Description : Charge toutes les classes listées dans le contenu binaire. *
* *
@@ -516,33 +560,53 @@ GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index)
* *
******************************************************************************/
-bool load_all_dex_classes(GDexFormat *format, GtkStatusStack *status)
+bool load_all_dex_classes(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 */
- uint32_t i; /* Boucle de parcours */
- GDexClass *class; /* Classe récupérée */
+ 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*/
result = true;
+ /* Préparation du réceptacle */
+
format->classes = (GDexClass **)calloc(format->header.class_defs_size, sizeof(GDexClass *));
+ /* Lancement des chargements */
+
+ runs_count = g_get_num_processors();
+
+ run_size = format->header.class_defs_size / runs_count;
+
+ queue = get_work_queue();
+
msg = gtk_status_stack_add_activity(status, _("Loading all classes from the Dex pool..."),
format->header.class_defs_size);
- for (i = 0; i < format->header.class_defs_size && result; i++)
+ for (i = 0; i < runs_count; i++)
{
- class = get_class_from_dex_pool(format, i);
+ begin = i * run_size;
- if (class != NULL)
- g_object_unref(G_OBJECT(class));
+ if ((i + 1) == runs_count)
+ end = format->header.class_defs_size;
else
- result = false;
+ end = begin + run_size;
+
+ loading = g_dex_loading_new(format, begin, end, msg,
+ (dex_loading_cb)get_class_from_dex_pool, &result);
- gtk_status_stack_update_activity_value(status, msg, 1);
+ 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;
diff --git a/src/format/dex/pool.h b/src/format/dex/pool.h
index 4b804cc..cd4c2de 100644
--- a/src/format/dex/pool.h
+++ b/src/format/dex/pool.h
@@ -43,13 +43,13 @@ const char *get_string_from_dex_pool(const GDexFormat *, uint32_t);
/* Charge en mémoire l'ensemble des types du format DEX. */
-bool load_all_dex_types(GDexFormat *, GtkStatusStack *);
+bool load_all_dex_types(GDexFormat *, wgroup_id_t, GtkStatusStack *);
/* Extrait une représentation de type d'une table DEX. */
GDataType *get_type_from_dex_pool(GDexFormat *, uint32_t);
/* Charge en mémoire l'ensemble des champs du format DEX. */
-bool load_all_dex_fields(GDexFormat *, GtkStatusStack *);
+bool load_all_dex_fields(GDexFormat *, wgroup_id_t, GtkStatusStack *);
/* Extrait une représentation de champ d'une table DEX. */
GBinVariable *get_field_from_dex_pool(GDexFormat *, uint32_t);
@@ -61,7 +61,7 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *, uint32_t);
GDexMethod *get_method_from_dex_pool(GDexFormat *, uint32_t);
/* Charge toutes les classes listées dans le contenu binaire. */
-bool load_all_dex_classes(GDexFormat *, GtkStatusStack *);
+bool load_all_dex_classes(GDexFormat *, wgroup_id_t, GtkStatusStack *);
/* Extrait une représentation de classe d'une table DEX. */
GDexClass *get_class_from_dex_pool(GDexFormat *, uint32_t);