diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2010-05-13 12:32:03 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2010-05-13 12:32:03 (GMT) |
commit | 118a668adbf6ca9d4c549618e54f58330f46ce58 (patch) | |
tree | 10e75f1a7e83ab48aba82a5a595441a065a6037e /src/format/dex | |
parent | e56b4db3aae87f0458319019635dea4968a5c529 (diff) |
Supported Dalvik VM / DEX (partially).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@155 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/dex')
-rwxr-xr-x | src/format/dex/Makefile.am | 19 | ||||
-rw-r--r-- | src/format/dex/class.c | 298 | ||||
-rw-r--r-- | src/format/dex/class.h | 71 | ||||
-rw-r--r-- | src/format/dex/dex-int.c | 518 | ||||
-rwxr-xr-x | src/format/dex/dex-int.h | 117 | ||||
-rwxr-xr-x | src/format/dex/dex.c | 307 | ||||
-rwxr-xr-x | src/format/dex/dex.h | 62 | ||||
-rwxr-xr-x | src/format/dex/dex_def.h | 189 | ||||
-rw-r--r-- | src/format/dex/method.c | 193 | ||||
-rw-r--r-- | src/format/dex/method.h | 68 | ||||
-rw-r--r-- | src/format/dex/pool.c | 197 | ||||
-rw-r--r-- | src/format/dex/pool.h | 48 |
12 files changed, 2087 insertions, 0 deletions
diff --git a/src/format/dex/Makefile.am b/src/format/dex/Makefile.am new file mode 100755 index 0000000..76cd63e --- /dev/null +++ b/src/format/dex/Makefile.am @@ -0,0 +1,19 @@ + +noinst_LTLIBRARIES = libformatdex.la + +libformatdex_la_SOURCES = \ + class.h class.c \ + dex-int.h dex-int.c \ + dex.h dex.c \ + dex_def.h \ + method.h method.c \ + pool.h pool.c + +libformatdex_la_LDFLAGS = + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/src/format/dex/class.c b/src/format/dex/class.c new file mode 100644 index 0000000..03431f0 --- /dev/null +++ b/src/format/dex/class.c @@ -0,0 +1,298 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * class.c - manipulation des classes du format DEX + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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" + + + + + + + + +/* Classe issue du code source (instance) */ +struct _GDexClass +{ + GObject parent; /* A laisser en premier */ + + 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 *); + +/* Crée une nouvelle représentation de classe issue de code. */ +static GDexClass *g_dex_class_new(const GDexFormat *, off_t); + + + + + + + + + + +/* 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) +{ + +} + + +/****************************************************************************** +* * +* 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 : format = représentation interne du format DEX à consulter. * +* offset = tête de lecture des données initiale. * +* * +* Description : Crée une nouvelle représentation de classe issue de code. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDexClass *g_dex_class_new(const GDexFormat *format, off_t offset) +{ + GDexClass *result; /* Composant à retourner */ + class_def_item def; /* Définition de la classe */ + class_data_item data; /* Contenu de la classe */ + uleb128_t i; /* Boucle de parcours */ + GDexMethod *method; /* Méthode chargée */ + + if (!read_dex_class_def_item(format, &offset, &def)) + return NULL; + + offset = def.class_data_off; + + if (!read_dex_class_data_item(format, &offset, &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); + + for (i = 0; i < data.direct_methods_size; i++) + { + method = g_dex_method_new(format, &data.direct_methods[i]); + + 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; + + } + + } + + + + for (i = 0; i < data.virtual_methods_size; i++) + { + method = g_dex_method_new(format, &data.virtual_methods[i]); + + 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; + + } + + } + + + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : class = informations chargées à consulter. * +* parts = liste à venir compléter. * +* count = quantité de zones listées. [OUT] * +* * +* Description : Fournit les références aux zones binaires à analyser. * +* * +* Retour : Zones binaires à analyser. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinPart **g_dex_class_get_parts(const GDexClass *class, GBinPart **parts, size_t *count) +{ + 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; + + } + + 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; + +} + + + + + + + + + + + + + + + + + + + + + + +/****************************************************************************** +* * +* 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; + +} diff --git a/src/format/dex/class.h b/src/format/dex/class.h new file mode 100644 index 0000000..d78e6e9 --- /dev/null +++ b/src/format/dex/class.h @@ -0,0 +1,71 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * class.h - prototypes pour la manipulation des classes du format DEX + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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/>. + */ + + +#ifndef _FORMAT_DEX_CLASS_H +#define _FORMAT_DEX_CLASS_H + + +#include <glib-object.h> + + +#include "dex.h" + + + +#define G_TYPE_DEX_CLASS (g_dex_class_get_type()) +#define G_DEX_CLASS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DEX_CLASS, GDexClass)) +#define G_DEX_CLASS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_CLASS, GDexClassClass)) +#define G_IS_DEX_CLASS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DEX_CLASS)) +#define G_IS_DEX_CLASS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_CLASS)) +#define G_DEX_CLASS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_CLASS, GDexClassClass)) + + + +/* Classe issue du code source (instance) */ +typedef struct _GDexClass GDexClass; + +/* Classe issue du code source (classe) */ +typedef struct _GDexClassClass GDexClassClass; + + + +/* Détermine le type d'une classe issue du code source. */ +GType g_dex_class_get_type(void); + +/* Fournit les références aux zones binaires à analyser. */ +GBinPart **g_dex_class_get_parts(const GDexClass *, GBinPart **, size_t *); + + + + + + + +/* Charge toutes les classes listées dans le contenu binaire. */ +bool load_all_dex_classes(GDexFormat *); + + + + + +#endif /* _FORMAT_DEX_CLASS_H */ diff --git a/src/format/dex/dex-int.c b/src/format/dex/dex-int.c new file mode 100644 index 0000000..be1c211 --- /dev/null +++ b/src/format/dex/dex-int.c @@ -0,0 +1,518 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * dex-int.c - structures internes du format DEX + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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 "dex-int.h" + + +#include <malloc.h> + + +#include "../../common/endianness.h" + + + +/* ---------------------------------------------------------------------------------- */ +/* ELEMENTS DE TABLE DES CONSTANTES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* str_id = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'un identifiant de chaîne DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_string_id_item(const GDexFormat *format, off_t *pos, string_id_item *str_id) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + result &= read_u32(&str_id->string_data_off, content, pos, length, SRE_LITTLE); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* str_data = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture de proriétés de chaîne DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_string_data_item(const GDexFormat *format, off_t *pos, string_data_item *str_data) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + result &= read_uleb128(&str_data->utf16_size, content, pos, length); + + str_data->data = &content[*pos]; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* item = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'un identifiant de type DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_type_id_item(const GDexFormat *format, off_t *pos, type_id_item *item) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + result &= read_u32(&item->descriptor_idx, content, pos, length, SRE_LITTLE); + + return result; + +} + + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* meth_id = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'une description de méthode. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_method_id_item(const GDexFormat *format, off_t *pos, method_id_item *meth_id) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + result &= read_u16(&meth_id->class_idx, content, pos, length, SRE_LITTLE); + result &= read_u16(&meth_id->proto_idx, content, pos, length, SRE_LITTLE); + result &= read_u32(&meth_id->name_idx, content, pos, length, SRE_LITTLE); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* class_def = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture des propriétés d'une classe DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_class_def_item(const GDexFormat *format, off_t *pos, class_def_item *class_def) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + result &= read_u32(&class_def->class_idx, content, pos, length, SRE_LITTLE); + result &= read_u32(&class_def->access_flags, content, pos, length, SRE_LITTLE); + result &= read_u32(&class_def->superclass_idx, content, pos, length, SRE_LITTLE); + result &= read_u32(&class_def->interfaces_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&class_def->source_file_idx, content, pos, length, SRE_LITTLE); + result &= read_u32(&class_def->annotations_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&class_def->class_data_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&class_def->static_values_off, content, pos, length, SRE_LITTLE); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* DESCRIPTION DE CLASSES DEX */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* field = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'un champ quelconque DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_encoded_field(const GDexFormat *format, off_t *pos, encoded_field *field) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + result &= read_uleb128(&field->field_idx_diff, content, pos, length); + result &= read_uleb128(&field->access_flags, content, pos, length); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* method = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'une méthode quelconque DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_encoded_method(const GDexFormat *format, off_t *pos, encoded_method *method) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + result &= read_uleb128(&method->method_idx_diff, content, pos, length); + result &= read_uleb128(&method->access_flags, content, pos, length); + result &= read_uleb128(&method->code_off, content, pos, length); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* item = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'un contenu de classe DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_class_data_item(const GDexFormat *format, off_t *pos, class_data_item *item) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + uleb128_t i; /* Boucle de parcours */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + item->static_fields = NULL; + item->instance_fields = NULL; + item->direct_methods = NULL; + item->virtual_methods = NULL; + + result &= read_uleb128(&item->static_fields_size, content, pos, length); + result &= read_uleb128(&item->instance_fields_size, content, pos, length); + result &= read_uleb128(&item->direct_methods_size, content, pos, length); + result &= read_uleb128(&item->virtual_methods_size, content, pos, length); + + if (result && item->static_fields_size > 0) + { + item->static_fields = (encoded_field *)calloc(item->static_fields_size, sizeof(encoded_field)); + + for (i = 0; i < item->static_fields_size && result; i++) + result = read_dex_encoded_field(format, pos, &item->static_fields[i]); + + } + + if (result && item->instance_fields_size > 0) + { + item->instance_fields = (encoded_field *)calloc(item->instance_fields_size, sizeof(encoded_field)); + + for (i = 0; i < item->instance_fields_size && result; i++) + result = read_dex_encoded_field(format, pos, &item->instance_fields[i]); + + } + + if (result && item->direct_methods_size > 0) + { + item->direct_methods = (encoded_method *)calloc(item->direct_methods_size, sizeof(encoded_method)); + + for (i = 0; i < item->direct_methods_size && result; i++) + result = read_dex_encoded_method(format, pos, &item->direct_methods[i]); + + } + + if (result && item->virtual_methods_size > 0) + { + item->virtual_methods = (encoded_method *)calloc(item->virtual_methods_size, sizeof(encoded_method)); + + for (i = 0; i < item->virtual_methods_size && result; i++) + result = read_dex_encoded_method(format, pos, &item->virtual_methods[i]); + + } + + if (!result) + reset_dex_class_data_item(item); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : item = structure à nettoyer. * +* * +* Description : Supprime tous les éléments chargés en mémoire à la lecture. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void reset_dex_class_data_item(class_data_item *item) +{ + if (item->static_fields != NULL) + free(item->static_fields); + + if (item->instance_fields != NULL) + free(item->instance_fields); + + if (item->direct_methods != NULL) + free(item->direct_methods); + + if (item->virtual_methods != NULL) + free(item->virtual_methods); + +} + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* item = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'une portion de code DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_code_item(const GDexFormat *format, off_t *pos, code_item *item) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + result &= read_u16(&item->registers_size, content, pos, length, SRE_LITTLE); + result &= read_u16(&item->ins_size, content, pos, length, SRE_LITTLE); + result &= read_u16(&item->outs_size, content, pos, length, SRE_LITTLE); + result &= read_u16(&item->tries_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&item->debug_info_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&item->insns_size, content, pos, length, SRE_LITTLE); + + item->insns = (uint16_t *)pos; + + return result; + +} + + + + + + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* pos = position de début de lecture. [OUT] * +* header = structure lue à retourner. [OUT] * +* * +* Description : Procède à la lecture d'une en-tête de programme DEX. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool read_dex_header(const GDexFormat *format, off_t *pos, dex_header *header) +{ + bool result; /* Bilan à retourner */ + const bin_t *content; /* Contenu binaire à lire */ + off_t length; /* Taille totale du contenu */ + size_t i; /* Boucle de parcours */ + + result = true; + + content = G_BIN_FORMAT(format)->content; + length = G_BIN_FORMAT(format)->length; + + for (i = 0; i < DEX_FILE_MAGIC_LEN && result; i++) + result = read_u8(&header->magic[i], content, pos, length, SRE_LITTLE); + + result &= read_u32(&header->checksum, content, pos, length, SRE_LITTLE); + + for (i = 0; i < 20 && result; i++) + result = read_u8(&header->signature[i], content, pos, length, SRE_LITTLE); + + result &= read_u32(&header->file_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->header_size, content, pos, length, SRE_LITTLE); + + result &= read_u32(&header->endian_tag, content, pos, length, SRE_LITTLE); + + result &= read_u32(&header->link_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->link_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->map_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->string_ids_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->string_ids_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->type_ids_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->type_ids_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->proto_ids_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->proto_ids_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->field_ids_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->field_ids_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->method_ids_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->method_ids_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->class_defs_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->class_defs_off, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->data_size, content, pos, length, SRE_LITTLE); + result &= read_u32(&header->data_off, content, pos, length, SRE_LITTLE); + + return result; + +} + + + + + diff --git a/src/format/dex/dex-int.h b/src/format/dex/dex-int.h new file mode 100755 index 0000000..e34dbd3 --- /dev/null +++ b/src/format/dex/dex-int.h @@ -0,0 +1,117 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * dex-int.h - prototypes pour les structures internes du format DEX + * + * Copyright (C) 2008 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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/>. + */ + + +#ifndef _FORMAT_DEX_DEX_INT_H +#define _FORMAT_DEX_DEX_INT_H + + +#include "class.h" +#include "dex.h" +#include "dex_def.h" +#include "../executable-int.h" + + + + + +/* Format d'exécutable DEX (instance) */ +struct _GDexFormat +{ + GExeFormat parent; /* A laisser en premier */ + + dex_header header; /* En-tête du programme */ + + + + GDexClass **classes; /* Classes retrouvées */ + size_t classes_count; /* Nombre de ces classes */ + + + +}; + +/* Format d'exécutable DEX (classe) */ +struct _GDexFormatClass +{ + GExeFormatClass parent; /* A laisser en premier */ + +}; + + + +/* ------------------------ ELEMENTS DE TABLE DES CONSTANTES ------------------------ */ + + +/* Procède à la lecture d'un identifiant de chaîne DEX. */ +bool read_dex_string_id_item(const GDexFormat *, off_t *, string_id_item *); + +/* Procède à la lecture de proriétés de chaîne DEX. */ +bool read_dex_string_data_item(const GDexFormat *, off_t *, string_data_item *); + +/* Procède à la lecture d'un identifiant de type DEX. */ +bool read_dex_type_id_item(const GDexFormat *, off_t *, type_id_item *); + + + +/* Procède à la lecture d'une description de méthode. */ +bool read_dex_method_id_item(const GDexFormat *, off_t *, method_id_item *); + +/* Procède à la lecture des propriétés d'une classe DEX. */ +bool read_dex_class_def_item(const GDexFormat *, off_t *, class_def_item *); + + + +/* --------------------------- DESCRIPTION DE CLASSES DEX --------------------------- */ + + +/* Procède à la lecture d'un champ quelconque DEX. */ +bool read_dex_encoded_field(const GDexFormat *, off_t *, encoded_field *); + +/* Procède à la lecture d'une méthode quelconque DEX. */ +bool read_dex_encoded_method(const GDexFormat *, off_t *, encoded_method *); + +/* Procède à la lecture d'un contenu de classe DEX. */ +bool read_dex_class_data_item(const GDexFormat *, off_t *, class_data_item *); + +/* Supprime tous les éléments chargés en mémoire à la lecture. */ +void reset_dex_class_data_item(class_data_item *); + + + +/* Procède à la lecture d'une portion de code DEX. */ +bool read_dex_code_item(const GDexFormat *, off_t *, code_item *); + + + + +/* Procède à la lecture d'une en-tête de programme DEX. */ +bool read_dex_header(const GDexFormat *, off_t *, dex_header *); + + + + + + + + +#endif /* _FORMAT_DEX_DEX_INT_H */ diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c new file mode 100755 index 0000000..5b68d5f --- /dev/null +++ b/src/format/dex/dex.c @@ -0,0 +1,307 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * dex.c - support du format DEX + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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 "dex.h" + + +#include <string.h> + + +#include "dex-int.h" + + + + + + + + + + + +/* Initialise la classe des formats d'exécutables DEX. */ +static void g_dex_format_class_init(GDexFormatClass *); + +/* Initialise une instance de format d'exécutable DEX. */ +static void g_dex_format_init(GDexFormat *); + +/* Indique le type d'architecture visée par le format. */ +static FormatTargetMachine g_dex_format_get_target_machine(const GDexFormat *); + +/* Fournit l'adresse mémoire du point d'entrée du programme. */ +static vmpa_t g_dex_format_get_entry_point(const GDexFormat *); + +/* Fournit les références aux zones binaires à analyser. */ +static GBinPart **g_dex_format_get_parts(const GDexFormat *, size_t *); + +/* Fournit la position correspondant à une adresse virtuelle. */ +static bool g_dex_format_translate_address_into_offset(const GDexFormat *, vmpa_t, off_t *); + +/* Fournit l'adresse virtuelle correspondant à une position. */ +static bool g_dex_format_translate_offset_into_address(const GDexFormat *, off_t, vmpa_t *); + + + +/****************************************************************************** +* * +* Paramètres : type = type de format recherché. * +* content = contenu binaire à parcourir. * +* length = taille du contenu en question. * +* * +* Description : Indique si le format peut être pris en charge ici. * +* * +* Retour : true si la réponse est positive, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool dex_is_matching(FormatType type, const uint8_t *content, off_t length) +{ + bool result; /* Bilan à faire connaître */ + + result = false; + + if (length >= DEX_FILE_MAGIC_LEN) + result = (memcmp(content, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0); + + return result; + +} + + +/* Indique le type défini pour un format d'exécutable DEX. */ +G_DEFINE_TYPE(GDexFormat, g_dex_format, G_TYPE_EXE_FORMAT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des formats d'exécutables DEX. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_format_class_init(GDexFormatClass *klass) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : format = instance à initialiser. * +* * +* Description : Initialise une instance de format d'exécutable DEX. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_format_init(GDexFormat *format) +{ + GExeFormat *exe_format; /* Format parent à constituer */ + + exe_format = G_EXE_FORMAT(format); + + exe_format->get_machine = (get_target_machine_fc)g_dex_format_get_target_machine; + exe_format->get_entry_point = (get_entry_point_fc)g_dex_format_get_entry_point; + exe_format->get_parts = (get_parts_fc)g_dex_format_get_parts; + + exe_format->translate_addr = (translate_addr_fc)g_dex_format_translate_address_into_offset; + exe_format->translate_off = (translate_off_fc)g_dex_format_translate_offset_into_address; + +} + + +/****************************************************************************** +* * +* Paramètres : content = contenu binaire à parcourir. * +* length = taille du contenu en question. * +* * +* Description : Prend en charge un nouveau format DEX. * +* * +* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.* +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinFormat *g_dex_format_new(const bin_t *content, off_t length) +{ + GDexFormat *result; /* Structure à retourner */ + off_t offset; /* Tête de lecture */ + + result = g_object_new(G_TYPE_DEX_FORMAT, NULL); + + g_binary_format_set_content(G_BIN_FORMAT(result), content, length); + + + offset = 0; + + if (!read_dex_header(result, &offset, &result->header)) + { + /* TODO */ + return NULL; + } + + /* TODO : vérifier l'en-tête ! */ + + + + if (!load_all_dex_classes(result)) + { + g_object_unref(G_OBJECT(result)); + return NULL; + } + + + + + + return G_BIN_FORMAT(result); + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Indique le type d'architecture visée par le format. * +* * +* Retour : Identifiant de l'architecture ciblée par le format. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static FormatTargetMachine g_dex_format_get_target_machine(const GDexFormat *format) +{ + return FTM_DALVIK; + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* * +* Description : Fournit l'adresse mémoire du point d'entrée du programme. * +* * +* Retour : Adresse de mémoire. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static vmpa_t g_dex_format_get_entry_point(const GDexFormat *format) +{ + return 0;//(format->is_32b ? format->header.e_entry.addr32 : format->header.e_entry.addr64); + +} + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* count = quantité de zones listées. [OUT] * +* * +* Description : Fournit les références aux zones binaires à analyser. * +* * +* Retour : Zones binaires à analyser. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GBinPart **g_dex_format_get_parts(const GDexFormat *format, size_t *count) +{ + GBinPart **result; /* Tableau à retourner */ + size_t i; /* Boucle de parcours */ + + result = NULL; + *count = 0; + + for (i = 0; i < format->classes_count; i++) + result = g_dex_class_get_parts(format->classes[i], result, count); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* addr = adresse virtuelle à retrouver. * +* pos = position correspondante. [OUT] * +* * +* Description : Fournit la position correspondant à une adresse virtuelle. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_dex_format_translate_address_into_offset(const GDexFormat *format, vmpa_t addr, off_t *pos) +{ + bool result; /* Bilan à retourner */ + + result = false; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* pos = position dans le flux binaire à retrouver. * +* addr = adresse virtuelle correspondante. [OUT] * +* * +* Description : Fournit l'adresse virtuelle correspondant à une position. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_dex_format_translate_offset_into_address(const GDexFormat *format, off_t pos, vmpa_t *addr) +{ + bool result; /* Bilan à retourner */ + + result = false; + + return result; + +} diff --git a/src/format/dex/dex.h b/src/format/dex/dex.h new file mode 100755 index 0000000..cfa72c1 --- /dev/null +++ b/src/format/dex/dex.h @@ -0,0 +1,62 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * dex.h - prototypes pour le support du format DEX + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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/>. + */ + + +#ifndef _FORMAT_DEX_DEX_H +#define _FORMAT_DEX_DEX_H + + +#include <glib-object.h> +#include <stdbool.h> +#include <sys/types.h> + + +#include "../format.h" + + + +#define G_TYPE_DEX_FORMAT g_dex_format_get_type() +#define G_DEX_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dex_format_get_type(), GDexFormat)) +#define G_IS_DEX_FORMAT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dex_format_get_type())) +#define G_DEX_FORMAT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_dex_format_get_type(), GDexFormatIface)) +#define G_DEX_FORMAT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_FORMAT, GDexFormatClass)) + + +/* Format d'exécutable DEX (instance) */ +typedef struct _GDexFormat GDexFormat; + +/* Format d'exécutable DEX (classe) */ +typedef struct _GDexFormatClass GDexFormatClass; + + +/* Indique si le format peut être pris en charge ici. */ +bool dex_is_matching(FormatType, const bin_t *, off_t); + +/* Indique le type défini pour un format d'exécutable DEX. */ +GType g_dex_format_get_type(void); + +/* Prend en charge un nouveau format DEX. */ +GBinFormat *g_dex_format_new(const bin_t *, off_t); + + + +#endif /* _FORMAT_DEX_DEX_H */ diff --git a/src/format/dex/dex_def.h b/src/format/dex/dex_def.h new file mode 100755 index 0000000..9387a90 --- /dev/null +++ b/src/format/dex/dex_def.h @@ -0,0 +1,189 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * dex_def.h - liste des structures et constantes utilisées par le format DEX + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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/>. + */ + + +#ifndef _FORMAT_DEX_DEX_DEF_H +#define _FORMAT_DEX_DEX_DEF_H + + +#include "../../common/leb128.h" + + + +/* ------------------------ ELEMENTS DE TABLE DES CONSTANTES ------------------------ */ + + +/* Chaîne de caractères */ + +typedef struct _string_id_item +{ + uint32_t string_data_off; /* Propriétés de la chaîne */ + +} string_id_item; + +typedef struct _string_data_item +{ + uleb128_t utf16_size; /* Taille du décodage */ + const uint8_t *data; /* Caractères terminés par '\0'*/ + +} string_data_item; + +/* Description d'un type */ +typedef struct _type_id_item +{ + uint32_t descriptor_idx; /* Description du type */ + +} type_id_item; + + + + +/* Description d'une méthode */ +typedef struct _method_id_item +{ + uint16_t class_idx; /* Classe d'appartenance */ + uint16_t proto_idx; /* Prototype de la méthode */ + uint32_t name_idx; /* Nom de la méthode */ + +} method_id_item; + +/* Description d'une classe */ +typedef struct _class_def_item +{ + uint32_t class_idx; /* Type de la classe */ + uint32_t access_flags; /* Drapeaux d'accès déclarés */ + uint32_t superclass_idx; /* Type de la classe parente */ + uint32_t interfaces_off; /* Liste des interfaces */ + uint32_t source_file_idx; /* Fichier source d'origine */ + uint32_t annotations_off; /* Eventuelles annotations */ + uint32_t class_data_off; /* Données de la classe */ + uint32_t static_values_off; /* Initialisations statiques */ + +} class_def_item; + + + +/* --------------------------- DESCRIPTION DE CLASSES DEX --------------------------- */ + + +/* Propriétés d'une champ */ +typedef struct _encoded_field +{ + uleb128_t field_idx_diff; /* Description du champ */ + uleb128_t access_flags; /* Conditions d'accès */ + +} encoded_field; + +/* Propriétés d'une méthode */ +typedef struct _encoded_method +{ + uleb128_t method_idx_diff; /* Description de la méthode */ + uleb128_t access_flags; /* Conditions d'accès */ + uleb128_t code_off; /* Position du code associé */ + +} encoded_method; + +/* Données de fonctionnement pour classe */ +typedef struct _class_data_item +{ + uleb128_t static_fields_size; /* Quantité de champs statiques*/ + uleb128_t instance_fields_size; /* Qté de champs instanciables */ + uleb128_t direct_methods_size; /* Qté de méthodes propres */ + uleb128_t virtual_methods_size; /* Qté de méthodes virtuelles */ + + encoded_field *static_fields; /* Champs statiques */ + encoded_field *instance_fields; /* Champs instanciables */ + encoded_method *direct_methods; /* Méthodes propres */ + encoded_method *virtual_methods; /* Méthodes virtuelles */ + +} class_data_item; + + + +/* --------------------------- PORTION DE CODE EXECUTABLE --------------------------- */ + + +/* Description de la zone */ +typedef struct _code_item +{ + uint16_t registers_size; /* Qté de registres utilisés */ + uint16_t ins_size; /* Nbre d'arguments en entrée */ + uint16_t outs_size; /* Nbre d'arguments en sortie */ + uint16_t tries_size; /* Qté de try/catch */ + uint32_t debug_info_off; /* Information de débogage */ + uint32_t insns_size; /* Nbre de blocs de 2 octets */ + + uint16_t *insns; /* Code exécutable */ + + +} code_item; + + + + +/* -------------------------- DESCRIPTION DU FORMAT DALVIK -------------------------- */ + + +/* Identifiant magique "dex\n035\0" */ +#define DEX_FILE_MAGIC "\x64\x65\x78\x0a\x30\x33\x35\x00" +#define DEX_FILE_MAGIC_LEN 8 + +/* Types de boutisme */ +#define ENDIAN_CONSTANT 0x12345678 +#define REVERSE_ENDIAN_CONSTANT 0x78563412 + + +/* En-tête de tout programe Dex */ +typedef struct _dex_header +{ + uint8_t magic[DEX_FILE_MAGIC_LEN]; /* Valeur magique du format */ + + uint32_t checksum; /* Somme de contrôle adler32 */ + uint8_t signature[20]; /* Emprunte SHA-1 du reste */ + uint32_t file_size; /* Taille du fichier */ + uint32_t header_size; /* Taille de cette en-tête */ + + uint32_t endian_tag; /* Boutisme du fichier */ + + uint32_t link_size; /* Taille de section 'liaisons'*/ + uint32_t link_off; /* Position de ladite section */ + uint32_t map_off; /* Position de la cartographie */ + uint32_t string_ids_size; /* Nombre de chaînes de carac. */ + uint32_t string_ids_off; /* Position de cette liste */ + uint32_t type_ids_size; /* Nom d'identifiant de type */ + uint32_t type_ids_off; /* Position de la liste */ + uint32_t proto_ids_size; /* Nombre de prototypes */ + uint32_t proto_ids_off; /* Position de la liste */ + uint32_t field_ids_size; /* Nombre de champs */ + uint32_t field_ids_off; /* Position de la liste */ + uint32_t method_ids_size; /* Nombre de méthodes */ + uint32_t method_ids_off; /* Position de la liste */ + uint32_t class_defs_size; /* Nombre de classes déclarées */ + uint32_t class_defs_off; /* Position de la liste */ + uint32_t data_size; /* Taille des données */ + uint32_t data_off; /* Début des données */ + +} dex_header; + + + +#endif /* _FORMAT_DEX_DEX_DEF_H */ diff --git a/src/format/dex/method.c b/src/format/dex/method.c new file mode 100644 index 0000000..3a604d0 --- /dev/null +++ b/src/format/dex/method.c @@ -0,0 +1,193 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * method.c - manipulation des methodes du format DEX + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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 "method.h" + + +#include "dex-int.h" +#include "pool.h" + + + + + +/* Methode issue du code source (instance) */ +struct _GDexMethod +{ + GObject parent; /* A laisser en premier */ + + GBinRoutine *routine; /* Représentation interne */ + + code_item body; /* Corps de la méthode */ + off_t offset; /* Position du code */ + +}; + +/* Methode issue du code source (classe) */ +struct _GDexMethodClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Procède à l'initialisation d'une methode issue du code. */ +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 *); + + + + + + + + + + +/* Détermine le type d'une methode issue du code source. */ +G_DEFINE_TYPE(GDexMethod, g_dex_method, G_TYPE_OBJECT); + + + +/****************************************************************************** +* * +* Paramètres : class = classe de composant GLib à initialiser. * +* * +* Description : Procède à l'initialisation d'une methode issue du code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_method_class_init(GDexMethodClass *class) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : method = composant GLib à initialiser. * +* * +* Description : Procède à l'initialisation d'une methode issue du code. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dex_method_init(GDexMethod *method) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : format = représentation interne du format DEX à consulter. * +* seed = graine des informations à extraire. * +* * +* Description : Crée une nouvelle représentation de methode issue de code. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDexMethod *g_dex_method_new(const GDexFormat *format, const encoded_method *seed) +{ + GDexMethod *result; /* Composant à retourner */ + off_t offset; /* Tête de lecture */ + code_item item; /* Corps de la méthode */ + + + GBinRoutine *routine; + + offset = seed->code_off; + + if (!read_dex_code_item(format, &offset, &item)) + return NULL; + + result = g_object_new(G_TYPE_DEX_METHOD, NULL); + + result->body = item; + + //printf(" method idx :: %d\n", seed->method_idx_diff); + //printf(" code size :: %d\n", item.insns_size); + + + routine = get_routine_from_dex_pool(format, seed->method_idx_diff); + + + + result->offset = seed->code_off + 4 * sizeof(uint16_t) + 2 *sizeof(uint32_t);/* TODO : faire plus propre ! */ + + + + g_binary_routine_set_address(routine, result->offset); + + + g_binary_format_add_routine(G_BIN_FORMAT(format), routine); + + + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : method = représentation interne du format DEX à consulter. * +* * +* Description : Fournit la zone binaire correspondant à la méthode. * +* * +* Retour : Zone binaire à analyser. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinPart *g_dex_method_as_part(const GDexMethod *method) +{ + GBinPart *result; /* Instance à retourner */ + + result = g_binary_part_new(); + + g_binary_part_set_name(result, "name"); + + g_binary_part_set_values(result, + method->offset, method->body.insns_size * sizeof(uint16_t), method->offset); + + return result; + +} + + + diff --git a/src/format/dex/method.h b/src/format/dex/method.h new file mode 100644 index 0000000..dd6f4b1 --- /dev/null +++ b/src/format/dex/method.h @@ -0,0 +1,68 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * method.h - prototypes pour la manipulation des methodes du format DEX + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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/>. + */ + + +#ifndef _FORMAT_DEX_METHOD_H +#define _FORMAT_DEX_METHOD_H + + +#include <glib-object.h> + + +#include "dex.h" +#include "dex_def.h" + + + +#define G_TYPE_DEX_METHOD (g_dex_method_get_type()) +#define G_DEX_METHOD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DEX_METHOD, GDexMethod)) +#define G_DEX_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_METHOD, GDexMethodClass)) +#define G_IS_DEX_METHOD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DEX_METHOD)) +#define G_IS_DEX_METHOD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_METHOD)) +#define G_DEX_METHOD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_METHOD, GDexMethodClass)) + + + +/* Methode issue du code source (instance) */ +typedef struct _GDexMethod GDexMethod; + +/* Methode issue du code source (classe) */ +typedef struct _GDexMethodClass GDexMethodClass; + + + +/* Détermine le type d'une methode issue du code source. */ +GType g_dex_method_get_type(void); + +/* Crée une nouvelle représentation de methode issue de code. */ +GDexMethod *g_dex_method_new(const GDexFormat *, const encoded_method *); + +/* Fournit la zone binaire correspondant à la méthode. */ +GBinPart *g_dex_method_as_part(const GDexMethod *); + + + + + + + +#endif /* _FORMAT_DEX_METHOD_H */ diff --git a/src/format/dex/pool.c b/src/format/dex/pool.c new file mode 100644 index 0000000..0a8bed3 --- /dev/null +++ b/src/format/dex/pool.c @@ -0,0 +1,197 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * pool.c - extraction des informations issues des tables globales + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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 "pool.h" + + +#include "dex-int.h" +#include "../mangling/demangler.h" + + + +/****************************************************************************** +* * +* Paramètres : format = représentation interne du format DEX à consulter. * +* index = index du type recherchée. * +* * +* Description : Extrait une représentation de type d'une table DEX. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GOpenidaType *get_type_from_dex_pool(const GDexFormat *format, uint16_t index) +{ + off_t pos; /* Tête de lecture */ + type_id_item type_id; /* Définition de la classe */ + string_id_item str_id; /* Identifiant de chaîne */ + string_data_item str_data; /* Description de chaîne */ + + + //printf("Index :: 0x%04hx\n", index); + + + pos = format->header.type_ids_off + index * sizeof(type_id_item); + + if (!read_dex_type_id_item(format, &pos, &type_id)) + return NULL; + + + + + pos = format->header.string_ids_off + type_id.descriptor_idx * sizeof(string_id_item); + + if (!read_dex_string_id_item(format, &pos, &str_id)) + return NULL; + + pos = str_id.string_data_off; + + if (!read_dex_string_data_item(format, &pos, &str_data)) + return NULL; + + + //printf(">> String :: '%s'\n", str_data.data); + + + return demangle_type(DGT_JAVA, (char *)str_data.data); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : format = représentation interne du format DEX à consulter. * +* index = index de la classe recherchée. * +* * +* Description : Extrait une représentation de classe d'une table DEX. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GOpenidaType *get_class_from_dex_pool(const GDexFormat *format, uint16_t index) +{ + GOpenidaType *result; /* Instance à retourner */ + off_t pos; /* Tête de lecture */ + class_def_item class_def; /* Définition de la classe */ + + pos = format->header.class_defs_off + index * sizeof(class_def_item); + + if (!read_dex_class_def_item(format, &pos, &class_def)) + return NULL; + + + + result = NULL; + + + return result; + +} + + + + + + +/****************************************************************************** +* * +* Paramètres : format = représentation interne du format DEX à consulter. * +* index = index de la routine recherchée. * +* * +* Description : Extrait une représentation de routine d'une table DEX. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinRoutine *get_routine_from_dex_pool(const GDexFormat *format, uleb128_t index) +{ + GBinRoutine *result; /* Instance à retourner */ + off_t pos; /* Tête de lecture */ + method_id_item meth_id; /* Description de la méthode */ + + + GOpenidaType *type; + + string_id_item str_id; /* Identifiant de chaîne */ + string_data_item str_data; /* Description de chaîne */ + + pos = format->header.method_ids_off + index * sizeof(method_id_item); + + if (!read_dex_method_id_item(format, &pos, &meth_id)) + return NULL; + + + + + + + type = get_type_from_dex_pool(format, meth_id.class_idx); + + /* + if (type == NULL) + printf("class is nil\n"); + + else + printf("class = '%s'\n", g_openida_type_to_string(type)); + */ + + /* Nom de la méthode */ + + pos = format->header.string_ids_off + meth_id.name_idx * sizeof(string_id_item); + + if (!read_dex_string_id_item(format, &pos, &str_id)) + return NULL; + + pos = str_id.string_data_off; + + if (!read_dex_string_data_item(format, &pos, &str_data)) + return NULL; + + + //printf("String :: '%s'\n", str_data.data); + + + result = g_binary_routine_new(); + + g_binary_routine_set_name(result, (char *)str_data.data); + + if (type != NULL) + g_binary_routine_set_namespace(result, type); + + + //printf("==>>> routine :: '%s'\n", g_binary_routine_to_string(result)); + + return result; + +} diff --git a/src/format/dex/pool.h b/src/format/dex/pool.h new file mode 100644 index 0000000..a41a1da --- /dev/null +++ b/src/format/dex/pool.h @@ -0,0 +1,48 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * pool.h - prototypes pour l'extraction des informations issues des tables globales + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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/>. + */ + + +#ifndef _FORMAT_DEX_POOL_H +#define _FORMAT_DEX_POOL_H + + +#include "dex.h" +#include "../../analysis/routine.h" +#include "../../common/leb128.h" + + + +/* Extrait une représentation de type d'une table DEX. */ +GOpenidaType *get_type_from_dex_pool(const GDexFormat *, uint16_t); + + +/* Extrait une représentation de classe d'une table DEX. */ +GOpenidaType *get_class_from_dex_pool(const GDexFormat *, uint16_t); + + + +/* Extrait une représentation de routine d'une table DEX. */ +GBinRoutine *get_routine_from_dex_pool(const GDexFormat *, uleb128_t); + + + +#endif /* _FORMAT_DEX_POOL_H */ |