From b92a5e56de9198c08956ce486cd12712d7034731 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 4 May 2019 19:56:33 +0200 Subject: Created a GLib object for the Dex pool. --- plugins/dalvik/link.c | 14 +- plugins/dalvik/operands/pool.c | 22 +- plugins/dex/class.c | 38 ++- plugins/dex/dex-int.h | 7 +- plugins/dex/field.c | 7 +- plugins/dex/field.h | 2 - plugins/dex/format.c | 95 ++++--- plugins/dex/format.h | 11 +- plugins/dex/loading.c | 10 +- plugins/dex/loading.h | 8 +- plugins/dex/method.c | 18 +- plugins/dex/pool.c | 401 ++++++++++++++++++++++-------- plugins/dex/pool.h | 58 +++-- plugins/dex/python/Makefile.am | 1 + plugins/dex/python/format.c | 336 ++----------------------- plugins/dex/python/module.c | 2 + plugins/dex/python/pool.c | 545 +++++++++++++++++++++++++++++++++++++++++ plugins/dex/python/pool.h | 45 ++++ plugins/readdex/class.c | 17 +- 19 files changed, 1096 insertions(+), 541 deletions(-) create mode 100644 plugins/dex/python/pool.c create mode 100644 plugins/dex/python/pool.h diff --git a/plugins/dalvik/link.c b/plugins/dalvik/link.c index 6b100c9..4960917 100644 --- a/plugins/dalvik/link.c +++ b/plugins/dalvik/link.c @@ -81,6 +81,7 @@ void handle_links_for_dalvik_string(GArchInstruction *instr, GArchProcessor *pro { GArchOperand *op; /* Opérande numérique en place */ uint32_t index; /* Indice dans la table Dex */ + GDexPool *pool; /* Table de ressources */ GBinSymbol *string; /* Emplacement de la chaîne */ const mrange_t *range; /* Zone d'occupation */ GArchInstruction *target; /* Ligne visée par la référence*/ @@ -99,7 +100,11 @@ void handle_links_for_dalvik_string(GArchInstruction *instr, GArchProcessor *pro index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(op)); - string = get_string_symbol_from_dex_pool(G_DEX_FORMAT(format), index); + pool = g_dex_format_get_pool(G_DEX_FORMAT(format)); + + string = g_dex_pool_get_string_symbol(pool, index); + + g_object_unref(G_OBJECT(pool)); if (string != NULL) { @@ -396,6 +401,7 @@ void handle_links_between_caller_and_callee(GArchInstruction *instr, GArchProces { GArchOperand *op; /* Opérande numérique en place */ uint32_t index; /* Indice dans la table Dex */ + GDexPool *pool; /* Table de ressources */ GDexMethod *method; /* Méthode ciblée ici */ GBinRoutine *routine; /* Routine liée à la méthode */ const mrange_t *range; /* Zone d'occupation */ @@ -415,7 +421,11 @@ void handle_links_between_caller_and_callee(GArchInstruction *instr, GArchProces index = g_dalvik_pool_operand_get_index(G_DALVIK_POOL_OPERAND(op)); - method = get_method_from_dex_pool(G_DEX_FORMAT(format), index); + pool = g_dex_format_get_pool(G_DEX_FORMAT(format)); + + method = g_dex_pool_get_method(pool, index); + + g_object_unref(G_OBJECT(pool)); if (method != NULL) { diff --git a/plugins/dalvik/operands/pool.c b/plugins/dalvik/operands/pool.c index 8f6ccff..e9f1d60 100644 --- a/plugins/dalvik/operands/pool.c +++ b/plugins/dalvik/operands/pool.c @@ -262,6 +262,7 @@ static int g_dalvik_pool_operand_compare(const GDalvikPoolOperand *a, const GDal static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBufferLine *line) { + GDexPool *pool; /* Table de ressources */ const char *string; /* Chaîne de caractères #1 */ GDataType *type; /* Type à représenter */ size_t len; /* Taille du texte à créer */ @@ -270,6 +271,8 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff GBinVariable *field; /* Champ à représenter */ GDexMethod *method; /* Méthode à retrouver */ + pool = g_dex_format_get_pool(operand->format); + switch (operand->type) { case DPT_NONE: @@ -278,7 +281,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff case DPT_STRING: - string = get_string_from_dex_pool(operand->format, operand->index, NULL); + string = g_dex_pool_get_string(pool, operand->index, NULL); if (string != NULL) { @@ -308,7 +311,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff case DPT_TYPE: - type = get_type_from_dex_pool(operand->format, operand->index); + type = g_dex_pool_get_type_(pool, operand->index); if (type != NULL) { @@ -336,7 +339,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff case DPT_PROTO: - routine = get_prototype_from_dex_pool(operand->format, operand->index); + routine = g_dex_pool_get_prototype(pool, operand->index); if (routine != NULL) { @@ -362,7 +365,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff case DPT_FIELD: - field = get_field_from_dex_pool(operand->format, operand->index); + field = g_dex_pool_get_field(pool, operand->index); if (field != NULL) { @@ -390,7 +393,7 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff case DPT_METHOD: - method = get_method_from_dex_pool(operand->format, operand->index); + method = g_dex_pool_get_method(pool, operand->index); if (method != NULL) routine = g_dex_method_get_routine(method); @@ -424,6 +427,8 @@ static void g_dalvik_pool_operand_print(const GDalvikPoolOperand *operand, GBuff } + g_object_unref(G_OBJECT(pool)); + } @@ -628,6 +633,7 @@ static bool g_dalvik_pool_operand_serialize(const GDalvikPoolOperand *operand, G static bool g_dalvik_pool_operand_get_addr(const GDalvikPoolOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) { bool result; /* Bilan à retourner */ + GDexPool *pool; /* Table de ressources */ GDexMethod *method; /* Méthode ciblée ici */ GBinRoutine *routine; /* Routine liée à la méthode */ const mrange_t *range; /* Zone d'occupation */ @@ -636,7 +642,11 @@ static bool g_dalvik_pool_operand_get_addr(const GDalvikPoolOperand *operand, co if (operand->type == DPT_METHOD) { - method = get_method_from_dex_pool(G_DEX_FORMAT(format), operand->index); + pool = g_dex_format_get_pool(G_DEX_FORMAT(format)); + + method = g_dex_pool_get_method(pool, operand->index); + + g_object_unref(G_OBJECT(pool)); if (method != NULL) { diff --git a/plugins/dex/class.c b/plugins/dex/class.c index 8a094d5..b5ec462 100644 --- a/plugins/dex/class.c +++ b/plugins/dex/class.c @@ -222,6 +222,7 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def) uleb128_t index; /* Conservation du dernier id */ uleb128_t i; /* Boucle de parcours */ GDexField *field; /* Champ chargé */ + GDexPool *pool; /* Table de ressources */ GDataType *ctype; /* Type créé par la classe */ GBinFormat *base; /* Autre version du format */ GDexMethod *method; /* Méthode chargée */ @@ -291,7 +292,12 @@ GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def) * Chargement des méthodes de classe. */ - ctype = get_type_from_dex_pool(format, def->class_idx); + pool = g_dex_format_get_pool(format); + + ctype = g_dex_pool_get_type_(pool, def->class_idx); + + g_object_unref(G_OBJECT(pool)); + if (ctype == NULL) goto gdcn_unknown_type; base = G_BIN_FORMAT(format); @@ -424,8 +430,13 @@ const class_data_item *g_dex_class_get_data(const GDexClass *class) GDataType *g_dex_class_get_class_type(const GDexClass *class) { GDataType *result; /* Type à renvoyer */ + GDexPool *pool; /* Table de ressources */ - result = get_type_from_dex_pool(class->format, class->definition.class_idx); + pool = g_dex_format_get_pool(class->format); + + result = g_dex_pool_get_type_(pool, class->definition.class_idx); + + g_object_unref(G_OBJECT(pool)); return result; @@ -447,8 +458,13 @@ GDataType *g_dex_class_get_class_type(const GDexClass *class) GDataType *g_dex_class_get_superclass_type(const GDexClass *class) { GDataType *result; /* Type à renvoyer */ + GDexPool *pool; /* Table de ressources */ + + pool = g_dex_format_get_pool(class->format); - result = get_type_from_dex_pool(class->format, class->definition.superclass_idx); + result = g_dex_pool_get_type_(pool, class->definition.superclass_idx); + + g_object_unref(G_OBJECT(pool)); return result; @@ -474,6 +490,7 @@ GDataType **g_dex_class_get_interface_types(const GDexClass *class, size_t *coun vmpa2t addr; /* Tête de lecture générique */ type_list interfaces; /* Liste des interfaces */ bool status; /* Bilan d'une lecture */ + GDexPool *pool; /* Table de ressources */ size_t i; /* Boucle de parcours */ if (class->definition.interfaces_off == 0) @@ -491,10 +508,14 @@ GDataType **g_dex_class_get_interface_types(const GDexClass *class, size_t *coun if (status) { *count = interfaces.size; - result = (GDataType **)malloc(*count * sizeof(GDataType *)); + result = malloc(*count * sizeof(GDataType *)); + + pool = g_dex_format_get_pool(class->format); for (i = 0; i < *count; i++) - result[i] = get_type_from_dex_pool(class->format, interfaces.list[i].type_idx); + result[i] = g_dex_pool_get_type_(pool, interfaces.list[i].type_idx); + + g_object_unref(G_OBJECT(pool)); } @@ -716,8 +737,13 @@ bool g_dex_method_get_offset(const GDexMethod *method, phys_t *offset) const char *g_dex_class_get_source_file(const GDexClass *class) { const char *result; /* Trouvaille à renvoyer */ + GDexPool *pool; /* Table de ressources */ + + pool = g_dex_format_get_pool(class->format); + + result = g_dex_pool_get_string(pool, class->definition.source_file_idx, NULL); - result = get_string_from_dex_pool(class->format, class->definition.source_file_idx, NULL); + g_object_unref(G_OBJECT(pool)); return result; diff --git a/plugins/dex/dex-int.h b/plugins/dex/dex-int.h index 48a920c..fb1d0fe 100644 --- a/plugins/dex/dex-int.h +++ b/plugins/dex/dex-int.h @@ -31,6 +31,7 @@ #include "class.h" #include "dex_def.h" #include "format.h" +#include "pool.h" @@ -41,11 +42,7 @@ struct _GDexFormat dex_header header; /* En-tête du programme */ - 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 */ + GDexPool *pool; /* Table de ressources */ }; diff --git a/plugins/dex/field.c b/plugins/dex/field.c index 620d159..a3b9ec5 100644 --- a/plugins/dex/field.c +++ b/plugins/dex/field.c @@ -166,11 +166,16 @@ static void g_dex_field_finalize(GDexField *field) GDexField *g_dex_field_new(GDexFormat *format, const encoded_field *seed, uleb128_t *last) { GDexField *result; /* Composant à retourner */ + GDexPool *pool; /* Table de ressources */ GBinVariable *variable; /* Variable de représentation */ *last += seed->field_idx_diff; - variable = get_field_from_dex_pool(format, *last); + pool = g_dex_format_get_pool(format); + + variable = g_dex_pool_get_field(pool, *last); + + g_object_unref(G_OBJECT(pool)); if (variable == NULL) return NULL; diff --git a/plugins/dex/field.h b/plugins/dex/field.h index e430d7f..00e4d3d 100644 --- a/plugins/dex/field.h +++ b/plugins/dex/field.h @@ -44,7 +44,6 @@ #define G_DEX_FIELD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_FIELD, GDexFieldClass)) - /* Champ d'une classe Dex (instance) */ typedef struct _GDexField GDexField; @@ -52,7 +51,6 @@ typedef struct _GDexField GDexField; typedef struct _GDexFieldClass GDexFieldClass; - /* Détermine le type d'une fielde issue du code source. */ GType g_dex_field_get_type(void); diff --git a/plugins/dex/format.c b/plugins/dex/format.c index 44e8ba3..53cdc29 100644 --- a/plugins/dex/format.c +++ b/plugins/dex/format.c @@ -205,6 +205,8 @@ static void g_dex_format_init(GDexFormat *format) static void g_dex_format_dispose(GDexFormat *format) { + g_clear_object(&format->pool); + G_OBJECT_CLASS(g_dex_format_parent_class)->dispose(G_OBJECT(format)); } @@ -252,6 +254,8 @@ GExeFormat *g_dex_format_new(GBinContent *content) g_binary_format_set_content(G_BIN_FORMAT(result), content); + result->pool = g_dex_pool_new(result); + return G_EXE_FORMAT(result); } @@ -326,6 +330,7 @@ static bool g_dex_format_analyze(GDexFormat *format, wgroup_id_t gid, GtkStatusS phys_t size; /* Taille du binaire */ VMPA_BUFFER(size_str); /* Conversion en chaîne */ uint32_t max; /* Nombre maximal d'éléments */ + GDexPool *pool; /* Table de ressources */ result = false; @@ -388,30 +393,36 @@ static bool g_dex_format_analyze(GDexFormat *format, wgroup_id_t gid, GtkStatusS /* TODO : vérifier que les *_id ne se chevauchent pas */ - if (!load_all_dex_string_symbols(format, gid, status)) - goto gdfa_error; + pool = g_dex_format_get_pool(format); - if (!load_all_dex_types(format, gid, status)) - goto gdfa_error; + if (!g_dex_pool_load_all_string_symbols(pool, gid, status)) + goto pool_error; - if (!load_all_dex_fields(format, gid, status)) - goto gdfa_error; + if (!g_dex_pool_load_all_types(pool, gid, status)) + goto pool_error; - if (!load_all_dex_methods(format, gid, status)) - goto gdfa_error; + if (!g_dex_pool_load_all_fields(pool, gid, status)) + goto pool_error; - if (!load_all_dex_classes(format, gid, status)) - goto gdfa_error; + if (!g_dex_pool_load_all_methods(pool, gid, status)) + goto pool_error; + + if (!g_dex_pool_load_all_classes(pool, gid, status)) + goto pool_error; preload_binary_format(PGA_FORMAT_PRELOAD, base, base->info, status); g_executable_format_setup_portions(exe, status); if (!g_executable_format_complete_loading(exe, gid, status)) - goto gdfa_error; + goto pool_error; result = true; + pool_error: + + g_object_unref(G_OBJECT(pool)); + gdfa_error: return result; @@ -475,13 +486,23 @@ static void g_dex_format_refine_portions(GDexFormat *format) GExeFormat *exe_format; /* Autre version du format */ size_t max; /* Nombre d'itérations prévues */ size_t i; /* Boucle de parcours */ + GDexClass *class; /* Classe du format Dex */ exe_format = G_EXE_FORMAT(format); - max = g_dex_format_count_classes(format); + max = g_dex_pool_count_classes(format->pool); for (i = 0; i < max; i++) - g_dex_class_include_as_portion(format->classes[i], exe_format); + { + class = g_dex_pool_get_class(format->pool, i); + + if (class != NULL) + { + g_dex_class_include_as_portion(class, exe_format); + g_object_unref(G_OBJECT(class)); + } + + } } @@ -574,61 +595,27 @@ const dex_header *g_dex_format_get_header(const GDexFormat *format) } - - - /****************************************************************************** * * -* Paramètres : format = description de l'exécutable à consulter. * -* * -* Description : Dénombre le nombre de classes trouvées. * -* * -* Retour : Quantité de classes présentes. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_dex_format_count_classes(const GDexFormat *format) -{ - return format->header.class_defs_size; - -} - - -/****************************************************************************** -* * -* Paramètres : format = description de l'exécutable à consulter. * -* index = indice de la classe visée. * +* Paramètres : format = informations chargées à consulter. * * * -* Description : Fournit une classe du format chargée en mémoire. * +* Description : Fournit la table des ressources associée au format Dex. * * * -* Retour : Instance représentant une classe chargée. * +* Retour : Table de ressources mise en place ou NULL si aucune. * * * * Remarques : - * * * ******************************************************************************/ -GDexClass *g_dex_format_get_class(const GDexFormat *format, size_t index) +GDexPool *g_dex_format_get_pool(const GDexFormat *format) { - GDexClass *result; /* Classe trouvée à retourner */ + GDexPool *result; /* Instance à retourner */ - assert(index < format->header.class_defs_size); + result = format->pool; - if (index < format->header.class_defs_size) - { - result = format->classes[index]; + if (result != NULL) g_object_ref(G_OBJECT(result)); - } - - else - result = NULL; return result; } - - - - - diff --git a/plugins/dex/format.h b/plugins/dex/format.h index e0f1739..433ca26 100644 --- a/plugins/dex/format.h +++ b/plugins/dex/format.h @@ -65,14 +65,11 @@ GExeFormat *g_dex_format_new(GBinContent *); /* Présente l'en-tête DEX du format chargé. */ const dex_header *g_dex_format_get_header(const GDexFormat *); -/* Redéfinition : classe issue du code source (instance) */ -typedef struct _GDexClass GDexClass; +/* Redéfinition : table des ressources pour format Dex (instance) */ +typedef struct _GDexPool GDexPool; -/* Dénombre le nombre de classes trouvées. */ -size_t g_dex_format_count_classes(const GDexFormat *); - -/* Fournit une classe du format chargée en mémoire. */ -GDexClass *g_dex_format_get_class(const GDexFormat *, size_t); +/* Fournit la table des ressources associée au format Dex. */ +GDexPool *g_dex_format_get_pool(const GDexFormat *); diff --git a/plugins/dex/loading.c b/plugins/dex/loading.c index efe1531..8b14d3e 100644 --- a/plugins/dex/loading.c +++ b/plugins/dex/loading.c @@ -38,7 +38,7 @@ struct _GDexLoading { GDelayedWork parent; /* A laisser en premier */ - GDexFormat *format; /* Format à faire évoluer */ + GObject *target; /* Cible à faire évoluer */ dex_loading_cb callback; /* Routine de traitement finale*/ uint32_t begin; /* Point de départ du parcours */ @@ -166,7 +166,7 @@ static void g_dex_loading_finalize(GDexLoading *loading) /****************************************************************************** * * -* Paramètres : format = = ensemble d'instructions désassemblées. * +* Paramètres : target = cible finale de l'évolution programmée. * * begin = point de départ du parcours de liste. * * end = point d'arrivée exclu du parcours. * * id = identifiant du message affiché à l'utilisateur. * @@ -181,13 +181,13 @@ static void g_dex_loading_finalize(GDexLoading *loading) * * ******************************************************************************/ -GDexLoading *g_dex_loading_new(GDexFormat *format, uint32_t begin, uint32_t end, activity_id_t id, dex_loading_cb callback, bool *status) +GDexLoading *g_dex_loading_new(GObject *target, 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->target = target; result->callback = callback; result->begin = begin; @@ -222,7 +222,7 @@ static void g_dex_loading_process(GDexLoading *loading, GtkStatusStack *status) for (i = loading->begin; i < loading->end && *(loading->status); i++) { - obj = loading->callback(loading->format, i); + obj = loading->callback(loading->target, i); if (obj != NULL) g_object_unref(obj); diff --git a/plugins/dex/loading.h b/plugins/dex/loading.h index fe5ce1f..c7891e2 100644 --- a/plugins/dex/loading.h +++ b/plugins/dex/loading.h @@ -25,10 +25,10 @@ #define _PLUGINS_DEX_LOADING_H -#include +#include -#include "format.h" +#include @@ -48,14 +48,14 @@ typedef struct _GDexLoadingClass GDexLoadingClass; /* Extrait une représentation générique d'une table Dex. */ -typedef GObject * (* dex_loading_cb) (GDexFormat *, uint32_t); +typedef GObject * (* dex_loading_cb) (GObject *, 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 *); +GDexLoading *g_dex_loading_new(GObject *, uint32_t, uint32_t, activity_id_t, dex_loading_cb, bool *); diff --git a/plugins/dex/method.c b/plugins/dex/method.c index 7f0d0f8..f35858e 100644 --- a/plugins/dex/method.c +++ b/plugins/dex/method.c @@ -193,6 +193,7 @@ static void g_dex_method_finalize(GDexMethod *method) GDexMethod *g_dex_method_new_defined(GDexFormat *format, const encoded_method *seed, uleb128_t *last) { GDexMethod *result; /* Composant à retourner */ + GDexPool *pool; /* Table de ressources */ vmpa2t addr; /* Tête de lecture générique */ code_item item; /* Corps de la méthode */ phys_t ins_offset; /* Position physique du code */ @@ -200,7 +201,11 @@ GDexMethod *g_dex_method_new_defined(GDexFormat *format, const encoded_method *s *last += seed->method_idx_diff; - result = get_method_from_dex_pool(format, *last); + pool = g_dex_format_get_pool(format); + + result = g_dex_pool_get_method(pool, *last); + + g_object_unref(G_OBJECT(pool)); if (result == NULL) return NULL; @@ -266,18 +271,21 @@ 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 */ + GDexPool *pool; /* Table de ressources */ 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); + pool = g_dex_format_get_pool(format); - name = get_string_from_dex_pool(format, method_id->name_idx, NULL); + ns = g_dex_pool_get_type_(pool, method_id->class_idx); + + name = g_dex_pool_get_string(pool, method_id->name_idx, NULL); if (name == NULL) goto gdmne_exit; - routine = get_prototype_from_dex_pool(format, method_id->proto_idx); + routine = g_dex_pool_get_prototype(pool, method_id->proto_idx); if (routine == NULL) goto gdmne_exit; if (ns != NULL) @@ -293,6 +301,8 @@ GDexMethod *g_dex_method_new_callable(GDexFormat *format, const method_id_item * gdmne_exit: + g_object_unref(G_OBJECT(pool)); + return result; } diff --git a/plugins/dex/pool.c b/plugins/dex/pool.c index 90c991b..6905c3b 100644 --- a/plugins/dex/pool.c +++ b/plugins/dex/pool.c @@ -41,9 +41,155 @@ +/* Table des ressources pour format Dex (instance) */ +struct _GDexPool +{ + GObject parent; /* A laisser en premier */ + + GDexFormat *format; /* Format de rattachement */ + + 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 */ + +}; + +/* Table des ressources pour format Dex (classe) */ +struct _GDexPoolClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Procède à l'initialisation des tables de ressources pour Dex. */ +static void g_dex_pool_class_init(GDexPoolClass *); + +/* Procède à l'initialisation d'une table de ressources Dex. */ +static void g_dex_pool_init(GDexPool *); + +/* Supprime toutes les références externes. */ +static void g_dex_pool_dispose(GDexPool *); + +/* Procède à la libération totale de la mémoire. */ +static void g_dex_pool_finalize(GDexPool *); + + + +/* Détermine le type d'une table des ressources pour format Dex. */ +G_DEFINE_TYPE(GDexPool, g_dex_pool, G_TYPE_OBJECT); + + /****************************************************************************** * * -* Paramètres : format = description de l'exécutable à compléter. * +* Paramètres : class = classe de composant GLib à initialiser. * +* * +* Description : Procède à l'initialisation des tables de ressources pour Dex.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_pool_class_init(GDexPoolClass *class) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_pool_dispose; + object->finalize = (GObjectFinalizeFunc)g_dex_pool_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : pool = composant GLib à initialiser. * +* * +* Description : Procède à l'initialisation d'une table de ressources Dex. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_pool_init(GDexPool *pool) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : pool = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_pool_dispose(GDexPool *pool) +{ + G_OBJECT_CLASS(g_dex_pool_parent_class)->dispose(G_OBJECT(pool)); + +} + + +/****************************************************************************** +* * +* Paramètres : pool = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_pool_finalize(GDexPool *pool) +{ + G_OBJECT_CLASS(g_dex_pool_parent_class)->finalize(G_OBJECT(pool)); + +} + + +/****************************************************************************** +* * +* Paramètres : format = représentation interne du format Dex à consulter. * +* * +* Description : Crée une nouvelle table de ressources pour format Dex. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDexPool *g_dex_pool_new(GDexFormat *format) +{ + GDexPool *result; /* Composant à retourner */ + + result = g_object_new(G_TYPE_DEX_POOL, NULL); + + result->format = format; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pool = table de ressources pour format Dex à compléter. * * gid = groupe de travail impliqué. * status = barre de statut à tenir informée. * * * @@ -55,7 +201,7 @@ * * ******************************************************************************/ -bool load_all_dex_string_symbols(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status) +bool g_dex_pool_load_all_string_symbols(GDexPool *pool, wgroup_id_t gid, GtkStatusStack *status) { bool result; /* Bilan à retourner */ uint32_t count; /* Nombre d'éléments présents */ @@ -72,9 +218,9 @@ bool load_all_dex_string_symbols(GDexFormat *format, wgroup_id_t gid, GtkStatusS /* Préparation du réceptacle */ - count = count_strings_in_dex_pool(format); + count = g_dex_pool_count_strings(pool); - format->strings = (GBinSymbol **)calloc(count, sizeof(GBinSymbol *)); + pool->strings = calloc(count, sizeof(GBinSymbol *)); /* Lancement des chargements */ @@ -93,8 +239,8 @@ bool load_all_dex_string_symbols(GDexFormat *format, wgroup_id_t gid, GtkStatusS else end = begin + run_size; - loading = g_dex_loading_new(format, begin, end, msg, - (dex_loading_cb)get_string_symbol_from_dex_pool, &result); + loading = g_dex_loading_new(G_OBJECT(pool), begin, end, msg, + (dex_loading_cb)g_dex_pool_get_string_symbol, &result); g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid); @@ -111,7 +257,7 @@ bool load_all_dex_string_symbols(GDexFormat *format, wgroup_id_t gid, GtkStatusS /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * +* Paramètres : pool = table de resources pour format Dex à consulter. * * * * Description : Compte le nombre de chaînes de caractères dans une table DEX.* * * @@ -121,11 +267,11 @@ bool load_all_dex_string_symbols(GDexFormat *format, wgroup_id_t gid, GtkStatusS * * ******************************************************************************/ -uint32_t count_strings_in_dex_pool(const GDexFormat *format) +uint32_t g_dex_pool_count_strings(const GDexPool *pool) { uint32_t result; /* Quantité à retourner */ - result = format->header.string_ids_size; + result = pool->format->header.string_ids_size; return result; @@ -134,9 +280,9 @@ uint32_t count_strings_in_dex_pool(const GDexFormat *format) /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * -* index = index de la chaîne recherchée. * -* range = éventuelle couverture à renseigner ou NULL. [OUT] * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index de la chaîne recherchée. * +* range = éventuelle couverture à renseigner ou NULL. [OUT] * * * * Description : Extrait une chaîne de caractères d'une table DEX. * * * @@ -146,9 +292,10 @@ uint32_t count_strings_in_dex_pool(const GDexFormat *format) * * ******************************************************************************/ -const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, mrange_t *range) +const char *g_dex_pool_get_string(const GDexPool *pool, uint32_t index, mrange_t *range) { uint32_t count; /* Nombre d'éléments présents */ + GDexFormat *format; /* Format associé à la table */ off_t pos; /* Tête de lecture */ vmpa2t addr; /* Tête de lecture générique */ string_id_item str_id; /* Identifiant de chaîne */ @@ -156,11 +303,13 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, m string_data_item str_data; /* Description de chaîne */ phys_t diff; /* Avancée de tête de lecture */ - count = count_strings_in_dex_pool(format); + count = g_dex_pool_count_strings(pool); if (index >= count) return NULL; + format = pool->format; + pos = format->header.string_ids_off + index * sizeof(string_id_item); init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); @@ -188,8 +337,8 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, m /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * -* index = index de la chaîne recherchée. * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index de la chaîne recherchée. * * * * Description : Extrait un symbole de chaîne d'une table DEX. * * * @@ -199,7 +348,7 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index, m * * ******************************************************************************/ -GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *format, uint32_t index) +GBinSymbol *g_dex_pool_get_string_symbol(GDexPool *pool, uint32_t index) { GBinSymbol *result; /* Instance à retourner */ uint32_t count; /* Nombre d'éléments présents */ @@ -211,17 +360,17 @@ GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *format, uint32_t index) result = NULL; - count = count_strings_in_dex_pool(format); + count = g_dex_pool_count_strings(pool); if (index >= count) goto gssfdp_error; - if (format->strings[index] == NULL) + if (pool->strings[index] == NULL) { - string = get_string_from_dex_pool(format, index, &range); + string = g_dex_pool_get_string(pool, index, &range); if (string == NULL) goto gssfdp_error; - base = G_BIN_FORMAT(format); + base = G_BIN_FORMAT(pool->format); new = g_string_symbol_new_read_only(base, &range, SET_MUTF_8); @@ -231,14 +380,14 @@ GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *format, uint32_t index) inserted = g_binary_format_add_symbol(base, new); if (inserted) - format->strings[index] = new; + pool->strings[index] = new; else g_object_unref(G_OBJECT(new)); } - result = format->strings[index]; + result = pool->strings[index]; if (result != NULL) g_object_ref(G_OBJECT(result)); @@ -252,7 +401,7 @@ GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *format, uint32_t index) /****************************************************************************** * * -* Paramètres : format = description de l'exécutable à compléter. * +* Paramètres : pool = table de ressources pour format Dex à compléter. * * gid = groupe de travail impliqué. * status = barre de statut à tenir informée. * * * @@ -264,7 +413,7 @@ GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *format, uint32_t index) * * ******************************************************************************/ -bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status) +bool g_dex_pool_load_all_types(GDexPool *pool, wgroup_id_t gid, GtkStatusStack *status) { bool result; /* Bilan à retourner */ uint32_t count; /* Nombre d'éléments présents */ @@ -281,9 +430,9 @@ bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *sta /* Préparation du réceptacle */ - count = count_types_in_dex_pool(format); + count = g_dex_pool_count_types(pool); - format->types = (GDataType **)calloc(count, sizeof(GDataType *)); + pool->types = calloc(count, sizeof(GDataType *)); /* Lancement des chargements */ @@ -302,8 +451,8 @@ bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *sta else end = begin + run_size; - loading = g_dex_loading_new(format, begin, end, msg, - (dex_loading_cb)get_type_from_dex_pool, &result); + loading = g_dex_loading_new(G_OBJECT(pool), begin, end, msg, + (dex_loading_cb)g_dex_pool_get_type_, &result); g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid); @@ -320,7 +469,7 @@ bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *sta /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * +* Paramètres : pool = table de resources pour format Dex à consulter. * * * * Description : Compte le nombre de types dans une table DEX. * * * @@ -330,11 +479,11 @@ bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *sta * * ******************************************************************************/ -uint32_t count_types_in_dex_pool(const GDexFormat *format) +uint32_t g_dex_pool_count_types(const GDexPool *pool) { uint32_t result; /* Quantité à retourner */ - result = format->header.type_ids_size; + result = pool->format->header.type_ids_size; return result; @@ -343,8 +492,8 @@ uint32_t count_types_in_dex_pool(const GDexFormat *format) /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * -* index = index du type recherché. * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index du type recherché. * * * * Description : Extrait une représentation de type d'une table DEX. * * * @@ -354,10 +503,11 @@ uint32_t count_types_in_dex_pool(const GDexFormat *format) * * ******************************************************************************/ -GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index) +GDataType *g_dex_pool_get_type_(GDexPool *pool, uint32_t index) { GDataType *result; /* Instance à retourner */ uint32_t count; /* Nombre d'éléments présents */ + GDexFormat *format; /* Format associé à la table */ phys_t pos; /* Tête de lecture */ vmpa2t addr; /* Tête de lecture générique */ type_id_item type_id; /* Définition de la classe */ @@ -366,13 +516,15 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index) result = NULL; - count = count_types_in_dex_pool(format); + count = g_dex_pool_count_types(pool); if (index >= count) goto gtfdp_error; - if (format->types[index] == NULL) + if (pool->types[index] == NULL) { + format = pool->format; + pos = format->header.type_ids_off + index * sizeof(type_id_item); init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); @@ -391,11 +543,11 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index) if (!read_dex_string_data_item(format, &addr, NULL, &str_data)) goto gtfdp_error; - format->types[index] = g_binary_format_decode_type(G_BIN_FORMAT(format), (char *)str_data.data); + pool->types[index] = g_binary_format_decode_type(G_BIN_FORMAT(format), (char *)str_data.data); } - result = format->types[index]; + result = pool->types[index]; if (result != NULL) g_object_ref(G_OBJECT(result)); @@ -409,7 +561,7 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index) /****************************************************************************** * * -* Paramètres : format = description de l'exécutable à compléter. * +* Paramètres : pool = table de ressources pour format Dex à compléter. * * gid = groupe de travail impliqué. * * status = barre de statut à tenir informée. * * * @@ -421,7 +573,7 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index) * * ******************************************************************************/ -bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status) +bool g_dex_pool_load_all_fields(GDexPool *pool, wgroup_id_t gid, GtkStatusStack *status) { bool result; /* Bilan à retourner */ uint32_t count; /* Nombre d'éléments présents */ @@ -438,9 +590,9 @@ bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *st /* Préparation du réceptacle */ - count = count_fields_in_dex_pool(format); + count = g_dex_pool_count_fields(pool); - format->fields = (GBinVariable **)calloc(count, sizeof(GBinVariable *)); + pool->fields = calloc(count, sizeof(GBinVariable *)); /* Lancement des chargements */ @@ -460,8 +612,8 @@ bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *st else end = begin + run_size; - loading = g_dex_loading_new(format, begin, end, msg, - (dex_loading_cb)get_field_from_dex_pool, &result); + loading = g_dex_loading_new(G_OBJECT(pool), begin, end, msg, + (dex_loading_cb)g_dex_pool_get_field, &result); g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid); @@ -478,7 +630,7 @@ bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *st /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * +* Paramètres : pool = table de resources pour format Dex à consulter. * * * * Description : Compte le nombre de champs dans une table DEX. * * * @@ -488,11 +640,11 @@ bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *st * * ******************************************************************************/ -uint32_t count_fields_in_dex_pool(const GDexFormat *format) +uint32_t g_dex_pool_count_fields(const GDexPool *pool) { uint32_t result; /* Quantité à retourner */ - result = format->header.field_ids_size; + result = pool->format->header.field_ids_size; return result; @@ -501,8 +653,8 @@ uint32_t count_fields_in_dex_pool(const GDexFormat *format) /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * -* index = index du champ recherché. * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index du champ recherché. * * * * Description : Extrait une représentation de champ d'une table DEX. * * * @@ -512,10 +664,11 @@ uint32_t count_fields_in_dex_pool(const GDexFormat *format) * * ******************************************************************************/ -GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index) +GBinVariable *g_dex_pool_get_field(GDexPool *pool, uint32_t index) { GBinVariable *result; /* Instance à retourner */ uint32_t count; /* Nombre d'éléments présents */ + GDexFormat *format; /* Format associé à la table */ phys_t pos; /* Tête de lecture */ vmpa2t addr; /* Tête de lecture générique */ field_id_item field_id; /* Description du champ */ @@ -526,23 +679,25 @@ GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index) result = NULL; - count = count_fields_in_dex_pool(format); + count = g_dex_pool_count_fields(pool); if (index >= count) goto gffdp_error; - if (format->fields[index] == NULL) + if (pool->fields[index] == NULL) { + format = pool->format; + pos = format->header.field_ids_off + index * sizeof(field_id_item); init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); if (!read_dex_field_id_item(format, &addr, &field_id)) goto gffdp_error; - type = get_type_from_dex_pool(format, field_id.type_idx); + type = g_dex_pool_get_type_(pool, field_id.type_idx); if (type == NULL) goto gffdp_error; - name = get_string_from_dex_pool(format, field_id.name_idx, NULL); + name = g_dex_pool_get_string(pool, field_id.name_idx, NULL); if (name == NULL) goto gffdp_bad_name; field = g_binary_variable_new(type); @@ -550,18 +705,18 @@ GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index) if (field_id.class_idx != NO_INDEX) { - owner = get_type_from_dex_pool(format, field_id.class_idx); + owner = g_dex_pool_get_type_(pool, field_id.class_idx); if (owner == NULL) goto gffdp_bad_owner; g_binary_variable_set_owner(field, owner); } - format->fields[index] = field; + pool->fields[index] = field; } - result = format->fields[index]; + result = pool->fields[index]; if (result != NULL) g_object_ref(G_OBJECT(result)); @@ -585,7 +740,7 @@ GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index) /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * +* Paramètres : pool = table de resources pour format Dex à consulter. * * * * Description : Compte le nombre de prototypes dans une table DEX. * * * @@ -595,11 +750,11 @@ GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index) * * ******************************************************************************/ -uint32_t count_prototypes_in_dex_pool(const GDexFormat *format) +uint32_t g_dex_pool_count_prototypes(const GDexPool *pool) { uint32_t result; /* Quantité à retourner */ - result = format->header.proto_ids_size; + result = pool->format->header.proto_ids_size; return result; @@ -608,8 +763,8 @@ uint32_t count_prototypes_in_dex_pool(const GDexFormat *format) /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * -* index = index de la routine recherchée. * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index de la routine recherchée. * * * * Description : Extrait une représentation de routine d'une table DEX. * * * @@ -619,10 +774,11 @@ uint32_t count_prototypes_in_dex_pool(const GDexFormat *format) * * ******************************************************************************/ -GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index) +GBinRoutine *g_dex_pool_get_prototype(GDexPool *pool, uint32_t index) { GBinRoutine *result; /* Instance à retourner */ uint32_t count; /* Nombre d'éléments présents */ + GDexFormat *format; /* Format associé à la table */ phys_t pos; /* Tête de lecture */ vmpa2t addr; /* Tête de lecture générique */ proto_id_item proto_id; /* Prototype de routine */ @@ -639,11 +795,13 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index) * les autres éléments de la table des constantes. */ - count = count_prototypes_in_dex_pool(format); + count = g_dex_pool_count_prototypes(pool); if (index >= count) goto grfdp_error; + format = pool->format; + pos = format->header.proto_ids_off + index * sizeof(proto_id_item); init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); @@ -658,7 +816,7 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index) /* Type de retour */ - type = get_type_from_dex_pool(format, proto_id.return_type_idx); + type = g_dex_pool_get_type_(pool, proto_id.return_type_idx); if (type == NULL) goto grfdp_error; result = G_BIN_ROUTINE(g_dex_routine_new()); @@ -678,7 +836,7 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index) for (i = 0; i < args.size; i++) { - type = get_type_from_dex_pool(format, args.list[i].type_idx); + type = g_dex_pool_get_type_(pool, args.list[i].type_idx); if (type == NULL) goto grfdp_error; arg = g_binary_variable_new(type); @@ -702,7 +860,7 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index) /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à compléter. * +* Paramètres : pool = table de ressources pour format Dex à compléter. * * gid = groupe de travail impliqué. * status = barre de statut à tenir informée. * * * @@ -714,9 +872,10 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index) * * ******************************************************************************/ -bool load_all_dex_methods(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status) +bool g_dex_pool_load_all_methods(GDexPool *pool, wgroup_id_t gid, GtkStatusStack *status) { bool result; /* Bilan à retourner */ + uint32_t count; /* Nombre d'éléments présents */ 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 */ @@ -749,28 +908,29 @@ bool load_all_dex_methods(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *s /* Préparation du réceptacle */ - format->methods = (GDexMethod **)calloc(format->header.method_ids_size, sizeof(GDexMethod *)); + count = pool->format->header.method_ids_size; + + pool->methods = calloc(count, sizeof(GDexMethod *)); /* Lancement des chargements */ - run_size = compute_run_size(format->header.method_ids_size, &runs_count); + run_size = compute_run_size(count, &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); + msg = gtk_status_stack_add_activity(status, _("Loading all methods from the Dex pool..."), count); for (i = 0; i < runs_count; i++) { begin = i * run_size; if ((i + 1) == runs_count) - end = format->header.method_ids_size; + end = count; else end = begin + run_size; - loading = g_dex_loading_new(format, begin, end, msg, - (dex_loading_cb)get_method_from_dex_pool, &result); + loading = g_dex_loading_new(G_OBJECT(pool), begin, end, msg, + (dex_loading_cb)g_dex_pool_get_method, &result); g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid); @@ -787,7 +947,7 @@ bool load_all_dex_methods(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *s /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * +* Paramètres : pool = table de resources pour format Dex à consulter. * * * * Description : Compte le nombre de méthodes dans une table DEX. * * * @@ -797,11 +957,11 @@ bool load_all_dex_methods(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *s * * ******************************************************************************/ -uint32_t count_methods_in_dex_pool(const GDexFormat *format) +uint32_t g_dex_pool_count_methods(const GDexPool *pool) { uint32_t result; /* Quantité à retourner */ - result = format->header.method_ids_size; + result = pool->format->header.method_ids_size; return result; @@ -810,8 +970,8 @@ uint32_t count_methods_in_dex_pool(const GDexFormat *format) /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * -* index = index de la méthode recherchée. * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index de la méthode recherchée. * * * * Description : Extrait une représentation de méthode d'une table DEX. * * * @@ -821,31 +981,37 @@ uint32_t count_methods_in_dex_pool(const GDexFormat *format) * * ******************************************************************************/ -GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index) +GDexMethod *g_dex_pool_get_method(GDexPool *pool, uint32_t index) { GDexMethod *result; /* Instance à retourner */ + uint32_t count; /* Nombre d'éléments présents */ + GDexFormat *format; /* Format associé à la table */ 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; - if (index >= format->header.method_ids_size) + count = g_dex_pool_count_methods(pool); + + if (index >= count) goto gmfdp_error; - if (format->methods[index] == NULL) + if (pool->methods[index] == NULL) { + format = pool->format; + 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; - format->methods[index] = g_dex_method_new_callable(format, &method_id); + pool->methods[index] = g_dex_method_new_callable(format, &method_id); } - result = format->methods[index]; + result = pool->methods[index]; if (result != NULL) g_object_ref(G_OBJECT(result)); @@ -859,7 +1025,7 @@ GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index) /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à compléter. * +* Paramètres : pool = table de ressources pour format Dex à compléter. * * gid = groupe de travail impliqué. * status = barre de statut à tenir informée. * * * @@ -871,9 +1037,10 @@ GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index) * * ******************************************************************************/ -bool load_all_dex_classes(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status) +bool g_dex_pool_load_all_classes(GDexPool *pool, wgroup_id_t gid, GtkStatusStack *status) { bool result; /* Bilan à retourner */ + uint32_t count; /* Nombre d'éléments présents */ 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 */ @@ -887,28 +1054,29 @@ bool load_all_dex_classes(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *s /* Préparation du réceptacle */ - format->classes = (GDexClass **)calloc(format->header.class_defs_size, sizeof(GDexClass *)); + count = pool->format->header.class_defs_size; + + pool->classes = calloc(count, sizeof(GDexClass *)); /* Lancement des chargements */ - run_size = compute_run_size(format->header.class_defs_size, &runs_count); + run_size = compute_run_size(count, &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); + msg = gtk_status_stack_add_activity(status, _("Loading all classes from the Dex pool..."), count); for (i = 0; i < runs_count; i++) { begin = i * run_size; if ((i + 1) == runs_count) - end = format->header.class_defs_size; + end = count; else end = begin + run_size; - loading = g_dex_loading_new(format, begin, end, msg, - (dex_loading_cb)get_class_from_dex_pool, &result); + loading = g_dex_loading_new(G_OBJECT(pool), begin, end, msg, + (dex_loading_cb)g_dex_pool_get_class, &result); g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid); @@ -925,8 +1093,31 @@ bool load_all_dex_classes(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *s /****************************************************************************** * * -* Paramètres : format = représentation interne du format DEX à consulter. * -* index = index de la classe recherchée. * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* * +* Description : Dénombre le nombre de classes trouvées. * +* * +* Retour : Valeur positive ou nulle. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint32_t g_dex_pool_count_classes(const GDexPool *pool) +{ + uint32_t result; /* Quantité à retourner */ + + result = pool->format->header.class_defs_size; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pool = table de resources pour format Dex à consulter. * +* index = index de la classe recherchée. * * * * Description : Extrait une représentation de classe d'une table DEX. * * * @@ -936,31 +1127,37 @@ bool load_all_dex_classes(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *s * * ******************************************************************************/ -GDexClass *get_class_from_dex_pool(GDexFormat *format, uint32_t index) +GDexClass *g_dex_pool_get_class(GDexPool *pool, uint32_t index) { GDexClass *result; /* Instance à retourner */ + uint32_t count; /* Nombre d'éléments présents */ + GDexFormat *format; /* Format associé à la table */ phys_t pos; /* Tête de lecture */ vmpa2t addr; /* Tête de lecture générique */ class_def_item class_def; /* Définition de la classe */ result = NULL; - if (index >= format->header.class_defs_size) + count = g_dex_pool_count_classes(pool); + + if (index >= count) goto gcfdp_error; - if (format->classes[index] == NULL) + if (pool->classes[index] == NULL) { + format = pool->format; + pos = format->header.class_defs_off + index * sizeof(class_def_item); init_vmpa(&addr, pos, VMPA_NO_VIRTUAL); if (!read_dex_class_def_item(format, &addr, &class_def)) goto gcfdp_error; - format->classes[index] = g_dex_class_new(format, &class_def); + pool->classes[index] = g_dex_class_new(format, &class_def); } - result = format->classes[index]; + result = pool->classes[index]; if (result != NULL) g_object_ref(G_OBJECT(result)); diff --git a/plugins/dex/pool.h b/plugins/dex/pool.h index dd27f94..26c11d6 100644 --- a/plugins/dex/pool.h +++ b/plugins/dex/pool.h @@ -35,56 +35,80 @@ +#define G_TYPE_DEX_POOL (g_dex_pool_get_type()) +#define G_DEX_POOL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DEX_POOL, GDexPool)) +#define G_DEX_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_POOL, GDexPoolClass)) +#define G_IS_DEX_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DEX_POOL)) +#define G_IS_DEX_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_POOL)) +#define G_DEX_POOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_POOL, GDexPoolClass)) + + +/* Table des ressources pour format Dex (instance) */ +typedef struct _GDexPool GDexPool; + +/* Table des ressources pour format Dex (classe) */ +typedef struct _GDexPoolClass GDexPoolClass; + + +/* Détermine le type d'une table des ressources pour format Dex. */ +GType g_dex_pool_get_type(void); + +/* Crée une nouvelle table de ressources pour format Dex. */ +GDexPool *g_dex_pool_new(GDexFormat *); + /* Charge en mémoire l'ensemble des chaînes du format DEX. */ -bool load_all_dex_string_symbols(GDexFormat *, wgroup_id_t, GtkStatusStack *); +bool g_dex_pool_load_all_string_symbols(GDexPool *, wgroup_id_t, GtkStatusStack *); /* Compte le nombre de chaînes de caractères dans une table DEX. */ -uint32_t count_strings_in_dex_pool(const GDexFormat *); +uint32_t g_dex_pool_count_strings(const GDexPool *); /* Extrait une chaîne de caractères d'une table DEX. */ -const char *get_string_from_dex_pool(const GDexFormat *, uint32_t, mrange_t *); +const char *g_dex_pool_get_string(const GDexPool *, uint32_t, mrange_t *); /* Extrait un symbole de chaîne d'une table DEX. */ -GBinSymbol *get_string_symbol_from_dex_pool(GDexFormat *, uint32_t); +GBinSymbol *g_dex_pool_get_string_symbol(GDexPool *, uint32_t); /* Charge en mémoire l'ensemble des types du format DEX. */ -bool load_all_dex_types(GDexFormat *, wgroup_id_t, GtkStatusStack *); +bool g_dex_pool_load_all_types(GDexPool *, wgroup_id_t, GtkStatusStack *); /* Compte le nombre de types dans une table DEX. */ -uint32_t count_types_in_dex_pool(const GDexFormat *); +uint32_t g_dex_pool_count_types(const GDexPool *); /* Extrait une représentation de type d'une table DEX. */ -GDataType *get_type_from_dex_pool(GDexFormat *, uint32_t); +GDataType *g_dex_pool_get_type_(GDexPool *, uint32_t); /* Charge en mémoire l'ensemble des champs du format DEX. */ -bool load_all_dex_fields(GDexFormat *, wgroup_id_t, GtkStatusStack *); +bool g_dex_pool_load_all_fields(GDexPool *, wgroup_id_t, GtkStatusStack *); /* Compte le nombre de champs dans une table DEX. */ -uint32_t count_fields_in_dex_pool(const GDexFormat *); +uint32_t g_dex_pool_count_fields(const GDexPool *); /* Extrait une représentation de champ d'une table DEX. */ -GBinVariable *get_field_from_dex_pool(GDexFormat *, uint32_t); +GBinVariable *g_dex_pool_get_field(GDexPool *, uint32_t); /* Compte le nombre de prototypes dans une table DEX. */ -uint32_t count_prototypes_in_dex_pool(const GDexFormat *); +uint32_t g_dex_pool_count_prototypes(const GDexPool *); /* Extrait une représentation de routine d'une table DEX. */ -GBinRoutine *get_prototype_from_dex_pool(GDexFormat *, uint32_t); +GBinRoutine *g_dex_pool_get_prototype(GDexPool *, uint32_t); /* Charge toutes les classes listées dans le contenu binaire. */ -bool load_all_dex_methods(GDexFormat *, wgroup_id_t, GtkStatusStack *); +bool g_dex_pool_load_all_methods(GDexPool *, wgroup_id_t, GtkStatusStack *); /* Compte le nombre de méthodes dans une table DEX. */ -uint32_t count_methods_in_dex_pool(const GDexFormat *); +uint32_t g_dex_pool_count_methods(const GDexPool *); /* Extrait une représentation de méthode d'une table DEX. */ -GDexMethod *get_method_from_dex_pool(GDexFormat *, uint32_t); +GDexMethod *g_dex_pool_get_method(GDexPool *, uint32_t); /* Charge toutes les classes listées dans le contenu binaire. */ -bool load_all_dex_classes(GDexFormat *, wgroup_id_t, GtkStatusStack *); +bool g_dex_pool_load_all_classes(GDexPool *, wgroup_id_t, GtkStatusStack *); + +/* Dénombre le nombre de classes trouvées. */ +uint32_t g_dex_pool_count_classes(const GDexPool *); /* Extrait une représentation de classe d'une table DEX. */ -GDexClass *get_class_from_dex_pool(GDexFormat *, uint32_t); +GDexClass *g_dex_pool_get_class(GDexPool *, uint32_t); diff --git a/plugins/dex/python/Makefile.am b/plugins/dex/python/Makefile.am index b371b87..2e3316b 100644 --- a/plugins/dex/python/Makefile.am +++ b/plugins/dex/python/Makefile.am @@ -8,6 +8,7 @@ libdexpython_la_SOURCES = \ format.h format.c \ method.h method.c \ module.h module.c \ + pool.h pool.c \ routine.h routine.c \ translate.h translate.c diff --git a/plugins/dex/python/format.c b/plugins/dex/python/format.c index 8f18fc8..77ebef6 100644 --- a/plugins/dex/python/format.c +++ b/plugins/dex/python/format.c @@ -39,30 +39,14 @@ #include "constants.h" #include "../class.h" #include "../format.h" -#include "../pool.h" /* Crée un nouvel objet Python de type 'DexFormat'. */ static PyObject *py_dex_format_new(PyTypeObject *, PyObject *, PyObject *); -/* Fournit la liste de toutes les chaînes de la table globale. */ -static PyObject *py_dex_format_get_pool_strings(PyObject *, void *); - -/* Fournit la liste de tous les types de la table globale. */ -static PyObject *py_dex_format_get_pool_types(PyObject *, void *); - -/* Fournit la liste de tous les prototypes de la table globale. */ -static PyObject *py_dex_format_get_pool_prototypes(PyObject *, void *); - -/* Fournit la liste de tous les champs de la table globale. */ -static PyObject *py_dex_format_get_pool_fields(PyObject *, void *); - -/* Fournit la liste de toutes les méthodes de la table globale. */ -static PyObject *py_dex_format_get_pool_methods(PyObject *, void *); - -/* Fournit la liste de toutes les classes du format. */ -static PyObject *py_dex_format_get_classes(PyObject *, void *); +/* Fournit la table des ressources associée au format Dex. */ +static PyObject *py_dex_format_get_pool(PyObject *, void *); @@ -117,300 +101,33 @@ static PyObject *py_dex_format_new(PyTypeObject *type, PyObject *args, PyObject * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * -* Description : Fournit la liste de toutes les chaînes de la table globale. * -* * -* Retour : Liste vide ou remplie de chaînes. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_dex_format_get_pool_strings(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GDexFormat *format; /* Version native */ - uint32_t count; /* Nombre d'éléments à traiter */ - uint32_t i; /* Boucle de parcours */ - const char *string; /* Chaîne à intégrer */ - PyObject *str; /* Chaîne au format Python */ - - format = G_DEX_FORMAT(pygobject_get(self)); - - count = count_strings_in_dex_pool(format); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { - string = get_string_from_dex_pool(format, i, NULL); - - if (string == NULL) - { - str = Py_None; - Py_INCREF(str); - } - - else - str = PyUnicode_FromString(string); - - PyTuple_SetItem(result, i, str); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la liste de tous les types de la table globale. * -* * -* Retour : Liste vide ou remplie de types. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_dex_format_get_pool_types(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GDexFormat *format; /* Version native */ - uint32_t count; /* Nombre d'éléments à traiter */ - uint32_t i; /* Boucle de parcours */ - GDataType *type; /* Type à intégrer */ - PyObject *tp; /* Type au format Python */ - - format = G_DEX_FORMAT(pygobject_get(self)); - - count = count_types_in_dex_pool(format); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { - type = get_type_from_dex_pool(format, i); - - if (type == NULL) - { - tp = Py_None; - Py_INCREF(tp); - } - - else - { - tp = pygobject_new(G_OBJECT(type)); - g_object_unref(type); - } - - PyTuple_SetItem(result, i, tp); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la liste de tous les champs de la table globale. * -* * -* Retour : Liste vide ou remplie de méthodes. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_dex_format_get_pool_fields(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GDexFormat *format; /* Version native */ - uint32_t count; /* Nombre d'éléments à traiter */ - uint32_t i; /* Boucle de parcours */ - GBinVariable *variable; /* Champ à intégrer */ - PyObject *var; /* Champ au format Python */ - - format = G_DEX_FORMAT(pygobject_get(self)); - - count = count_fields_in_dex_pool(format); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { - variable = get_field_from_dex_pool(format, i); - - if (variable == NULL) - { - var = Py_None; - Py_INCREF(var); - } - - else - { - var = pygobject_new(G_OBJECT(variable)); - g_object_unref(variable); - } - - PyTuple_SetItem(result, i, var); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la liste de toutes les méthodes de la table globale. * -* * -* Retour : Liste vide ou remplie de méthodes. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_dex_format_get_pool_methods(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GDexFormat *format; /* Version native */ - uint32_t count; /* Nombre d'éléments à traiter */ - uint32_t i; /* Boucle de parcours */ - GDexMethod *method; /* Méthode à intégrer */ - PyObject *meth; /* Méthode au format Python */ - - format = G_DEX_FORMAT(pygobject_get(self)); - - count = count_methods_in_dex_pool(format); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { - method = get_method_from_dex_pool(format, i); - - if (method == NULL) - { - meth = Py_None; - Py_INCREF(meth); - } - - else - { - meth = pygobject_new(G_OBJECT(method)); - g_object_unref(method); - } - - PyTuple_SetItem(result, i, meth); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la liste de tous les prototypes de la table globale. * +* Description : Fournit la table des ressources associée au format Dex. * * * -* Retour : Liste vide ou remplie de méthodes. * +* Retour : Table de ressources mise en place ou None si aucune. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_dex_format_get_pool_prototypes(PyObject *self, void *closure) +static PyObject *py_dex_format_get_pool(PyObject *self, void *closure) { PyObject *result; /* Valeur à retourner */ GDexFormat *format; /* Version native */ - uint32_t count; /* Nombre d'éléments à traiter */ - uint32_t i; /* Boucle de parcours */ - GBinRoutine *routine; /* Routine à intégrer */ - PyObject *rtn; /* Routine au format Python */ - - format = G_DEX_FORMAT(pygobject_get(self)); - - count = count_prototypes_in_dex_pool(format); - - result = PyTuple_New(count); - - for (i = 0; i < count; i++) - { - routine = get_prototype_from_dex_pool(format, i); - - if (routine == NULL) - { - rtn = Py_None; - Py_INCREF(rtn); - } - - else - { - rtn = pygobject_new(G_OBJECT(routine)); - g_object_unref(routine); - } - - PyTuple_SetItem(result, i, rtn); - - } - - return result; - -} + GDexPool *pool; /* Table de ressources associée*/ - -/****************************************************************************** -* * -* Paramètres : self = objet Python concerné par l'appel. * -* closure = non utilisé ici. * -* * -* Description : Fournit la liste de toutes les classes du format. * -* * -* Retour : Liste vide ou remplie de classes. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *py_dex_format_get_classes(PyObject *self, void *closure) -{ - PyObject *result; /* Valeur à retourner */ - GDexFormat *format; /* Version native */ - size_t count; /* Nombre d'éléments à traiter */ - size_t i; /* Boucle de parcours */ - GDexClass *class; /* Classe du format à intégrer */ +#define DEX_FORMAT_POOL_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + pool, py_dex_format, \ + "Resource pool of the Dex format." \ +) format = G_DEX_FORMAT(pygobject_get(self)); - count = g_dex_format_count_classes(format); + pool = g_dex_format_get_pool(format); - result = PyTuple_New(count); + result = pygobject_new(G_OBJECT(pool)); - for (i = 0; i < count; i++) - { - class = g_dex_format_get_class(format, i); - assert(class != NULL); - - PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(class))); - - g_object_unref(G_OBJECT(class)); - - } + g_object_unref(G_OBJECT(pool)); return result; @@ -436,30 +153,7 @@ PyTypeObject *get_python_dex_format_type(void) }; static PyGetSetDef py_dex_format_getseters[] = { - { - "pool_strings", py_dex_format_get_pool_strings, NULL, - "Strings inside the Dex pool.", NULL - }, - { - "pool_types", py_dex_format_get_pool_types, NULL, - "Types inside the Dex pool.", NULL - }, - { - "pool_prototypes", py_dex_format_get_pool_prototypes, NULL, - "Prototypes inside the Dex pool.", NULL - }, - { - "pool_fields", py_dex_format_get_pool_fields, NULL, - "Fields inside the Dex pool.", NULL - }, - { - "pool_methods", py_dex_format_get_pool_methods, NULL, - "Methods inside the Dex pool.", NULL - }, - { - "classes", py_dex_format_get_classes, NULL, - "Classes inside the Dex format.", NULL - }, + DEX_FORMAT_POOL_ATTRIB, { NULL } }; diff --git a/plugins/dex/python/module.c b/plugins/dex/python/module.c index 007b794..9fca785 100644 --- a/plugins/dex/python/module.c +++ b/plugins/dex/python/module.c @@ -36,6 +36,7 @@ #include "field.h" #include "format.h" #include "method.h" +#include "pool.h" #include "routine.h" @@ -81,6 +82,7 @@ bool add_format_dex_module_to_python_module(void) if (result) result = register_python_dex_field(module); if (result) result = register_python_dex_format(module); if (result) result = register_python_dex_method(module); + if (result) result = register_python_dex_pool(module); if (result) result = register_python_dex_routine(module); assert(result); diff --git a/plugins/dex/python/pool.c b/plugins/dex/python/pool.c new file mode 100644 index 0000000..eae1e86 --- /dev/null +++ b/plugins/dex/python/pool.c @@ -0,0 +1,545 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pool.c - équivalent Python du fichier "plugins/dex/pool.c" + * + * Copyright (C) 2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "pool.h" + + +#include + + +#include + + +#include "translate.h" +#include "../pool.h" + + + +/* Fournit la liste de toutes les chaînes de la table globale. */ +static PyObject *py_dex_pool_get_strings(PyObject *, void *); + +/* Fournit la liste de tous les types de la table globale. */ +static PyObject *py_dex_pool_get_types(PyObject *, void *); + +/* Fournit la liste de tous les champs de la table globale. */ +static PyObject *py_dex_pool_get_fields(PyObject *, void *); + +/* Fournit la liste de tous les prototypes de la table globale. */ +static PyObject *py_dex_pool_get_prototypes(PyObject *, void *); + +/* Fournit la liste de toutes les méthodes de la table globale. */ +static PyObject *py_dex_pool_get_methods(PyObject *, void *); + +/* Fournit la liste de toutes les classes de la table globale. */ +static PyObject *py_dex_pool_get_classes(PyObject *, void *); + + + +#define DEX_POOL_DOC \ + "DexPool is the class collecting all resources of a Dex format." \ + "\n" \ + "The pool is populated when the format gets analyzed." + + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la liste de toutes les chaînes de la table globale. * +* * +* Retour : Liste vide ou remplie de chaînes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_dex_pool_get_strings(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GDexPool *pool; /* Version native */ + uint32_t count; /* Nombre d'éléments à traiter */ + uint32_t i; /* Boucle de parcours */ + const char *string; /* Chaîne à intégrer */ + PyObject *str; /* Chaîne au format Python */ + +#define DEX_POOL_STRINGS_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + strings, py_dex_pool, \ + "Strings inside the Dex pool." \ + "\n" \ + "These objects are the Chrysalide version of all *string_id_item*" \ + " structures stored in the Dex format header." \ +) + + pool = G_DEX_POOL(pygobject_get(self)); + + count = g_dex_pool_count_strings(pool); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + string = g_dex_pool_get_string(pool, i, NULL); + + if (string == NULL) + { + str = Py_None; + Py_INCREF(str); + } + + else + str = PyUnicode_FromString(string); + + PyTuple_SetItem(result, i, str); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la liste de tous les types de la table globale. * +* * +* Retour : Liste vide ou remplie de types. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_dex_pool_get_types(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GDexPool *pool; /* Version native */ + uint32_t count; /* Nombre d'éléments à traiter */ + uint32_t i; /* Boucle de parcours */ + GDataType *type; /* Type à intégrer */ + PyObject *tp; /* Type au format Python */ + +#define DEX_POOL_TYPES_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + types, py_dex_pool, \ + "Types inside the Dex pool." \ + "\n" \ + "These objects are the Chrysalide version of all *type_id_item*" \ + " structures stored in the Dex format header." \ +) + + pool = G_DEX_POOL(pygobject_get(self)); + + count = g_dex_pool_count_types(pool); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + type = g_dex_pool_get_type_(pool, i); + + if (type == NULL) + { + tp = Py_None; + Py_INCREF(tp); + } + + else + { + tp = pygobject_new(G_OBJECT(type)); + g_object_unref(type); + } + + PyTuple_SetItem(result, i, tp); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la liste de tous les champs de la table globale. * +* * +* Retour : Liste vide ou remplie de méthodes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_dex_pool_get_fields(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GDexPool *pool; /* Version native */ + uint32_t count; /* Nombre d'éléments à traiter */ + uint32_t i; /* Boucle de parcours */ + GBinVariable *variable; /* Champ à intégrer */ + PyObject *var; /* Champ au format Python */ + +#define DEX_POOL_FIELDS_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + fields, py_dex_pool, \ + "Fields inside the Dex pool." \ + "\n" \ + "These objects are the Chrysalide version of all *field_id_item*" \ + " structures stored in the Dex format header." \ +) + + pool = G_DEX_POOL(pygobject_get(self)); + + count = g_dex_pool_count_fields(pool); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + variable = g_dex_pool_get_field(pool, i); + + if (variable == NULL) + { + var = Py_None; + Py_INCREF(var); + } + + else + { + var = pygobject_new(G_OBJECT(variable)); + g_object_unref(variable); + } + + PyTuple_SetItem(result, i, var); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la liste de tous les prototypes de la table globale. * +* * +* Retour : Liste vide ou remplie de méthodes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_dex_pool_get_prototypes(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GDexPool *pool; /* Version native */ + uint32_t count; /* Nombre d'éléments à traiter */ + uint32_t i; /* Boucle de parcours */ + GBinRoutine *routine; /* Routine à intégrer */ + PyObject *rtn; /* Routine au format Python */ + +#define DEX_POOL_PROTOTYPES_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + prototypes, py_dex_pool, \ + "Prototypes inside the Dex pool." \ + "\n" \ + "These objects are the Chrysalide version of all *proto_id_item*" \ + " structures stored in the Dex format header." \ +) + + pool = G_DEX_POOL(pygobject_get(self)); + + count = g_dex_pool_count_prototypes(pool); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + routine = g_dex_pool_get_prototype(pool, i); + + if (routine == NULL) + { + rtn = Py_None; + Py_INCREF(rtn); + } + + else + { + rtn = pygobject_new(G_OBJECT(routine)); + g_object_unref(routine); + } + + PyTuple_SetItem(result, i, rtn); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la liste de toutes les méthodes de la table globale. * +* * +* Retour : Liste vide ou remplie de méthodes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_dex_pool_get_methods(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GDexPool *pool; /* Version native */ + uint32_t count; /* Nombre d'éléments à traiter */ + uint32_t i; /* Boucle de parcours */ + GDexMethod *method; /* Méthode à intégrer */ + PyObject *meth; /* Méthode au format Python */ + +#define DEX_POOL_METHODS_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + methods, py_dex_pool, \ + "Methods inside the Dex pool." \ + "\n" \ + "These objects are the Chrysalide version of all *method_id_item*" \ + " structures stored in the Dex format header." \ +) + + pool = G_DEX_POOL(pygobject_get(self)); + + count = g_dex_pool_count_methods(pool); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + method = g_dex_pool_get_method(pool, i); + + if (method == NULL) + { + meth = Py_None; + Py_INCREF(meth); + } + + else + { + meth = pygobject_new(G_OBJECT(method)); + g_object_unref(method); + } + + PyTuple_SetItem(result, i, meth); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la liste de toutes les classes de la table globale. * +* * +* Retour : Liste vide ou remplie de classes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_dex_pool_get_classes(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GDexPool *pool; /* Version native */ + size_t count; /* Nombre d'éléments à traiter */ + size_t i; /* Boucle de parcours */ + GDexClass *class; /* Classe du format à intégrer */ + +#define DEX_POOL_CLASSES_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + classes, py_dex_pool, \ + "Classes inside the Dex pool." \ + "\n" \ + "These objects are the Chrysalide version of all *class_def_item*" \ + " structures stored in the Dex format header." \ +) + + pool = G_DEX_POOL(pygobject_get(self)); + + count = g_dex_pool_count_classes(pool); + + result = PyTuple_New(count); + + for (i = 0; i < count; i++) + { + class = g_dex_pool_get_class(pool, i); + assert(class != NULL); + + PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(class))); + + g_object_unref(G_OBJECT(class)); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_dex_pool_type(void) +{ + static PyMethodDef py_dex_pool_methods[] = { + { NULL } + }; + + static PyGetSetDef py_dex_pool_getseters[] = { + DEX_POOL_STRINGS_ATTRIB, + DEX_POOL_TYPES_ATTRIB, + DEX_POOL_FIELDS_ATTRIB, + DEX_POOL_METHODS_ATTRIB, + DEX_POOL_PROTOTYPES_ATTRIB, + DEX_POOL_CLASSES_ATTRIB, + { NULL } + }; + + static PyTypeObject py_dex_pool_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.format.dex.DexPool", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = DEX_POOL_DOC, + + .tp_methods = py_dex_pool_methods, + .tp_getset = py_dex_pool_getseters + + }; + + return &py_dex_pool_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.format.dex.DexPool'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_dex_pool(PyObject *module) +{ + PyTypeObject *type; /* Type Python 'DexPool' */ + PyObject *dict; /* Dictionnaire du module */ + + type = get_python_dex_pool_type(); + + dict = PyModule_GetDict(module); + + if (!register_class_for_pygobject(dict, G_TYPE_DEX_POOL, type, &PyGObject_Type)) + return false; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : arg = argument quelconque à tenter de convertir. * +* dst = destination des valeurs récupérées en cas de succès. * +* * +* Description : Tente de convertir en table de ressources pour format Dex. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_dex_pool(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_dex_pool_type()); + + switch (result) + { + case -1: + /* L'exception est déjà fixée par Python */ + result = 0; + break; + + case 0: + PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to loaded binary"); + break; + + case 1: + *((GDexPool **)dst) = G_DEX_POOL(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} diff --git a/plugins/dex/python/pool.h b/plugins/dex/python/pool.h new file mode 100644 index 0000000..50af852 --- /dev/null +++ b/plugins/dex/python/pool.h @@ -0,0 +1,45 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * pool.h - prototypes pour l'équivalent Python du fichier "plugins/dex/pool.h" + * + * Copyright (C) 2019 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide 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. + * + * Chrysalide 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_DEX_PYTHON_POOL_H +#define _PLUGINS_DEX_PYTHON_POOL_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_dex_pool_type(void); + +/* Prend en charge l'objet 'pychrysalide.format.dex.DexPool'. */ +bool register_python_dex_pool(PyObject *module); + +/* Tente de convertir en table de ressources pour format Dex. */ +int convert_to_dex_pool(PyObject *, void *); + + + +#endif /* _PLUGINS_DEX_PYTHON_POOL_H */ diff --git a/plugins/readdex/class.c b/plugins/readdex/class.c index c414821..4bfdbb5 100644 --- a/plugins/readdex/class.c +++ b/plugins/readdex/class.c @@ -25,7 +25,7 @@ #include -#include +#include #include #include @@ -265,6 +265,8 @@ bool annotate_dex_class_defs(const GDexFormat *format, GPreloadInfo *info, GtkSt bool result; /* Bilan à retourner */ const dex_header *header; /* En-tête principale */ vmpa2t pos; /* Tête de lecture des symboles*/ + GDexPool *pool; /* Table de ressources */ + uint32_t count; /* Nombre de classes présentes */ activity_id_t msg; /* Message de progression */ GBinFormat *bformat; /* Autre version du format */ uint32_t i; /* Boucle de parcours */ @@ -278,19 +280,22 @@ bool annotate_dex_class_defs(const GDexFormat *format, GPreloadInfo *info, GtkSt if (!result) goto adcd_exit; - msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex classes..."), - header->class_defs_size); + pool = g_dex_format_get_pool(format); + + count = g_dex_pool_count_classes(pool); + + msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex classes..."), count); bformat = G_BIN_FORMAT(format); - for (i = 0; i < header->class_defs_size && result; i++) + for (i = 0; i < count && result; i++) { result = parse_field_definitions(PARSING_DEFS(_dex_class_defs), bformat, info, &pos, NULL); if (!result) break; /* Annotations supplémentaires */ - class = g_dex_format_get_class(format, i); + class = g_dex_pool_get_class(pool, i); def = g_dex_class_get_definition(class); @@ -305,6 +310,8 @@ bool annotate_dex_class_defs(const GDexFormat *format, GPreloadInfo *info, GtkSt gtk_status_stack_remove_activity(status, msg); + g_object_unref(G_OBJECT(pool)); + adcd_exit: return result; -- cgit v0.11.2-87-g4458