summaryrefslogtreecommitdiff
path: root/src/format/dex/dex-int.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/format/dex/dex-int.c')
-rw-r--r--src/format/dex/dex-int.c518
1 files changed, 518 insertions, 0 deletions
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;
+
+}
+
+
+
+
+