diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-10-01 15:55:39 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-10-01 15:55:39 (GMT) |
commit | d51fef170f00602744e55a8fdb21a3c7d196696a (patch) | |
tree | 5f51c1cdb09669da974c1b99d280a4e7078aab7f /src/format/dex/class.c | |
parent | 9aa5b354e83825e2d9843aea742aa62221a2130b (diff) |
Rewritten the whole support of DEX file format.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@581 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/dex/class.c')
-rw-r--r-- | src/format/dex/class.c | 291 |
1 files changed, 102 insertions, 189 deletions
diff --git a/src/format/dex/class.c b/src/format/dex/class.c index b866cd7..657461f 100644 --- a/src/format/dex/class.c +++ b/src/format/dex/class.c @@ -33,11 +33,6 @@ - - - - - /* Classe issue du code source (instance) */ struct _GDexClass { @@ -66,17 +61,14 @@ static void g_dex_class_class_init(GDexClassClass *); /* Procède à l'initialisation d'une classe issue du code source. */ static void g_dex_class_init(GDexClass *); -/* Crée une nouvelle représentation de classe issue de code. */ -static GDexClass *g_dex_class_new(const GDexFormat *, off_t); - -/* Inscrit les méthodes d'une classe en tant que routines. */ -static void g_dex_class_register_method(const GDexClass *, GBinFormat *); - - - - +/* Supprime toutes les références externes. */ +static void g_dex_class_dispose(GDexClass *); +/* Procède à la libération totale de la mémoire. */ +static void g_dex_class_finalize(GDexClass *); +/* Inscrit les méthodes d'une classe en tant que routines. */ +//static void g_dex_class_register_method(const GDexClass *, GBinFormat *); @@ -84,7 +76,6 @@ static void g_dex_class_register_method(const GDexClass *, GBinFormat *); G_DEFINE_TYPE(GDexClass, g_dex_class, G_TYPE_OBJECT); - /****************************************************************************** * * * Paramètres : class = classe de composant GLib à initialiser. * @@ -99,6 +90,12 @@ G_DEFINE_TYPE(GDexClass, g_dex_class, G_TYPE_OBJECT); static void g_dex_class_class_init(GDexClassClass *class) { + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_class_dispose; + object->finalize = (GObjectFinalizeFunc)g_dex_class_finalize; } @@ -123,8 +120,64 @@ static void g_dex_class_init(GDexClass *class) /****************************************************************************** * * +* Paramètres : class = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_class_dispose(GDexClass *class) +{ + size_t i; /* Boucle de parcours */ + + if (class->direct_methods != NULL) + for (i = 0; i < class->dmethods_count; i++) + if (class->direct_methods[i] != NULL) + g_object_unref(G_OBJECT(class->direct_methods[i])); + + if (class->virtual_methods != NULL) + for (i = 0; i < class->vmethods_count; i++) + if (class->virtual_methods[i] != NULL) + g_object_unref(G_OBJECT(class->virtual_methods[i])); + + G_OBJECT_CLASS(g_dex_class_parent_class)->dispose(G_OBJECT(class)); + +} + + +/****************************************************************************** +* * +* Paramètres : class = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_class_finalize(GDexClass *class) +{ + if (class->direct_methods != NULL) + free(class->direct_methods); + + if (class->virtual_methods != NULL) + free(class->virtual_methods); + + G_OBJECT_CLASS(g_dex_class_parent_class)->finalize(G_OBJECT(class)); + +} + + +/****************************************************************************** +* * * Paramètres : format = représentation interne du format DEX à consulter. * -* offset = tête de lecture des données initiale. * +* def = définitions générales associées à la classe. * * * * Description : Crée une nouvelle représentation de classe issue de code. * * * @@ -134,120 +187,66 @@ static void g_dex_class_init(GDexClass *class) * * ******************************************************************************/ -static GDexClass *g_dex_class_new(const GDexFormat *format, off_t offset) +GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def) { GDexClass *result; /* Composant à retourner */ - class_def_item def; /* Définition de la classe */ + vmpa2t addr; /* Tête de lecture générique */ class_data_item data; /* Contenu de la classe */ uleb128_t index; /* Conservation du dernier id */ uleb128_t i; /* Boucle de parcours */ GDexMethod *method; /* Méthode chargée */ - if (!read_dex_class_def_item(format, &offset, &def)) - return NULL; + init_vmpa(&addr, def->class_data_off, VMPA_NO_VIRTUAL); - offset = def.class_data_off; - - if (!read_dex_class_data_item(format, &offset, &data)) + if (!read_dex_class_data_item(format, &addr, &data)) return NULL; - - - //printf(" Classe :: d meth count == 0x%lld\n", data.direct_methods_size); - //printf(" Classe :: v meth count == 0x%lld\n", data.virtual_methods_size); - - - result = g_object_new(G_TYPE_DEX_CLASS, NULL); - result->definition = def; + result->definition = *def; + + /** + * On évite ici les méthodes (virtuelles) non définies. + */ + if (def->access_flags & ACC_ANNOTATION) goto gdcn_done; index = 0; + result->dmethods_count = data.direct_methods_size; + result->direct_methods = (GDexMethod **)calloc(result->dmethods_count, sizeof(GDexMethod *)); + for (i = 0; i < data.direct_methods_size; i++) { method = g_dex_method_new(format, &data.direct_methods[i], &index); + if (method == NULL) goto gdcn_bad_method; - if (method != NULL) - { - result->dmethods_count++; - result->direct_methods = (GDexMethod **)realloc(result->direct_methods, - result->dmethods_count * sizeof(GDexMethod *)); - - result->direct_methods[result->dmethods_count - 1] = method; - - } + result->direct_methods[i] = method; } index = 0; + result->vmethods_count = data.virtual_methods_size; + result->virtual_methods = (GDexMethod **)calloc(result->vmethods_count, sizeof(GDexMethod *)); + for (i = 0; i < data.virtual_methods_size; i++) { method = g_dex_method_new(format, &data.virtual_methods[i], &index); + if (method == NULL) goto gdcn_bad_method; - if (method != NULL) - { - result->vmethods_count++; - result->virtual_methods = (GDexMethod **)realloc(result->virtual_methods, - result->vmethods_count * sizeof(GDexMethod *)); - - result->virtual_methods[result->vmethods_count - 1] = method; - - } + result->virtual_methods[i] = method; } - + gdcn_done: return result; -} + gdcn_bad_method: + g_object_unref(G_OBJECT(result)); -/****************************************************************************** -* * -* Paramètres : class = informations chargées à consulter. * -* format = format binaire à compléter. * -* * -* Description : Inscrit les méthodes d'une classe en tant que routines. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_dex_class_register_method(const GDexClass *class, GBinFormat *format) -{ - size_t i; /* Boucle de parcours */ - GBinRoutine *routine; /* Routine à inscrire */ - - for (i = 0; i < class->dmethods_count; i++) - { - routine = g_dex_method_get_routine(class->direct_methods[i]); - g_binary_format_add_routine(format, routine); - - /* - printf("routine @ 0x%08llx :: '%s'\n", - g_binary_routine_get_address(routine), - g_binary_routine_get_name(routine)); - */ - - } - - for (i = 0; i < class->vmethods_count; i++) - { - routine = g_dex_method_get_routine(class->virtual_methods[i]); - g_binary_format_add_routine(format, routine); - - /* - printf("routine @ 0x%08llx :: '%s'\n", - g_binary_routine_get_address(routine), - g_binary_routine_get_name(routine)); - */ - - } + return NULL; } @@ -310,47 +309,27 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t /****************************************************************************** * * * Paramètres : class = informations chargées à consulter. * -* parts = liste à venir compléter. * -* count = quantité de zones listées. [OUT] * +* raw = portion de binaire brut à raffiner. * * * -* Description : Fournit les références aux zones binaires à analyser. * +* Description : Intègre la méthode en tant que portion de code. * * * -* Retour : Zones binaires à analyser. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -#if 0 -GBinPart **g_dex_class_get_parts(const GDexClass *class, GBinPart **parts, size_t *count) + +void g_dex_class_include_as_portion(const GDexClass *class, GBinPortion *raw) { size_t i; /* Boucle de parcours */ - GBinPart *part; /* Partie à intégrer à la liste*/ for (i = 0; i < class->dmethods_count; i++) - { - part = g_dex_method_as_part(class->direct_methods[i]); - - parts = (GBinPart **)realloc(parts, ++(*count) * sizeof(GBinPart *)); - parts[*count - 1] = part; - - } + g_dex_method_include_as_portion(class->direct_methods[i], raw); for (i = 0; i < class->vmethods_count; i++) - { - part = g_dex_method_as_part(class->virtual_methods[i]); - - parts = (GBinPart **)realloc(parts, ++(*count) * sizeof(GBinPart *)); - parts[*count - 1] = part; - - } - - return parts; + g_dex_method_include_as_portion(class->virtual_methods[i], raw); } -#endif - - - /****************************************************************************** @@ -428,7 +407,7 @@ const char *g_dex_class_get_source_file(const GDexClass *class, const GDexFormat void g_dex_class_decompile(const GDexClass *class, GLangOutput *lang, GCodeBuffer *buffer, const GDexFormat *format) { - +#if 0 GDataType *type; @@ -482,7 +461,7 @@ GBufferLine *line, GLangOutput *output) - +#endif } @@ -500,69 +479,3 @@ GBufferLine *line, GLangOutput *output) - - -/****************************************************************************** -* * -* Paramètres : format = représentation interne du format DEX à compléter. * -* * -* Description : Charge toutes les classes listées dans le contenu binaire. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool load_all_dex_classes(GDexFormat *format) -{ - const dex_header *header; /* Raccourci d'usage */ - uint32_t i; /* Boucle de parcours */ - GDexClass *class; /* Représentation chargée */ - - header = &format->header; - - for (i = 0; i < header->class_defs_size; i++) - { - class = g_dex_class_new(format, header->class_defs_off + i * sizeof(class_def_item)); - - if (class != NULL) - { - format->classes_count++; - format->classes = (GDexClass **)realloc(format->classes, - format->classes_count * sizeof(GDexClass *)); - - format->classes[format->classes_count - 1] = class; - - } - - } - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : format = représentation interne du format DEX à compléter. * -* * -* Description : Enregistre toutes les méthodes des classes listées. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void register_all_dex_class_methods(GDexFormat *format) -{ - size_t i; /* Boucle de parcours */ - GBinFormat *bformat; /* Autre version du format */ - - bformat = G_BIN_FORMAT(format); - - for (i = 0; i < format->classes_count; i++) - g_dex_class_register_method(format->classes[i], bformat); - -} |