diff options
Diffstat (limited to 'src/format/dex/method.c')
-rw-r--r-- | src/format/dex/method.c | 156 |
1 files changed, 107 insertions, 49 deletions
diff --git a/src/format/dex/method.c b/src/format/dex/method.c index c721cea..c68e9e1 100644 --- a/src/format/dex/method.c +++ b/src/format/dex/method.c @@ -24,13 +24,15 @@ #include "method.h" +#include <i18n.h> + + #include "dex-int.h" #include "pool.h" - /* Methode issue du code source (instance) */ struct _GDexMethod { @@ -58,12 +60,11 @@ static void g_dex_method_class_init(GDexMethodClass *); /* Procède à l'initialisation d'une methode issue du code. */ static void g_dex_method_init(GDexMethod *); +/* Supprime toutes les références externes. */ +static void g_dex_method_dispose(GDexMethod *); - - - - - +/* Procède à la libération totale de la mémoire. */ +static void g_dex_method_finalize(GDexMethod *); @@ -86,6 +87,12 @@ G_DEFINE_TYPE(GDexMethod, g_dex_method, G_TYPE_OBJECT); static void g_dex_method_class_init(GDexMethodClass *class) { + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_method_dispose; + object->finalize = (GObjectFinalizeFunc)g_dex_method_finalize; } @@ -110,6 +117,47 @@ static void g_dex_method_init(GDexMethod *method) /****************************************************************************** * * +* Paramètres : format = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_method_dispose(GDexMethod *method) +{ + if (method->routine != NULL) + g_object_unref(G_OBJECT(method->routine)); + + G_OBJECT_CLASS(g_dex_method_parent_class)->dispose(G_OBJECT(method)); + +} + + +/****************************************************************************** +* * +* Paramètres : method = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_method_finalize(GDexMethod *method) +{ + G_OBJECT_CLASS(g_dex_method_parent_class)->finalize(G_OBJECT(method)); + +} + + +/****************************************************************************** +* * * Paramètres : format = représentation interne du format DEX à consulter. * * seed = graine des informations à extraire. * * last = dernier indice utilisé (à mettre à jour). [OUT] * @@ -122,63 +170,63 @@ static void g_dex_method_init(GDexMethod *method) * * ******************************************************************************/ -GDexMethod *g_dex_method_new(const GDexFormat *format, const encoded_method *seed, uleb128_t *last) +GDexMethod *g_dex_method_new(GDexFormat *format, const encoded_method *seed, uleb128_t *last) { GDexMethod *result; /* Composant à retourner */ - off_t offset; /* Tête de lecture */ + vmpa2t addr; /* Tête de lecture générique */ code_item item; /* Corps de la méthode */ + GBinRoutine *routine; /* Routine représentée */ + mrange_t range; /* Emplacement du code associé */ + init_vmpa(&addr, seed->code_off, VMPA_NO_VIRTUAL); - GBinRoutine *routine; - - vmpa2t addr; - mrange_t range; - - - offset = seed->code_off; - - if (!read_dex_code_item(format, &offset, &item)) + if (!read_dex_code_item(format, &addr, &item)) return NULL; *last += seed->method_idx_diff; - routine = get_routine_from_dex_pool(format, *last); + routine = get_prototype_from_dex_pool(format, *last); if (routine == NULL) return NULL; - result = g_object_new(G_TYPE_DEX_METHOD, NULL); result->info = *seed; result->body = item; - //printf(" ==== (%p) %s ====\n", routine, g_binary_routine_to_string(routine)); - - //printf(" try ? %d\n", item.tries_size); + result->offset = seed->code_off + 4 * sizeof(uint16_t) + 2 *sizeof(uint32_t);/* TODO : faire plus propre ! */ - //printf(" method idx :: %d\n", seed->method_idx_diff); - //printf(" code size :: %d\n", item.insns_size); + init_vmpa(&addr, result->offset, VMPA_NO_VIRTUAL); + init_mrange(&range, &addr, item.insns_size * sizeof(uint16_t)); - /* - printf(" code regs :: %d\n", item.registers_size); - printf(" code ins :: %d\n", item.ins_size); - printf(" code outs :: %d\n", item.outs_size); - */ + g_binary_routine_set_range(routine, &range); - //printf(" method idx :: %lld\n", *last); + result->routine = routine; + return result; - result->offset = seed->code_off + 4 * sizeof(uint16_t) + 2 *sizeof(uint32_t);/* TODO : faire plus propre ! */ +} - //printf(" method off :: 0x%08x\n", result->offset); +/****************************************************************************** +* * +* Paramètres : format = représentation interne du format DEX à consulter.* +* method_id = informations de base quant à la méthode. * +* * +* Description : Crée une nouvelle représentation de methode vide. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ - init_vmpa(&addr, result->offset, VMPA_NO_VIRTUAL); - init_mrange(&range, &addr, item.insns_size * sizeof(uint16_t)); +GDexMethod *g_dex_method_new_empty(const GDexFormat *format, const method_id_item *method_id) +{ + GDexMethod *result; /* Composant à retourner */ - g_binary_routine_set_range(routine, &range); - result->routine = routine; + result = g_object_new(G_TYPE_DEX_METHOD, NULL); return result; @@ -246,33 +294,43 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method) /****************************************************************************** * * * Paramètres : method = représentation interne du format DEX à consulter. * +* raw = portion de binaire brut à raffiner. * * * -* Description : Fournit la zone binaire correspondant à la méthode. * +* Description : Intègre la méthode en tant que portion de code. * * * -* Retour : Zone binaire à analyser. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -#if 0 -GBinPart *g_dex_method_as_part(const GDexMethod *method) + +void g_dex_method_include_as_portion(const GDexMethod *method, GBinPortion *raw) { - GBinPart *result; /* Instance à retourner */ - off_t size; /* Taille du code associé */ + GBinPortion *new; /* Nouvelle portion définie */ + char *desc; /* Description d'une portion */ + vmpa2t addr; /* Emplacement dans le binaire */ - result = g_binary_part_new(); + /* Si la taille est nulle, on ne fait rien */ + if (method->info.access_flags & ACC_NATIVE) + return; - g_binary_part_set_name(result, "name"); + new = g_binary_portion_new(BPC_CODE); - if (method->info.access_flags & ACC_NATIVE) size = 0; - else size = method->body.insns_size * sizeof(uint16_t); + asprintf(&desc, _("Dalvik code")); - g_binary_part_set_values(result, method->offset, size, method->offset); + g_binary_portion_set_desc(new, desc); - return result; + free(desc); + + init_vmpa(&addr, method->offset, VMPA_NO_VIRTUAL); + g_binary_portion_set_values(new, &addr, method->body.insns_size * sizeof(uint16_t)); + + g_binary_portion_set_rights(new, PAC_READ | PAC_EXEC); + + g_binary_portion_include(raw, new); } -#endif + /****************************************************************************** * * |