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