diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-10-18 20:50:10 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-10-18 20:50:10 (GMT) |
commit | dce9d9cdfef1d37ef11a987a21f36e83b6b1944f (patch) | |
tree | 830623ade20e892954fcbddd3b7b05d09aac1dd7 /src/format/dex/class.c | |
parent | 1e7c7de85438749d3faf7b76984b86a9c088fbc1 (diff) |
Created plugins for the Dex and Dalvik support.
Diffstat (limited to 'src/format/dex/class.c')
-rw-r--r-- | src/format/dex/class.c | 576 |
1 files changed, 0 insertions, 576 deletions
diff --git a/src/format/dex/class.c b/src/format/dex/class.c deleted file mode 100644 index bb2ae71..0000000 --- a/src/format/dex/class.c +++ /dev/null @@ -1,576 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * class.c - manipulation des classes du format DEX - * - * Copyright (C) 2010-2017 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 Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "class.h" - - -#include <malloc.h> - - -#include "dex-int.h" -#include "method.h" -#include "pool.h" - - - -/* Classe issue du code source (instance) */ -struct _GDexClass -{ - GObject parent; /* A laisser en premier */ - - class_def_item definition; /* Définition de la classe */ - bool has_data; /* Indicateur de présence */ - class_data_item data; /* Contenu de la classe */ - - GDexMethod **direct_methods; /* Méthodes propres */ - size_t dmethods_count; /* Quantité de ces méthodes */ - GDexMethod **virtual_methods; /* Méthodes virtuelles */ - size_t vmethods_count; /* Quantité de ces méthodes */ - -}; - -/* Classe issue du code source (classe) */ -struct _GDexClassClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Procède à l'initialisation d'une classe issue du code source. */ -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 *); - -/* 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 *); - - - -/* Détermine le type d'une classe issue du code source. */ -G_DEFINE_TYPE(GDexClass, g_dex_class, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : class = classe de composant GLib à initialiser. * -* * -* Description : Procède à l'initialisation d'une classe issue du code source.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -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; - -} - - -/****************************************************************************** -* * -* Paramètres : class = composant GLib à initialiser. * -* * -* Description : Procède à l'initialisation d'une classe issue du code source.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -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. * -* def = définitions générales associées à la classe. * -* * -* Description : Crée une nouvelle représentation de classe issue de code. * -* * -* Retour : Composant GLib créé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def) -{ - GDexClass *result; /* Composant à retourner */ - vmpa2t addr; /* Tête de lecture générique */ - class_data_item data; /* Contenu de la classe */ - GDataType *ctype; /* Type créé par la classe */ - GBinFormat *base; /* Autre version du format */ - uleb128_t index; /* Conservation du dernier id */ - uleb128_t i; /* Boucle de parcours */ - GDexMethod *method; /* Méthode chargée */ - GBinRoutine *routine; /* Version interne de méthode */ - - result = g_object_new(G_TYPE_DEX_CLASS, NULL); - - result->definition = *def; - result->has_data = (def->class_data_off != 0); - - /* Interface vide ? */ - if (!result->has_data) - { - result->dmethods_count = 0; - result->direct_methods = NULL; - - result->vmethods_count = 0; - result->virtual_methods = NULL; - - goto gdcn_done; - - } - - init_vmpa(&addr, def->class_data_off, VMPA_NO_VIRTUAL); - - if (!read_dex_class_data_item(format, &addr, &data)) - goto gdcn_bad_item; - - result->data = data; - - /** - * On évite ici les méthodes (virtuelles) non définies. - */ - if (def->access_flags & ACC_ANNOTATION) goto gdcn_done; - - ctype = get_type_from_dex_pool(format, def->class_idx); - if (ctype == NULL) goto gdcn_unknown_type; - - base = G_BIN_FORMAT(format); - - 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_defined(format, &data.direct_methods[i], &index); - if (method == NULL) goto gdcn_bad_method; - - result->direct_methods[i] = method; - - /* Ajout à la liste des symboles */ - if (g_dex_method_has_dex_body(method)) - { - routine = g_dex_method_get_routine(method); - - g_object_ref(G_OBJECT(ctype)); - g_binary_routine_set_namespace(routine, ctype, "."); - - g_binary_format_add_symbol(base, G_BIN_SYMBOL(routine)); - - } - - } - - 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_defined(format, &data.virtual_methods[i], &index); - if (method == NULL) goto gdcn_bad_method; - - result->virtual_methods[i] = method; - - /* Ajout à la liste des symboles */ - if (g_dex_method_has_dex_body(method)) - { - routine = g_dex_method_get_routine(method); - - g_object_ref(G_OBJECT(ctype)); - g_binary_routine_set_namespace(routine, ctype, "."); - - g_binary_format_add_symbol(base, G_BIN_SYMBOL(routine)); - - } - - } - - g_object_unref(G_OBJECT(ctype)); - - gdcn_done: - - return result; - - gdcn_bad_method: - - g_object_unref(G_OBJECT(ctype)); - - gdcn_unknown_type: - - gdcn_bad_item: - - g_object_unref(G_OBJECT(result)); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : class = informations chargées à consulter. * -* * -* Description : Fournit la définition brute d'une classe. * -* * -* Retour : Données brutes issues du binaire chargé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const class_def_item *g_dex_class_get_definition(const GDexClass *class) -{ - return &class->definition; - -} - - -/****************************************************************************** -* * -* Paramètres : class = informations chargées à consulter. * -* * -* Description : Fournit la définition brute des données d'une classe. * -* * -* Retour : Données brutes issues du binaire chargé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const class_data_item *g_dex_class_get_data(const GDexClass *class) -{ - return (class->has_data ? &class->data : NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : class = informations chargées à consulter. * -* virtual = précise la nature des méthodes ciblées. * -* * -* Description : Dénombre les méthodes chargées d'un type donné. * -* * -* Retour : Quantité de méthodes trouvées. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_dex_class_count_methods(const GDexClass *class, bool virtual) -{ - size_t result; /* Compte à retourner */ - - if (virtual) - result = class->vmethods_count; - else - result = class->dmethods_count; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = informations chargées à consulter. * -* virtual = précise la nature des méthodes ciblées. * -* index = indique l'indice de la méthode désirée. * -* * -* Description : Fournit une méthode chargée correspondant à un type donné. * -* * -* Retour : Quantité de méthodes trouvées. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t index) -{ - GDexMethod *result; /* Instance à renvoyer */ - - if (virtual) - result = class->virtual_methods[index]; - else - result = class->direct_methods[index]; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = informations chargées à consulter. * -* format = format permettant d'obtenir une adresse complète. * -* * -* Description : Intègre la méthode en tant que portion de code. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_dex_class_include_as_portion(const GDexClass *class, GExeFormat *format) -{ - size_t i; /* Boucle de parcours */ - - for (i = 0; i < class->dmethods_count; i++) - g_dex_method_include_as_portion(class->direct_methods[i], format); - - for (i = 0; i < class->vmethods_count; i++) - g_dex_method_include_as_portion(class->virtual_methods[i], format); - -} - - -/****************************************************************************** -* * -* Paramètres : class = informations chargées à consulter. * -* addr = adresse de la routine à retrouver. * -* * -* Description : Retrouve si possible la méthode associée à une adresse. * -* * -* Retour : Méthde retrouvée ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GDexMethod *g_dex_class_find_method_by_address(const GDexClass *class, vmpa_t addr) -{ - GDexMethod *result; /* Trouvaille à retourner */ - size_t i; /* Boucle de parcours */ - phys_t offset; /* Emplacement de méthode */ - - result = NULL; - -#if 0 /* FIXME */ - /* - -bool g_dex_method_get_offset(const GDexMethod *method, phys_t *offset) - - if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), method->offset, &addr)) - return; - - */ - - for (i = 0; i < class->dmethods_count && result == NULL; i++) - if (addr == (vmpa_t)g_dex_method_get_offset(class->direct_methods[i])) - result = class->direct_methods[i]; - - for (i = 0; i < class->vmethods_count && result == NULL; i++) - if (addr == (vmpa_t)g_dex_method_get_offset(class->virtual_methods[i])) - result = class->virtual_methods[i]; -#endif - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = informations chargées à consulter. * -* format = représentation interne du format DEX à compléter. * -* * -* Description : Retrouve si possible le nom du fichier source d'une classe. * -* * -* Retour : Nom du fichier trouvé ou NULL si aucun. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *g_dex_class_get_source_file(const GDexClass *class, const GDexFormat *format) -{ - const char *result; /* Trouvaille à renvoyer */ - - result = get_string_from_dex_pool(format, class->definition.source_file_idx, NULL); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : class = informations chargées à consulter. * -* lang = langage à utiliser pour la sortie humaine. * -* buffer = tampon mis à disposition pour la sortie. * -* format = informations chargées à consulter. * -* * -* Description : Procède à la décompilation complète d'une classe donnée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -#if 0 -void g_dex_class_decompile(const GDexClass *class, GLangOutput *lang, GCodeBuffer *buffer, const GDexFormat *format) -{ - -#if 0 - GDataType *type; - - - size_t i; /* Boucle de parcours */ - - - /* -GBufferLine *line, GLangOutput *output) - - for (i = 0; i < block->count; i++) - { - if (i > 0) - line = g_code_buffer_append_new_line(buffer); - -*/ - - - - type = get_type_from_dex_pool(format, class->definition.class_idx); - - //g_buffer_line_append_text(line, BLC_ASSEMBLY, "{", 3, RTT_SIGNS, NULL); - - //printf("Output :: %s\n", _g_data_type_to_string(type, true)); - - - - g_lang_output_start_class(lang, buffer, type); - - - - for (i = 0; i < class->vmethods_count; i++) - { - g_dex_method_decompile(class->virtual_methods[i], lang, buffer); - g_code_buffer_append_new_line_fixme(buffer); - } - - for (i = 0; i < class->dmethods_count; i++) - { - g_dex_method_decompile(class->direct_methods[i], lang, buffer); - g_code_buffer_append_new_line_fixme(buffer); - } - - - - - - - - - g_lang_output_end_class(lang, buffer); - - - -#endif - - -} -#endif |