summaryrefslogtreecommitdiff
path: root/src/format/dex
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-10-01 15:55:39 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-10-01 15:55:39 (GMT)
commitd51fef170f00602744e55a8fdb21a3c7d196696a (patch)
tree5f51c1cdb09669da974c1b99d280a4e7078aab7f /src/format/dex
parent9aa5b354e83825e2d9843aea742aa62221a2130b (diff)
Rewritten the whole support of DEX file format.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@581 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/format/dex')
-rw-r--r--src/format/dex/class.c291
-rw-r--r--src/format/dex/class.h14
-rw-r--r--src/format/dex/dex-int.c370
-rwxr-xr-xsrc/format/dex/dex-int.h51
-rwxr-xr-xsrc/format/dex/dex.c364
-rwxr-xr-xsrc/format/dex/dex.h6
-rwxr-xr-xsrc/format/dex/dex_def.h2
-rw-r--r--src/format/dex/method.c156
-rw-r--r--src/format/dex/method.h9
-rw-r--r--src/format/dex/pool.c472
-rw-r--r--src/format/dex/pool.h31
11 files changed, 1010 insertions, 756 deletions
diff --git a/src/format/dex/class.c b/src/format/dex/class.c
index b866cd7..657461f 100644
--- a/src/format/dex/class.c
+++ b/src/format/dex/class.c
@@ -33,11 +33,6 @@
-
-
-
-
-
/* Classe issue du code source (instance) */
struct _GDexClass
{
@@ -66,17 +61,14 @@ static void g_dex_class_class_init(GDexClassClass *);
/* Procède à l'initialisation d'une classe issue du code source. */
static void g_dex_class_init(GDexClass *);
-/* Crée une nouvelle représentation de classe issue de code. */
-static GDexClass *g_dex_class_new(const GDexFormat *, off_t);
-
-/* Inscrit les méthodes d'une classe en tant que routines. */
-static void g_dex_class_register_method(const GDexClass *, GBinFormat *);
-
-
-
-
+/* Supprime toutes les références externes. */
+static void g_dex_class_dispose(GDexClass *);
+/* Procède à la libération totale de la mémoire. */
+static void g_dex_class_finalize(GDexClass *);
+/* Inscrit les méthodes d'une classe en tant que routines. */
+//static void g_dex_class_register_method(const GDexClass *, GBinFormat *);
@@ -84,7 +76,6 @@ static void g_dex_class_register_method(const GDexClass *, GBinFormat *);
G_DEFINE_TYPE(GDexClass, g_dex_class, G_TYPE_OBJECT);
-
/******************************************************************************
* *
* Paramètres : class = classe de composant GLib à initialiser. *
@@ -99,6 +90,12 @@ G_DEFINE_TYPE(GDexClass, g_dex_class, G_TYPE_OBJECT);
static void g_dex_class_class_init(GDexClassClass *class)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_class_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dex_class_finalize;
}
@@ -123,8 +120,64 @@ static void g_dex_class_init(GDexClass *class)
/******************************************************************************
* *
+* Paramètres : class = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_class_dispose(GDexClass *class)
+{
+ size_t i; /* Boucle de parcours */
+
+ if (class->direct_methods != NULL)
+ for (i = 0; i < class->dmethods_count; i++)
+ if (class->direct_methods[i] != NULL)
+ g_object_unref(G_OBJECT(class->direct_methods[i]));
+
+ if (class->virtual_methods != NULL)
+ for (i = 0; i < class->vmethods_count; i++)
+ if (class->virtual_methods[i] != NULL)
+ g_object_unref(G_OBJECT(class->virtual_methods[i]));
+
+ G_OBJECT_CLASS(g_dex_class_parent_class)->dispose(G_OBJECT(class));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : class = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_class_finalize(GDexClass *class)
+{
+ if (class->direct_methods != NULL)
+ free(class->direct_methods);
+
+ if (class->virtual_methods != NULL)
+ free(class->virtual_methods);
+
+ G_OBJECT_CLASS(g_dex_class_parent_class)->finalize(G_OBJECT(class));
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = représentation interne du format DEX à consulter. *
-* offset = tête de lecture des données initiale. *
+* def = définitions générales associées à la classe. *
* *
* Description : Crée une nouvelle représentation de classe issue de code. *
* *
@@ -134,120 +187,66 @@ static void g_dex_class_init(GDexClass *class)
* *
******************************************************************************/
-static GDexClass *g_dex_class_new(const GDexFormat *format, off_t offset)
+GDexClass *g_dex_class_new(GDexFormat *format, const class_def_item *def)
{
GDexClass *result; /* Composant à retourner */
- class_def_item def; /* Définition de la classe */
+ vmpa2t addr; /* Tête de lecture générique */
class_data_item data; /* Contenu de la classe */
uleb128_t index; /* Conservation du dernier id */
uleb128_t i; /* Boucle de parcours */
GDexMethod *method; /* Méthode chargée */
- if (!read_dex_class_def_item(format, &offset, &def))
- return NULL;
+ init_vmpa(&addr, def->class_data_off, VMPA_NO_VIRTUAL);
- offset = def.class_data_off;
-
- if (!read_dex_class_data_item(format, &offset, &data))
+ if (!read_dex_class_data_item(format, &addr, &data))
return NULL;
-
-
- //printf(" Classe :: d meth count == 0x%lld\n", data.direct_methods_size);
- //printf(" Classe :: v meth count == 0x%lld\n", data.virtual_methods_size);
-
-
-
result = g_object_new(G_TYPE_DEX_CLASS, NULL);
- result->definition = def;
+ result->definition = *def;
+
+ /**
+ * On évite ici les méthodes (virtuelles) non définies.
+ */
+ if (def->access_flags & ACC_ANNOTATION) goto gdcn_done;
index = 0;
+ result->dmethods_count = data.direct_methods_size;
+ result->direct_methods = (GDexMethod **)calloc(result->dmethods_count, sizeof(GDexMethod *));
+
for (i = 0; i < data.direct_methods_size; i++)
{
method = g_dex_method_new(format, &data.direct_methods[i], &index);
+ if (method == NULL) goto gdcn_bad_method;
- if (method != NULL)
- {
- result->dmethods_count++;
- result->direct_methods = (GDexMethod **)realloc(result->direct_methods,
- result->dmethods_count * sizeof(GDexMethod *));
-
- result->direct_methods[result->dmethods_count - 1] = method;
-
- }
+ result->direct_methods[i] = method;
}
index = 0;
+ result->vmethods_count = data.virtual_methods_size;
+ result->virtual_methods = (GDexMethod **)calloc(result->vmethods_count, sizeof(GDexMethod *));
+
for (i = 0; i < data.virtual_methods_size; i++)
{
method = g_dex_method_new(format, &data.virtual_methods[i], &index);
+ if (method == NULL) goto gdcn_bad_method;
- if (method != NULL)
- {
- result->vmethods_count++;
- result->virtual_methods = (GDexMethod **)realloc(result->virtual_methods,
- result->vmethods_count * sizeof(GDexMethod *));
-
- result->virtual_methods[result->vmethods_count - 1] = method;
-
- }
+ result->virtual_methods[i] = method;
}
-
+ gdcn_done:
return result;
-}
+ gdcn_bad_method:
+ g_object_unref(G_OBJECT(result));
-/******************************************************************************
-* *
-* Paramètres : class = informations chargées à consulter. *
-* format = format binaire à compléter. *
-* *
-* Description : Inscrit les méthodes d'une classe en tant que routines. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_dex_class_register_method(const GDexClass *class, GBinFormat *format)
-{
- size_t i; /* Boucle de parcours */
- GBinRoutine *routine; /* Routine à inscrire */
-
- for (i = 0; i < class->dmethods_count; i++)
- {
- routine = g_dex_method_get_routine(class->direct_methods[i]);
- g_binary_format_add_routine(format, routine);
-
- /*
- printf("routine @ 0x%08llx :: '%s'\n",
- g_binary_routine_get_address(routine),
- g_binary_routine_get_name(routine));
- */
-
- }
-
- for (i = 0; i < class->vmethods_count; i++)
- {
- routine = g_dex_method_get_routine(class->virtual_methods[i]);
- g_binary_format_add_routine(format, routine);
-
- /*
- printf("routine @ 0x%08llx :: '%s'\n",
- g_binary_routine_get_address(routine),
- g_binary_routine_get_name(routine));
- */
-
- }
+ return NULL;
}
@@ -310,47 +309,27 @@ GDexMethod *g_dex_class_get_method(const GDexClass *class, bool virtual, size_t
/******************************************************************************
* *
* Paramètres : class = informations chargées à consulter. *
-* parts = liste à venir compléter. *
-* count = quantité de zones listées. [OUT] *
+* raw = portion de binaire brut à raffiner. *
* *
-* Description : Fournit les références aux zones binaires à analyser. *
+* Description : Intègre la méthode en tant que portion de code. *
* *
-* Retour : Zones binaires à analyser. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-#if 0
-GBinPart **g_dex_class_get_parts(const GDexClass *class, GBinPart **parts, size_t *count)
+
+void g_dex_class_include_as_portion(const GDexClass *class, GBinPortion *raw)
{
size_t i; /* Boucle de parcours */
- GBinPart *part; /* Partie à intégrer à la liste*/
for (i = 0; i < class->dmethods_count; i++)
- {
- part = g_dex_method_as_part(class->direct_methods[i]);
-
- parts = (GBinPart **)realloc(parts, ++(*count) * sizeof(GBinPart *));
- parts[*count - 1] = part;
-
- }
+ g_dex_method_include_as_portion(class->direct_methods[i], raw);
for (i = 0; i < class->vmethods_count; i++)
- {
- part = g_dex_method_as_part(class->virtual_methods[i]);
-
- parts = (GBinPart **)realloc(parts, ++(*count) * sizeof(GBinPart *));
- parts[*count - 1] = part;
-
- }
-
- return parts;
+ g_dex_method_include_as_portion(class->virtual_methods[i], raw);
}
-#endif
-
-
-
/******************************************************************************
@@ -428,7 +407,7 @@ const char *g_dex_class_get_source_file(const GDexClass *class, const GDexFormat
void g_dex_class_decompile(const GDexClass *class, GLangOutput *lang, GCodeBuffer *buffer, const GDexFormat *format)
{
-
+#if 0
GDataType *type;
@@ -482,7 +461,7 @@ GBufferLine *line, GLangOutput *output)
-
+#endif
}
@@ -500,69 +479,3 @@ GBufferLine *line, GLangOutput *output)
-
-
-/******************************************************************************
-* *
-* Paramètres : format = représentation interne du format DEX à compléter. *
-* *
-* Description : Charge toutes les classes listées dans le contenu binaire. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool load_all_dex_classes(GDexFormat *format)
-{
- const dex_header *header; /* Raccourci d'usage */
- uint32_t i; /* Boucle de parcours */
- GDexClass *class; /* Représentation chargée */
-
- header = &format->header;
-
- for (i = 0; i < header->class_defs_size; i++)
- {
- class = g_dex_class_new(format, header->class_defs_off + i * sizeof(class_def_item));
-
- if (class != NULL)
- {
- format->classes_count++;
- format->classes = (GDexClass **)realloc(format->classes,
- format->classes_count * sizeof(GDexClass *));
-
- format->classes[format->classes_count - 1] = class;
-
- }
-
- }
-
- return true;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : format = représentation interne du format DEX à compléter. *
-* *
-* Description : Enregistre toutes les méthodes des classes listées. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void register_all_dex_class_methods(GDexFormat *format)
-{
- size_t i; /* Boucle de parcours */
- GBinFormat *bformat; /* Autre version du format */
-
- bformat = G_BIN_FORMAT(format);
-
- for (i = 0; i < format->classes_count; i++)
- g_dex_class_register_method(format->classes[i], bformat);
-
-}
diff --git a/src/format/dex/class.h b/src/format/dex/class.h
index 8125b91..77fa6ba 100644
--- a/src/format/dex/class.h
+++ b/src/format/dex/class.h
@@ -54,14 +54,17 @@ typedef struct _GDexClassClass GDexClassClass;
/* Détermine le type d'une classe issue du code source. */
GType g_dex_class_get_type(void);
+/* Crée une nouvelle représentation de classe issue de code. */
+GDexClass *g_dex_class_new(GDexFormat *, const class_def_item *);
+
/* Dénombre les méthodes chargées d'un type donné. */
size_t g_dex_class_count_methods(const GDexClass *, bool);
/* Fournit une méthode chargée correspondant à un type donné. */
GDexMethod *g_dex_class_get_method(const GDexClass *, bool, size_t);
-/* Fournit les références aux zones binaires à analyser. */
-//GBinPart **g_dex_class_get_parts(const GDexClass *, GBinPart **, size_t *);
+/* Intègre la méthode en tant que portion de code. */
+void g_dex_class_include_as_portion(const GDexClass *, GBinPortion *);
/* Retrouve si possible la méthode associée à une adresse. */
GDexMethod *g_dex_class_find_method_by_address(const GDexClass *, vmpa_t);
@@ -76,13 +79,6 @@ void g_dex_class_decompile(const GDexClass *, GLangOutput *, GCodeBuffer *, cons
-/* Charge toutes les classes listées dans le contenu binaire. */
-bool load_all_dex_classes(GDexFormat *);
-
-/* Enregistre toutes les méthodes des classes listées. */
-void register_all_dex_class_methods(GDexFormat *);
-
-
#endif /* _FORMAT_DEX_CLASS_H */
diff --git a/src/format/dex/dex-int.c b/src/format/dex/dex-int.c
index 5ce0675..79cdc57 100644
--- a/src/format/dex/dex-int.c
+++ b/src/format/dex/dex-int.c
@@ -51,48 +51,46 @@
* *
******************************************************************************/
-bool read_dex_header(const GDexFormat *format, off_t *pos, dex_header *header)
+bool read_dex_header(const GDexFormat *format, vmpa2t *pos, dex_header *header)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
size_t i; /* Boucle de parcours */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
for (i = 0; i < DEX_FILE_MAGIC_LEN && result; i++)
- result = read_u8(&header->magic[i], content, pos, length);
+ result = g_binary_content_read_u8(content, pos, &header->magic[i]);
- result &= read_u32(&header->checksum, content, pos, length, SRE_LITTLE);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->checksum);
for (i = 0; i < 20 && result; i++)
- result = read_u8(&header->signature[i], content, pos, length);
-
- 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);
+ result = g_binary_content_read_u8(content, pos, &header->signature[i]);
+
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->file_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->header_size);
+
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->endian_tag);
+
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->link_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->link_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->map_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->string_ids_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->string_ids_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->type_ids_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->type_ids_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->proto_ids_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->proto_ids_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->field_ids_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->field_ids_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->method_ids_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->method_ids_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->class_defs_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->class_defs_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->data_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &header->data_off);
return result;
@@ -119,18 +117,14 @@ bool read_dex_header(const GDexFormat *format, off_t *pos, dex_header *header)
* *
******************************************************************************/
-bool read_dex_string_id_item(const GDexFormat *format, off_t *pos, string_id_item *str_id)
+bool read_dex_string_id_item(const GDexFormat *format, vmpa2t *pos, string_id_item *str_id)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
- result = true;
-
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_u32(&str_id->string_data_off, content, pos, length, SRE_LITTLE);
+ result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &str_id->string_data_off);
return result;
@@ -151,20 +145,17 @@ bool read_dex_string_id_item(const GDexFormat *format, off_t *pos, string_id_ite
* *
******************************************************************************/
-bool read_dex_string_data_item(const GDexFormat *format, off_t *pos, string_data_item *str_data)
+bool read_dex_string_data_item(const GDexFormat *format, vmpa2t *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;
+ GBinContent *content; /* Contenu binaire à lire */
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_uleb128(&str_data->utf16_size, content, pos, length);
+ result = g_binary_content_read_uleb128(content, pos, &str_data->utf16_size);
- str_data->data = &content[*pos];
+ if (result)
+ str_data->data = g_binary_content_get_raw_access(content, pos, str_data->utf16_size);
return result;
@@ -185,18 +176,14 @@ bool read_dex_string_data_item(const GDexFormat *format, off_t *pos, string_data
* *
******************************************************************************/
-bool read_dex_type_id_item(const GDexFormat *format, off_t *pos, type_id_item *item)
+bool read_dex_type_id_item(const GDexFormat *format, vmpa2t *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;
+ GBinContent *content; /* Contenu binaire à lire */
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_u32(&item->descriptor_idx, content, pos, length, SRE_LITTLE);
+ result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &item->descriptor_idx);
return result;
@@ -217,20 +204,16 @@ bool read_dex_type_id_item(const GDexFormat *format, off_t *pos, type_id_item *i
* *
******************************************************************************/
-bool read_dex_proto_id_item(const GDexFormat *format, off_t *pos, proto_id_item *proto_id)
+bool read_dex_proto_id_item(const GDexFormat *format, vmpa2t *pos, proto_id_item *proto_id)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
-
- result = true;
+ GBinContent *content; /* Contenu binaire à lire */
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_u32(&proto_id->shorty_idx, content, pos, length, SRE_LITTLE);
- result &= read_u32(&proto_id->return_type_idx, content, pos, length, SRE_LITTLE);
- result &= read_u32(&proto_id->parameters_off, content, pos, length, SRE_LITTLE);
+ result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &proto_id->shorty_idx);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &proto_id->return_type_idx);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &proto_id->parameters_off);
return result;
@@ -251,20 +234,16 @@ bool read_dex_proto_id_item(const GDexFormat *format, off_t *pos, proto_id_item
* *
******************************************************************************/
-bool read_dex_field_id_item(const GDexFormat *format, off_t *pos, field_id_item *field_id)
+bool read_dex_field_id_item(const GDexFormat *format, vmpa2t *pos, field_id_item *field_id)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
- result = true;
-
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_u16(&field_id->class_idx, content, pos, length, SRE_LITTLE);
- result &= read_u16(&field_id->type_idx, content, pos, length, SRE_LITTLE);
- result &= read_u32(&field_id->name_idx, content, pos, length, SRE_LITTLE);
+ result = g_binary_content_read_u16(content, pos, SRE_LITTLE, &field_id->class_idx);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &field_id->type_idx);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &field_id->name_idx);
return result;
@@ -285,20 +264,16 @@ bool read_dex_field_id_item(const GDexFormat *format, off_t *pos, field_id_item
* *
******************************************************************************/
-bool read_dex_method_id_item(const GDexFormat *format, off_t *pos, method_id_item *meth_id)
+bool read_dex_method_id_item(const GDexFormat *format, vmpa2t *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;
+ GBinContent *content; /* Contenu binaire à lire */
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- 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);
+ result = g_binary_content_read_u16(content, pos, SRE_LITTLE, &meth_id->class_idx);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &meth_id->proto_idx);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &meth_id->name_idx);
return result;
@@ -319,25 +294,21 @@ bool read_dex_method_id_item(const GDexFormat *format, off_t *pos, method_id_ite
* *
******************************************************************************/
-bool read_dex_class_def_item(const GDexFormat *format, off_t *pos, class_def_item *class_def)
+bool read_dex_class_def_item(const GDexFormat *format, vmpa2t *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;
+ GBinContent *content; /* Contenu binaire à lire */
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- 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);
+ result = g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->class_idx);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->access_flags);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->superclass_idx);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->interfaces_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->source_file_idx);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->annotations_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->class_data_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &class_def->static_values_off);
return result;
@@ -364,19 +335,17 @@ bool read_dex_class_def_item(const GDexFormat *format, off_t *pos, class_def_ite
* *
******************************************************************************/
-bool read_dex_encoded_field(const GDexFormat *format, off_t *pos, encoded_field *field)
+bool read_dex_encoded_field(const GDexFormat *format, vmpa2t *pos, encoded_field *field)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_uleb128(&field->field_idx_diff, content, pos, length);
- result &= read_uleb128(&field->access_flags, content, pos, length);
+ result &= g_binary_content_read_uleb128(content, pos, &field->field_idx_diff);
+ result &= g_binary_content_read_uleb128(content, pos, &field->access_flags);
return result;
@@ -397,20 +366,18 @@ bool read_dex_encoded_field(const GDexFormat *format, off_t *pos, encoded_field
* *
******************************************************************************/
-bool read_dex_encoded_method(const GDexFormat *format, off_t *pos, encoded_method *method)
+bool read_dex_encoded_method(const GDexFormat *format, vmpa2t *pos, encoded_method *method)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- 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);
+ result &= g_binary_content_read_uleb128(content, pos, &method->method_idx_diff);
+ result &= g_binary_content_read_uleb128(content, pos, &method->access_flags);
+ result &= g_binary_content_read_uleb128(content, pos, &method->code_off);
return result;
@@ -431,18 +398,14 @@ bool read_dex_encoded_method(const GDexFormat *format, off_t *pos, encoded_metho
* *
******************************************************************************/
-bool read_dex_type_item(const GDexFormat *format, off_t *pos, type_item *item)
+bool read_dex_type_item(const GDexFormat *format, vmpa2t *pos, type_item *item)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
- result = true;
-
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_u16(&item->type_idx, content, pos, length, SRE_LITTLE);
+ result = g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->type_idx);
return result;
@@ -463,21 +426,19 @@ bool read_dex_type_item(const GDexFormat *format, off_t *pos, type_item *item)
* *
******************************************************************************/
-bool read_dex_type_list(const GDexFormat *format, off_t *pos, type_list *list)
+bool read_dex_type_list(const GDexFormat *format, vmpa2t *pos, type_list *list)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_u32(&list->size, content, pos, length, SRE_LITTLE);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &list->size);
- list->list = (type_item *)&content[*pos];
- result &= ((*pos + list->size * sizeof(type_item)) <= length);
+ list->list = (type_item *)g_binary_content_get_raw_access(content, pos, list->size * sizeof(type_item));
+ result &= (list->list != NULL);
return result;
@@ -498,27 +459,25 @@ bool read_dex_type_list(const GDexFormat *format, off_t *pos, type_list *list)
* *
******************************************************************************/
-bool read_dex_class_data_item(const GDexFormat *format, off_t *pos, class_data_item *item)
+bool read_dex_class_data_item(const GDexFormat *format, vmpa2t *pos, class_data_item *item)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
uleb128_t i; /* Boucle de parcours */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //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);
+ content = G_BIN_FORMAT(format)->content;
+
+ result &= g_binary_content_read_uleb128(content, pos, &item->static_fields_size);
+ result &= g_binary_content_read_uleb128(content, pos, &item->instance_fields_size);
+ result &= g_binary_content_read_uleb128(content, pos, &item->direct_methods_size);
+ result &= g_binary_content_read_uleb128(content, pos, &item->virtual_methods_size);
if (result && item->static_fields_size > 0)
{
@@ -617,19 +576,17 @@ void reset_dex_class_data_item(class_data_item *item)
* *
******************************************************************************/
-bool read_dex_encoded_type_addr_pair(const GDexFormat *format, off_t *pos, encoded_type_addr_pair *pair)
+bool read_dex_encoded_type_addr_pair(const GDexFormat *format, vmpa2t *pos, encoded_type_addr_pair *pair)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_uleb128(&pair->type_idx, content, pos, length);
- result &= read_uleb128(&pair->addr, content, pos, length);
+ result &= g_binary_content_read_uleb128(content, pos, &pair->type_idx);
+ result &= g_binary_content_read_uleb128(content, pos, &pair->addr);
return result;
@@ -650,22 +607,20 @@ bool read_dex_encoded_type_addr_pair(const GDexFormat *format, off_t *pos, encod
* *
******************************************************************************/
-bool read_dex_encoded_catch_handler(const GDexFormat *format, off_t *pos, encoded_catch_handler *handler)
+bool read_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t *pos, encoded_catch_handler *handler)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
leb128_t count; /* Nombre de gestionnaires */
leb128_t i; /* Boucle de parcours */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- handler->offset = *pos;
+ handler->offset = get_phy_addr(pos);
- result &= read_leb128(&handler->size, content, pos, length);
+ result &= g_binary_content_read_leb128(content, pos, &handler->size);
count = leb128_abs(handler->size);
@@ -680,7 +635,8 @@ bool read_dex_encoded_catch_handler(const GDexFormat *format, off_t *pos, encode
else handler->handlers = NULL;
if (handler->size < 0)
- result &= read_uleb128(&handler->catch_all_addr, content, pos, length);
+ result &= g_binary_content_read_uleb128(content, pos, &handler->catch_all_addr);
+
else
handler->catch_all_addr = ULEB128_MAX;
@@ -723,22 +679,20 @@ void reset_dex_encoded_catch_handler(encoded_catch_handler *handler)
* *
******************************************************************************/
-bool read_dex_encoded_catch_handler_list(const GDexFormat *format, off_t *pos, encoded_catch_handler_list *list)
+bool read_dex_encoded_catch_handler_list(const GDexFormat *format, vmpa2t *pos, encoded_catch_handler_list *list)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
off_t saved_off; /* Sauvegarde de position */
+ GBinContent *content; /* Contenu binaire à lire */
uleb128_t i; /* Boucle de parcours */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ saved_off = get_phy_addr(pos);
- saved_off = *pos;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_uleb128(&list->size, content, pos, length);
+ result &= g_binary_content_read_uleb128(content, pos, &list->size);
if (list->size > 0 && result)
{
@@ -800,20 +754,18 @@ void reset_dex_encoded_catch_handler_list(encoded_catch_handler_list *list)
* *
******************************************************************************/
-bool read_dex_try_item(const GDexFormat *format, off_t *pos, try_item *item)
+bool read_dex_try_item(const GDexFormat *format, vmpa2t *pos, try_item *item)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
- result &= read_u32(&item->start_addr, content, pos, length, SRE_LITTLE);
- result &= read_u16(&item->insn_count, content, pos, length, SRE_LITTLE);
- result &= read_u16(&item->handler_off, content, pos, length, SRE_LITTLE);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &item->start_addr);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->insn_count);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->handler_off);
return result;
@@ -834,33 +786,29 @@ bool read_dex_try_item(const GDexFormat *format, off_t *pos, try_item *item)
* *
******************************************************************************/
-bool read_dex_code_item(const GDexFormat *format, off_t *pos, code_item *item)
+bool read_dex_code_item(const GDexFormat *format, vmpa2t *pos, code_item *item)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
uint16_t padding; /* Eventuel alignement */
uint16_t i; /* Boucle de parcours */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //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);
+ content = G_BIN_FORMAT(format)->content;
- item->insns = (uint16_t *)pos;
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->registers_size);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->ins_size);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->outs_size);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &item->tries_size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &item->debug_info_off);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &item->insns_size);
- *pos += item->insns_size * sizeof(uint16_t);
+ item->insns = (uint16_t *)g_binary_content_get_raw_access(content, pos, item->insns_size * sizeof(uint16_t));
/* Padding ? */
if (item->tries_size > 0 && item->insns_size % 2 == 1)
- result &= read_u16(&padding, content, pos, length, SRE_LITTLE);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &padding);
if (item->tries_size > 0 && result)
{
@@ -928,30 +876,28 @@ void reset_dex_code_item(code_item *item)
* *
******************************************************************************/
-bool read_dex_packed_switch(const GDexFormat *format, off_t *pos, packed_switch *packed)
+bool read_dex_packed_switch(const GDexFormat *format, vmpa2t *pos, packed_switch *packed)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
uint16_t i; /* Boucle de parcours */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
-
packed->targets = NULL;
- result &= read_u16(&packed->ident, content, pos, length, SRE_LITTLE);
- result &= read_u16(&packed->size, content, pos, length, SRE_LITTLE);
- result &= read_u32(&packed->first_key, content, pos, length, SRE_LITTLE);
+ content = G_BIN_FORMAT(format)->content;
+
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &packed->ident);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &packed->size);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &packed->first_key);
if (result && packed->size > 0)
{
packed->targets = (uint32_t *)calloc(packed->size, sizeof(uint32_t));
for (i = 0; i < packed->size && result; i++)
- result &= read_u32(&packed->targets[i], content, pos, length, SRE_LITTLE);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &packed->targets[i]);
}
@@ -997,23 +943,21 @@ void reset_dex_packed_switch(packed_switch *packed)
* *
******************************************************************************/
-bool read_dex_sparse_switch(const GDexFormat *format, off_t *pos, sparse_switch *sparse)
+bool read_dex_sparse_switch(const GDexFormat *format, vmpa2t *pos, sparse_switch *sparse)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
uint16_t i; /* Boucle de parcours */
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
sparse->keys = NULL;
sparse->targets = NULL;
- result &= read_u16(&sparse->ident, content, pos, length, SRE_LITTLE);
- result &= read_u16(&sparse->size, content, pos, length, SRE_LITTLE);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &sparse->ident);
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &sparse->size);
if (result && sparse->size > 0)
{
@@ -1021,10 +965,10 @@ bool read_dex_sparse_switch(const GDexFormat *format, off_t *pos, sparse_switch
sparse->targets = (uint32_t *)calloc(sparse->size, sizeof(uint32_t));
for (i = 0; i < sparse->size && result; i++)
- result &= read_u32(&sparse->keys[i], content, pos, length, SRE_LITTLE);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &sparse->keys[i]);
for (i = 0; i < sparse->size && result; i++)
- result &= read_u32(&sparse->targets[i], content, pos, length, SRE_LITTLE);
+ result &= g_binary_content_read_u32(content, pos, SRE_LITTLE, &sparse->targets[i]);
}
@@ -1073,19 +1017,21 @@ void reset_dex_sparse_switch(sparse_switch *sparse)
* *
******************************************************************************/
-bool read_dex_switch(const GDexFormat *format, off_t *pos, dex_switch *dswitch)
+bool read_dex_switch(const GDexFormat *format, vmpa2t *pos, dex_switch *dswitch)
{
bool result; /* Bilan à retourner */
- const bin_t *content; /* Contenu binaire à lire */
- off_t length; /* Taille totale du contenu */
+ GBinContent *content; /* Contenu binaire à lire */
uint16_t ident; /* Pseudo-code d'identification*/
result = true;
- content = NULL; //G_BIN_FORMAT(format)->content;
- length = 0; //G_BIN_FORMAT(format)->length;
+ content = G_BIN_FORMAT(format)->content;
+
+ result &= g_binary_content_read_u16(content, pos, SRE_LITTLE, &ident);
- result &= read_u16(&ident, content, (off_t []) { *pos }, length, SRE_LITTLE);
+ /**
+ * La tête de lecture n'est pas mise à jour volontairement !
+ */
if (result)
{
diff --git a/src/format/dex/dex-int.h b/src/format/dex/dex-int.h
index 1803e05..28aadd5 100755
--- a/src/format/dex/dex-int.h
+++ b/src/format/dex/dex-int.h
@@ -41,12 +41,11 @@ struct _GDexFormat
dex_header header; /* En-tête du programme */
-
-
+ GDataType **types; /* Types partagés pour Dalvik */
+ GBinVariable **fields; /* Champs de données partagés */
+ GBinRoutine **prototypes; /* Routines vierges à décorer */
+ GDexMethod **methods; /* Méthodes retrouvées */
GDexClass **classes; /* Classes retrouvées */
- size_t classes_count; /* Nombre de ces classes */
-
-
};
@@ -72,7 +71,7 @@ GDexClass *g_dex_format_get_class(const GDexFormat *, size_t);
/* Procède à la lecture d'une en-tête de programme DEX. */
-bool read_dex_header(const GDexFormat *, off_t *, dex_header *);
+bool read_dex_header(const GDexFormat *, vmpa2t *, dex_header *);
@@ -80,25 +79,25 @@ bool read_dex_header(const GDexFormat *, off_t *, dex_header *);
/* Procède à la lecture d'un identifiant de chaîne DEX. */
-bool read_dex_string_id_item(const GDexFormat *, off_t *, string_id_item *);
+bool read_dex_string_id_item(const GDexFormat *, vmpa2t *, 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 *);
+bool read_dex_string_data_item(const GDexFormat *, vmpa2t *, 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 *);
+bool read_dex_type_id_item(const GDexFormat *, vmpa2t *, type_id_item *);
/* Procède à la lecture d'une description de prototype. */
-bool read_dex_proto_id_item(const GDexFormat *, off_t *, proto_id_item *);
+bool read_dex_proto_id_item(const GDexFormat *, vmpa2t *, proto_id_item *);
/* Procède à la lecture d'une description de champ. */
-bool read_dex_field_id_item(const GDexFormat *, off_t *, field_id_item *);
+bool read_dex_field_id_item(const GDexFormat *, vmpa2t *, field_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 *);
+bool read_dex_method_id_item(const GDexFormat *, vmpa2t *, 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 *);
+bool read_dex_class_def_item(const GDexFormat *, vmpa2t *, class_def_item *);
@@ -106,19 +105,19 @@ bool read_dex_class_def_item(const GDexFormat *, off_t *, class_def_item *);
/* Procède à la lecture d'un champ quelconque DEX. */
-bool read_dex_encoded_field(const GDexFormat *, off_t *, encoded_field *);
+bool read_dex_encoded_field(const GDexFormat *, vmpa2t *, encoded_field *);
/* Procède à la lecture d'une méthode quelconque DEX. */
-bool read_dex_encoded_method(const GDexFormat *, off_t *, encoded_method *);
+bool read_dex_encoded_method(const GDexFormat *, vmpa2t *, encoded_method *);
/* Procède à la lecture d'un type DEX. */
-bool read_dex_type_item(const GDexFormat *, off_t *, type_item *);
+bool read_dex_type_item(const GDexFormat *, vmpa2t *, type_item *);
/* Procède à la lecture d'une liste de types DEX. */
-bool read_dex_type_list(const GDexFormat *, off_t *, type_list *);
+bool read_dex_type_list(const GDexFormat *, vmpa2t *, type_list *);
/* Procède à la lecture d'un contenu de classe DEX. */
-bool read_dex_class_data_item(const GDexFormat *, off_t *, class_data_item *);
+bool read_dex_class_data_item(const GDexFormat *, vmpa2t *, class_data_item *);
/* Supprime tous les éléments chargés en mémoire à la lecture. */
void reset_dex_class_data_item(class_data_item *);
@@ -129,25 +128,25 @@ void reset_dex_class_data_item(class_data_item *);
/* Procède à la lecture d'une association exception <-> code. */
-bool read_dex_encoded_type_addr_pair(const GDexFormat *, off_t *, encoded_type_addr_pair *);
+bool read_dex_encoded_type_addr_pair(const GDexFormat *, vmpa2t *, encoded_type_addr_pair *);
/* Procède à la lecture d'une association exception <-> code. */
-bool read_dex_encoded_catch_handler(const GDexFormat *, off_t *, encoded_catch_handler *);
+bool read_dex_encoded_catch_handler(const GDexFormat *, vmpa2t *, encoded_catch_handler *);
/* Supprime tous les éléments chargés en mémoire à la lecture. */
void reset_dex_encoded_catch_handler(encoded_catch_handler *);
/* Procède à la lecture d'une association exception <-> code. */
-bool read_dex_encoded_catch_handler_list(const GDexFormat *, off_t *, encoded_catch_handler_list *);
+bool read_dex_encoded_catch_handler_list(const GDexFormat *, vmpa2t *, encoded_catch_handler_list *);
/* Supprime tous les éléments chargés en mémoire à la lecture. */
void reset_dex_encoded_catch_handler_list(encoded_catch_handler_list *);
/* Procède à la lecture d'une association exception <-> code. */
-bool read_dex_try_item(const GDexFormat *, off_t *, try_item *);
+bool read_dex_try_item(const GDexFormat *, vmpa2t *, try_item *);
/* Procède à la lecture d'une portion de code DEX. */
-bool read_dex_code_item(const GDexFormat *, off_t *, code_item *);
+bool read_dex_code_item(const GDexFormat *, vmpa2t *, code_item *);
/* Supprime tous les éléments chargés en mémoire à la lecture. */
void reset_dex_code_item(code_item *);
@@ -158,19 +157,19 @@ void reset_dex_code_item(code_item *);
/* Procède à la lecture d'un contenu d'aiguillage compact. */
-bool read_dex_packed_switch(const GDexFormat *, off_t *, packed_switch *);
+bool read_dex_packed_switch(const GDexFormat *, vmpa2t *, packed_switch *);
/* Supprime tous les éléments chargés en mémoire à la lecture. */
void reset_dex_packed_switch(packed_switch *);
/* Procède à la lecture d'un contenu d'aiguillage dispersé. */
-bool read_dex_sparse_switch(const GDexFormat *, off_t *, sparse_switch *);
+bool read_dex_sparse_switch(const GDexFormat *, vmpa2t *, sparse_switch *);
/* Supprime tous les éléments chargés en mémoire à la lecture. */
void reset_dex_sparse_switch(sparse_switch *);
/* Procède à la lecture d'un contenu d'aiguillage Dex interne. */
-bool read_dex_switch(const GDexFormat *, off_t *, dex_switch *);
+bool read_dex_switch(const GDexFormat *, vmpa2t *, dex_switch *);
/* Supprime tous les éléments chargés en mémoire à la lecture. */
void reset_dex_switch(dex_switch *);
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index 0015357..35ffe47 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -45,49 +45,81 @@ static void g_dex_format_class_init(GDexFormatClass *);
/* Initialise une instance de format d'exécutable DEX. */
static void g_dex_format_init(GDexFormat *);
-/* Détermine tous les fichiers source indiqués. */
-static void g_dex_format_find_all_sources(GDexFormat *);
+/* Supprime toutes les références externes. */
+static void g_dex_format_dispose(GDexFormat *);
-/* Procède à la décompilation complète du format. */
-static void g_dex_format_decompile(const GDexFormat *, GCodeBuffer *, const char *);
+/* Procède à la libération totale de la mémoire. */
+static void g_dex_format_finalize(GDexFormat *);
/* Indique le type d'architecture visée par le format. */
static const char *g_dex_format_get_target_machine(const GDexFormat *);
-/* Fournit les références aux zones binaires à analyser. */
-//static GBinPart **g_dex_format_get_parts(const GDexFormat *, size_t *);
+/* Etend la définition des portions au sein d'un binaire. */
+static void g_dex_format_refine_portions(const GDexFormat *, GBinPortion *);
+
+/* Fournit l'emplacement d'une section donnée. */
+static bool g_dex_format_get_section_range_by_name(const GDexFormat *, const char *, mrange_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 *);
+/* Détermine tous les fichiers source indiqués. */
+//static void g_dex_format_find_all_sources(GDexFormat *);
+
+/* Procède à la décompilation complète du format. */
+static void g_dex_format_decompile(const GDexFormat *, GCodeBuffer *, const char *);
/******************************************************************************
* *
* Paramètres : content = contenu binaire à parcourir. *
+* parent = éventuel format exécutable déjà chargé. *
+* unused = adresse non utilisée ici. *
+* key = identifiant de format trouvé ou NULL. [OUT] *
* *
* Description : Indique si le format peut être pris en charge ici. *
* *
-* Retour : true si la réponse est positive, false sinon. *
+* Retour : Conclusion de haut niveau sur la reconnaissance effectuée. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool dex_is_matching(GBinContent *content)
+FormatMatchStatus dex_is_matching(GBinContent *content, GExeFormat *parent, void *unused, char **key)
{
- bool result; /* Bilan à faire connaître */
+ FormatMatchStatus result; /* Bilan à renvoyer */
vmpa2t addr; /* Tête de lecture initiale */
+ bool status; /* Bilan des accès mémoire */
char magic[DEX_FILE_MAGIC_LEN]; /* Idenfiant standard */
+
+ /* REMME */
+ if (parent != NULL) return FMS_UNKNOWN;
+
+
init_vmpa(&addr, 0, VMPA_NO_VIRTUAL);
- result = g_binary_content_read_raw(content, &addr, DEX_FILE_MAGIC_LEN, (bin_t *)magic);
+ status = g_binary_content_read_raw(content, &addr, DEX_FILE_MAGIC_LEN, (bin_t *)magic);
- result &= (memcmp(magic, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0);
+ status &= (memcmp(magic, DEX_FILE_MAGIC, DEX_FILE_MAGIC_LEN) == 0);
+
+ if (status)
+ {
+ result = FMS_MATCHED;
+ *key = strdup(parent == NULL ? "dex" : "dexdbg");
+ }
+ else
+ result = FMS_UNKNOWN;
return result;
@@ -112,6 +144,23 @@ G_DEFINE_TYPE(GDexFormat, g_dex_format, G_TYPE_EXE_FORMAT);
static void g_dex_format_class_init(GDexFormatClass *klass)
{
+ GObjectClass *object; /* Autre version de la classe */
+ GExeFormatClass *exe; /* Version en exécutable */
+
+ object = G_OBJECT_CLASS(klass);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_format_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dex_format_finalize;
+
+ exe = G_EXE_FORMAT_CLASS(klass);
+
+ exe->get_machine = (get_target_machine_fc)g_dex_format_get_target_machine;
+ exe->refine_portions = (refine_portions_fc)g_dex_format_refine_portions;
+
+ exe->translate_phys = (translate_phys_fc)g_exe_format_without_virt_translate_offset_into_vmpa;
+ exe->translate_virt = (translate_virt_fc)g_exe_format_without_virt_translate_address_into_vmpa;
+
+ exe->get_range_by_name = (get_range_by_name_fc)g_dex_format_get_section_range_by_name;
}
@@ -130,19 +179,49 @@ static void g_dex_format_class_init(GDexFormatClass *klass)
static void g_dex_format_init(GDexFormat *format)
{
- GExeFormat *exe_format; /* Format parent à compléter #1*/
- GBinFormat *bin_format; /* Format parent à compléter #2*/
+ GBinFormat *bin_format; /* Format parent à compléter #1*/
bin_format = G_BIN_FORMAT(format);
bin_format->decompile = (format_decompile_fc)g_dex_format_decompile;
- exe_format = G_EXE_FORMAT(format);
+}
- exe_format->get_machine = (get_target_machine_fc)g_dex_format_get_target_machine;
- 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 : format = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_format_dispose(GDexFormat *format)
+{
+ G_OBJECT_CLASS(g_dex_format_parent_class)->dispose(G_OBJECT(format));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_format_finalize(GDexFormat *format)
+{
+ G_OBJECT_CLASS(g_dex_format_parent_class)->finalize(G_OBJECT(format));
}
@@ -150,9 +229,9 @@ static void g_dex_format_init(GDexFormat *format)
/******************************************************************************
* *
* Paramètres : content = contenu binaire à parcourir. *
-* length = taille du contenu en question. *
+* parent = éventuel format exécutable déjà chargé. *
* *
-* Description : Prend en charge un nouveau format DEX. *
+* Description : Prend en charge un nouveau format Dex. *
* *
* Retour : Adresse de la structure mise en place ou NULL en cas d'échec.*
* *
@@ -160,54 +239,127 @@ static void g_dex_format_init(GDexFormat *format)
* *
******************************************************************************/
-GBinFormat *g_dex_format_new(const bin_t *content, off_t length)
+GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent)
{
GDexFormat *result; /* Structure à retourner */
- off_t offset; /* Tête de lecture */
+ vmpa2t pos; /* Position de tête de lecture */
result = g_object_new(G_TYPE_DEX_FORMAT, NULL);
- //g_binary_format_set_content(G_BIN_FORMAT(result), content, length);
+ g_binary_format_set_content(G_BIN_FORMAT(result), content);
+ init_vmpa(&pos, 0, VMPA_NO_VIRTUAL);
- offset = 0;
+ if (!read_dex_header(result, &pos, &result->header))
+ goto gdfn_error;
- if (!read_dex_header(result, &offset, &result->header))
- {
- /* TODO */
- return NULL;
- }
+ if (!load_all_dex_types(result))
+ goto gdfn_error;
- /* TODO : vérifier l'en-tête ! */
+ if (!load_all_dex_fields(result))
+ goto gdfn_error;
+ if (!load_all_dex_prototypes(result))
+ goto gdfn_error;
+ if (!load_all_dex_methods(result))
+ goto gdfn_error;
if (!load_all_dex_classes(result))
- {
- g_object_unref(G_OBJECT(result));
- return NULL;
- }
+ goto gdfn_error;
- register_all_dex_class_methods(result);
+ return G_BIN_FORMAT(result);
- g_dex_format_find_all_sources(result);
+ gdfn_error:
+ g_object_unref(G_OBJECT(result));
+ exit(0);
- if (!find_all_dex_strings(result))
- {
- g_object_unref(G_OBJECT(result));
- return NULL;
- }
+ 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 const char *g_dex_format_get_target_machine(const GDexFormat *format)
+{
+ return "dalvik";
+
+}
+
+/******************************************************************************
+* *
+* Paramètres : format = informations chargées à consulter. *
+* raw = portion de binaire brut à raffiner. *
+* *
+* Description : Etend la définition des portions au sein d'un binaire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_format_refine_portions(const GDexFormat *format, GBinPortion *raw)
+{
+ size_t max; /* Nombre d'itérations prévues */
+ size_t i; /* Boucle de parcours */
+
+ max = g_dex_format_count_classes(format);
+
+ for (i = 0; i < max; i++)
+ g_dex_class_include_as_portion(format->classes[i], raw);
}
/******************************************************************************
* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* name = nom de la section recherchée. *
+* range = emplacement en mémoire à renseigner. [OUT] *
+* *
+* Description : Fournit l'emplacement d'une section donnée. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_dex_format_get_section_range_by_name(const GDexFormat *format, const char *name, mrange_t *range)
+{
+ bool result; /* Bilan à retourner */
+
+ result = false;
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+* *
* Paramètres : format = informations chargées à consulter. *
* addr = adresse de la routine à retrouver. *
* *
@@ -221,6 +373,11 @@ GBinFormat *g_dex_format_new(const bin_t *content, off_t length)
GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *format, vmpa_t addr)
{
+
+ return NULL;
+
+
+#if 0
GDexMethod *result; /* Trouvaille à retourner */
size_t i; /* Boucle de parcours */
@@ -230,6 +387,7 @@ GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *format, vmpa_t
result = g_dex_class_find_method_by_address(format->classes[i], addr);
return result;
+#endif
}
@@ -245,9 +403,12 @@ GDexMethod *g_dex_format_find_method_by_address(const GDexFormat *format, vmpa_t
* Remarques : - *
* *
******************************************************************************/
-
+#if 0
static void g_dex_format_find_all_sources(GDexFormat *format)
{
+
+#if 0
+
GBinFormat *bf; /* Instance parente */
size_t i; /* Boucle de parcours #1 */
const char *source; /* Fichier source trouvé */
@@ -275,8 +436,10 @@ static void g_dex_format_find_all_sources(GDexFormat *format)
}
-}
+#endif
+}
+#endif
/******************************************************************************
* *
@@ -294,6 +457,9 @@ static void g_dex_format_find_all_sources(GDexFormat *format)
static void g_dex_format_decompile(const GDexFormat *format, GCodeBuffer *buffer, const char *filename)
{
+
+#if 0
+
GLangOutput *lang; /* Langage de sortie */
size_t i; /* Boucle de parcours */
const char *source; /* Fichier source trouvé */
@@ -328,106 +494,11 @@ char *_g_data_type_to_string(const GDataType *type, bool simple)
}
-}
-
-
-/******************************************************************************
-* *
-* 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 const char *g_dex_format_get_target_machine(const GDexFormat *format)
-{
- return "dalvik";
-
-}
-
-
-/******************************************************************************
-* *
-* 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 : - *
-* *
-******************************************************************************/
-#if 0
-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;
-
-}
#endif
-/******************************************************************************
-* *
-* 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;
-
-}
-
/******************************************************************************
* *
@@ -443,7 +514,11 @@ static bool g_dex_format_translate_offset_into_address(const GDexFormat *format,
size_t g_dex_format_count_classes(const GDexFormat *format)
{
+ return 0;
+
+#if 0
return format->classes_count;
+#endif
}
@@ -466,3 +541,8 @@ GDexClass *g_dex_format_get_class(const GDexFormat *format, size_t index)
return format->classes[index];
}
+
+
+
+
+
diff --git a/src/format/dex/dex.h b/src/format/dex/dex.h
index 7f427a3..1ff3809 100755
--- a/src/format/dex/dex.h
+++ b/src/format/dex/dex.h
@@ -30,7 +30,7 @@
#include <sys/types.h>
-#include "../format.h"
+#include "../../core/formats.h"
@@ -49,13 +49,13 @@ typedef struct _GDexFormatClass GDexFormatClass;
/* Indique si le format peut être pris en charge ici. */
-bool dex_is_matching(GBinContent *);
+FormatMatchStatus dex_is_matching(GBinContent *, GExeFormat *, void *, char **);
/* 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);
+GBinFormat *g_dex_format_new(GBinContent *, GExeFormat *);
/* Redéfinition : classe issue du code source (instance) */
typedef struct _GDexClass GDexClass;
diff --git a/src/format/dex/dex_def.h b/src/format/dex/dex_def.h
index 09496b6..ea2cd60 100755
--- a/src/format/dex/dex_def.h
+++ b/src/format/dex/dex_def.h
@@ -250,7 +250,7 @@ typedef struct _encoded_catch_handler
* structure efface la représentation physique, on conserve en mémoire
* le décalage rencontré à la lecture dans un champ artificiel.
*/
- off_t offset; /* Position dans le binaire */
+ phys_t offset; /* Position dans le binaire */
} encoded_catch_handler;
diff --git a/src/format/dex/method.c b/src/format/dex/method.c
index c721cea..c68e9e1 100644
--- a/src/format/dex/method.c
+++ b/src/format/dex/method.c
@@ -24,13 +24,15 @@
#include "method.h"
+#include <i18n.h>
+
+
#include "dex-int.h"
#include "pool.h"
-
/* Methode issue du code source (instance) */
struct _GDexMethod
{
@@ -58,12 +60,11 @@ 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 *);
+/* Supprime toutes les références externes. */
+static void g_dex_method_dispose(GDexMethod *);
-
-
-
-
-
+/* Procède à la libération totale de la mémoire. */
+static void g_dex_method_finalize(GDexMethod *);
@@ -86,6 +87,12 @@ G_DEFINE_TYPE(GDexMethod, g_dex_method, G_TYPE_OBJECT);
static void g_dex_method_class_init(GDexMethodClass *class)
{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_method_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_dex_method_finalize;
}
@@ -110,6 +117,47 @@ static void g_dex_method_init(GDexMethod *method)
/******************************************************************************
* *
+* Paramètres : format = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_method_dispose(GDexMethod *method)
+{
+ if (method->routine != NULL)
+ g_object_unref(G_OBJECT(method->routine));
+
+ G_OBJECT_CLASS(g_dex_method_parent_class)->dispose(G_OBJECT(method));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : method = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_dex_method_finalize(GDexMethod *method)
+{
+ G_OBJECT_CLASS(g_dex_method_parent_class)->finalize(G_OBJECT(method));
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = représentation interne du format DEX à consulter. *
* seed = graine des informations à extraire. *
* last = dernier indice utilisé (à mettre à jour). [OUT] *
@@ -122,63 +170,63 @@ static void g_dex_method_init(GDexMethod *method)
* *
******************************************************************************/
-GDexMethod *g_dex_method_new(const GDexFormat *format, const encoded_method *seed, uleb128_t *last)
+GDexMethod *g_dex_method_new(GDexFormat *format, const encoded_method *seed, uleb128_t *last)
{
GDexMethod *result; /* Composant à retourner */
- off_t offset; /* Tête de lecture */
+ vmpa2t addr; /* Tête de lecture générique */
code_item item; /* Corps de la méthode */
+ GBinRoutine *routine; /* Routine représentée */
+ mrange_t range; /* Emplacement du code associé */
+ init_vmpa(&addr, seed->code_off, VMPA_NO_VIRTUAL);
- GBinRoutine *routine;
-
- vmpa2t addr;
- mrange_t range;
-
-
- offset = seed->code_off;
-
- if (!read_dex_code_item(format, &offset, &item))
+ if (!read_dex_code_item(format, &addr, &item))
return NULL;
*last += seed->method_idx_diff;
- routine = get_routine_from_dex_pool(format, *last);
+ routine = get_prototype_from_dex_pool(format, *last);
if (routine == NULL) return NULL;
-
result = g_object_new(G_TYPE_DEX_METHOD, NULL);
result->info = *seed;
result->body = item;
- //printf(" ==== (%p) %s ====\n", routine, g_binary_routine_to_string(routine));
-
- //printf(" try ? %d\n", item.tries_size);
+ result->offset = seed->code_off + 4 * sizeof(uint16_t) + 2 *sizeof(uint32_t);/* TODO : faire plus propre ! */
- //printf(" method idx :: %d\n", seed->method_idx_diff);
- //printf(" code size :: %d\n", item.insns_size);
+ init_vmpa(&addr, result->offset, VMPA_NO_VIRTUAL);
+ init_mrange(&range, &addr, item.insns_size * sizeof(uint16_t));
- /*
- printf(" code regs :: %d\n", item.registers_size);
- printf(" code ins :: %d\n", item.ins_size);
- printf(" code outs :: %d\n", item.outs_size);
- */
+ g_binary_routine_set_range(routine, &range);
- //printf(" method idx :: %lld\n", *last);
+ result->routine = routine;
+ return result;
- result->offset = seed->code_off + 4 * sizeof(uint16_t) + 2 *sizeof(uint32_t);/* TODO : faire plus propre ! */
+}
- //printf(" method off :: 0x%08x\n", result->offset);
+/******************************************************************************
+* *
+* Paramètres : format = représentation interne du format DEX à consulter.*
+* method_id = informations de base quant à la méthode. *
+* *
+* Description : Crée une nouvelle représentation de methode vide. *
+* *
+* Retour : Composant GLib créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- init_vmpa(&addr, result->offset, VMPA_NO_VIRTUAL);
- init_mrange(&range, &addr, item.insns_size * sizeof(uint16_t));
+GDexMethod *g_dex_method_new_empty(const GDexFormat *format, const method_id_item *method_id)
+{
+ GDexMethod *result; /* Composant à retourner */
- g_binary_routine_set_range(routine, &range);
- result->routine = routine;
+ result = g_object_new(G_TYPE_DEX_METHOD, NULL);
return result;
@@ -246,33 +294,43 @@ GBinRoutine *g_dex_method_get_routine(const GDexMethod *method)
/******************************************************************************
* *
* Paramètres : method = représentation interne du format DEX à consulter. *
+* raw = portion de binaire brut à raffiner. *
* *
-* Description : Fournit la zone binaire correspondant à la méthode. *
+* Description : Intègre la méthode en tant que portion de code. *
* *
-* Retour : Zone binaire à analyser. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-#if 0
-GBinPart *g_dex_method_as_part(const GDexMethod *method)
+
+void g_dex_method_include_as_portion(const GDexMethod *method, GBinPortion *raw)
{
- GBinPart *result; /* Instance à retourner */
- off_t size; /* Taille du code associé */
+ GBinPortion *new; /* Nouvelle portion définie */
+ char *desc; /* Description d'une portion */
+ vmpa2t addr; /* Emplacement dans le binaire */
- result = g_binary_part_new();
+ /* Si la taille est nulle, on ne fait rien */
+ if (method->info.access_flags & ACC_NATIVE)
+ return;
- g_binary_part_set_name(result, "name");
+ new = g_binary_portion_new(BPC_CODE);
- if (method->info.access_flags & ACC_NATIVE) size = 0;
- else size = method->body.insns_size * sizeof(uint16_t);
+ asprintf(&desc, _("Dalvik code"));
- g_binary_part_set_values(result, method->offset, size, method->offset);
+ g_binary_portion_set_desc(new, desc);
- return result;
+ free(desc);
+
+ init_vmpa(&addr, method->offset, VMPA_NO_VIRTUAL);
+ g_binary_portion_set_values(new, &addr, method->body.insns_size * sizeof(uint16_t));
+
+ g_binary_portion_set_rights(new, PAC_READ | PAC_EXEC);
+
+ g_binary_portion_include(raw, new);
}
-#endif
+
/******************************************************************************
* *
diff --git a/src/format/dex/method.h b/src/format/dex/method.h
index 79e3077..dee33cb 100644
--- a/src/format/dex/method.h
+++ b/src/format/dex/method.h
@@ -67,7 +67,10 @@ typedef enum _DexVariableIndex
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 *, uleb128_t *);
+GDexMethod *g_dex_method_new(GDexFormat *, const encoded_method *, uleb128_t *);
+
+/* Crée une nouvelle représentation de methode vide. */
+GDexMethod *g_dex_method_new_empty(const GDexFormat *, const method_id_item *);
/* Fournit les indications Dex concernant la méthode. */
const encoded_method *g_dex_method_get_dex_info(const GDexMethod *);
@@ -78,8 +81,8 @@ const code_item *g_dex_method_get_dex_body(const GDexMethod *);
/* Fournit la routine OpenIDA correspondant à la méthode. */
GBinRoutine *g_dex_method_get_routine(const GDexMethod *);
-/* Fournit la zone binaire correspondant à la méthode. */
-//GBinPart *g_dex_method_as_part(const GDexMethod *);
+/* Intègre la méthode en tant que portion de code. */
+void g_dex_method_include_as_portion(const GDexMethod *, GBinPortion *);
/* Indique la position de la méthode au sein du binaire. */
off_t g_dex_method_get_offset(const GDexMethod *);
diff --git a/src/format/dex/pool.c b/src/format/dex/pool.c
index a869873..904ab76 100644
--- a/src/format/dex/pool.c
+++ b/src/format/dex/pool.c
@@ -24,11 +24,13 @@
#include "pool.h"
+#include <malloc.h>
#include <string.h>
#include "dex-int.h"
#include "../mangling/demangler.h"
+#include "../mangling/dex/context.h"
@@ -83,6 +85,7 @@ bool find_all_dex_strings(GDexFormat *format)
const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)
{
off_t pos; /* Tête de lecture */
+ vmpa2t addr; /* Tête de lecture générique */
string_id_item str_id; /* Identifiant de chaîne */
string_data_item str_data; /* Description de chaîne */
@@ -90,13 +93,15 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)
return NULL;
pos = format->header.string_ids_off + index * sizeof(string_id_item);
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- if (!read_dex_string_id_item(format, &pos, &str_id))
+ if (!read_dex_string_id_item(format, &addr, &str_id))
return NULL;
pos = str_id.string_data_off;
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- if (!read_dex_string_data_item(format, &pos, &str_data))
+ if (!read_dex_string_data_item(format, &addr, &str_data))
return NULL;
return (const char *)str_data.data;
@@ -109,6 +114,49 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* *
+* Description : Charge en mémoire l'ensemble des types du format DEX. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_all_dex_types(GDexFormat *format)
+{
+ bool result; /* Bilan à retourner */
+ uint32_t i; /* Boucle de parcours */
+ GDataType *type; /* Type récupéré */
+
+ result = true;
+
+ format->types = (GDataType **)calloc(format->header.type_ids_size, sizeof(GDataType *));
+
+ for (i = 0; i < format->header.type_ids_size && result; i++)
+ {
+ type = get_type_from_dex_pool(format, i);
+
+ if (type != NULL)
+ g_object_unref(G_OBJECT(type));
+ else
+ result = false;
+
+ }
+
+ return result;
+
+}
+
+
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
@@ -122,89 +170,94 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)
* *
******************************************************************************/
-GDataType *get_type_from_dex_pool(const GDexFormat *format, uint16_t index)
+GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)
{
- off_t pos; /* Tête de lecture */
+ GDataType *result; /* Instance à retourner */
+ phys_t pos; /* Tête de lecture */
+ vmpa2t addr; /* Tête de lecture générique */
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("Tp Index :: %hd / %d\n", index, format->header.type_ids_size);
-
+ result = NULL;
if (index >= format->header.type_ids_size)
- return NULL;
-
- pos = format->header.type_ids_off + index * sizeof(type_id_item);
+ goto gtfdp_error;
- if (!read_dex_type_id_item(format, &pos, &type_id))
- return NULL;
+ if (format->types[index] == NULL)
+ {
+ pos = format->header.type_ids_off + index * sizeof(type_id_item);
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
+ if (!read_dex_type_id_item(format, &addr, &type_id))
+ goto gtfdp_error;
+ pos = format->header.string_ids_off + type_id.descriptor_idx * sizeof(string_id_item);
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
+ if (!read_dex_string_id_item(format, &addr, &str_id))
+ goto gtfdp_error;
- pos = format->header.string_ids_off + type_id.descriptor_idx * sizeof(string_id_item);
+ pos = str_id.string_data_off;
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- if (!read_dex_string_id_item(format, &pos, &str_id))
- return NULL;
+ if (!read_dex_string_data_item(format, &addr, &str_data))
+ goto gtfdp_error;
- pos = str_id.string_data_off;
+ format->types[index] = demangle_type(G_TYPE_DEX_DEMANGLER, (char *)str_data.data);
- if (!read_dex_string_data_item(format, &pos, &str_data))
- return NULL;
+ }
+ result = format->types[index];
- //printf(">> String :: '%s'\n", str_data.data);
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+ gtfdp_error:
- return demangle_type(DGT_JAVA, (char *)str_data.data);
+ return result;
}
-
-
-
/******************************************************************************
* *
-* Paramètres : format = représentation interne du format DEX à consulter. *
-* index = index de la classe recherchée. *
+* Paramètres : format = description de l'exécutable à compléter. *
* *
-* Description : Extrait une représentation de classe d'une table DEX. *
+* Description : Charge en mémoire l'ensemble des champs du format DEX. *
* *
-* Retour : Composant GLib créé. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-GDataType *get_class_from_dex_pool(const GDexFormat *format, uint32_t index)
+bool load_all_dex_fields(GDexFormat *format)
{
- GDataType *result; /* Instance à retourner */
- off_t pos; /* Tête de lecture */
- class_def_item class_def; /* Définition de la classe */
-
- if (index >= format->header.class_defs_size)
- return NULL;
+ bool result; /* Bilan à retourner */
+ uint32_t i; /* Boucle de parcours */
+ GBinVariable *field; /* Champ récupéré */
- pos = format->header.class_defs_off + index * sizeof(class_def_item);
-
- if (!read_dex_class_def_item(format, &pos, &class_def))
- return NULL;
+ result = true;
+ format->fields = (GBinVariable **)calloc(format->header.field_ids_size, sizeof(GBinVariable *));
+ for (i = 0; i < format->header.field_ids_size && result; i++)
+ {
+ field = get_field_from_dex_pool(format, i);
- result = NULL;
+ if (field != NULL)
+ g_object_unref(G_OBJECT(field));
+ else
+ result = false;
+ }
return result;
}
-
-
/******************************************************************************
* *
* Paramètres : format = représentation interne du format DEX à consulter. *
@@ -218,48 +271,67 @@ GDataType *get_class_from_dex_pool(const GDexFormat *format, uint32_t index)
* *
******************************************************************************/
-GBinVariable *get_field_from_dex_pool(const GDexFormat *format, uint32_t index)
+GBinVariable *get_field_from_dex_pool(GDexFormat *format, uint32_t index)
{
GBinVariable *result; /* Instance à retourner */
- off_t pos; /* Tête de lecture */
+ phys_t pos; /* Tête de lecture */
+ vmpa2t addr; /* Tête de lecture générique */
field_id_item field_id; /* Description du champ */
GDataType *type; /* Type du champ */
const char *name; /* Désignation humaine */
+ GBinVariable *field; /* Instance nouvelle à définir */
GDataType *owner; /* Propriétaire du champ */
+ result = NULL;
+
if (index >= format->header.field_ids_size)
- return NULL;
+ goto gffdp_error;
- pos = format->header.field_ids_off + index * sizeof(field_id_item);
+ if (format->fields[index] == NULL)
+ {
+ pos = format->header.field_ids_off + index * sizeof(field_id_item);
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- if (!read_dex_field_id_item(format, &pos, &field_id))
- return NULL;
+ if (!read_dex_field_id_item(format, &addr, &field_id))
+ goto gffdp_error;
- type = get_type_from_dex_pool(format, field_id.type_idx);
+ type = get_type_from_dex_pool(format, field_id.type_idx);
+ if (type == NULL) goto gffdp_error;
- name = get_string_from_dex_pool(format, field_id.name_idx);
- if (name == NULL) goto bad_name;
+ name = get_string_from_dex_pool(format, field_id.name_idx);
+ if (name == NULL) goto gffdp_bad_name;
- result = g_binary_variable_new(type);
- g_binary_variable_set_name(result, name);
+ field = g_binary_variable_new(type);
+ g_binary_variable_set_name(field, name);
- if (field_id.class_idx != NO_INDEX)
- {
- owner = get_type_from_dex_pool(format, field_id.class_idx);
- if (owner == NULL) goto bad_owner;
+ if (field_id.class_idx != NO_INDEX)
+ {
+ owner = get_type_from_dex_pool(format, field_id.class_idx);
+ if (owner == NULL) goto gffdp_bad_owner;
+
+ g_binary_variable_set_owner(field, owner);
+
+ }
- g_binary_variable_set_owner(result, owner);
+ format->fields[index] = field;
}
+ result = format->fields[index];
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ gffdp_error:
+
return result;
- bad_owner:
+ gffdp_bad_owner:
g_object_ref(G_OBJECT(type));
g_object_unref(G_OBJECT(result));
- bad_name:
+ gffdp_bad_name:
g_object_unref(G_OBJECT(type));
@@ -270,6 +342,44 @@ GBinVariable *get_field_from_dex_pool(const GDexFormat *format, uint32_t index)
/******************************************************************************
* *
+* Paramètres : format = représentation interne du format DEX à compléter. *
+* *
+* Description : Charge tous les prototypes listés dans le contenu binaire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_all_dex_prototypes(GDexFormat *format)
+{
+ bool result; /* Bilan à retourner */
+ uint32_t i; /* Boucle de parcours */
+ GBinRoutine *proto; /* Prototype récupéré */
+
+ result = true;
+
+ format->prototypes = (GBinRoutine **)calloc(format->header.proto_ids_size, sizeof(GBinRoutine *));
+
+ for (i = 0; i < format->header.proto_ids_size && result; i++)
+ {
+ proto = get_prototype_from_dex_pool(format, i);
+
+ if (proto != NULL)
+ g_object_unref(G_OBJECT(proto));
+ else
+ result = false;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = représentation interne du format DEX à consulter. *
* index = index de la routine recherchée. *
* *
@@ -281,114 +391,244 @@ GBinVariable *get_field_from_dex_pool(const GDexFormat *format, uint32_t index)
* *
******************************************************************************/
-GBinRoutine *get_routine_from_dex_pool(const GDexFormat *format, uint32_t index)
+GBinRoutine *get_prototype_from_dex_pool(GDexFormat *format, uint32_t index)
{
GBinRoutine *result; /* Instance à retourner */
- off_t pos; /* Tête de lecture */
- method_id_item meth_id; /* Description de la méthode */
+ phys_t pos; /* Tête de lecture */
+ vmpa2t addr; /* Tête de lecture générique */
+ proto_id_item proto_id; /* Prototype de routine */
+ GDataType *type; /* Type de retour */
+ const char *name; /* Description compressée */
+ type_list args; /* Liste des arguments */
+ uint32_t i; /* Boucle de parcours */
+ GBinVariable *arg; /* Argument reconstitué */
+ if (index >= format->header.method_ids_size)
+ goto grfdp_error;
- GDataType *type;
+ if (format->prototypes[index] == NULL)
+ {
+ pos = format->header.proto_ids_off + index * sizeof(proto_id_item);
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- string_id_item str_id; /* Identifiant de chaîne */
- string_data_item str_data; /* Description de chaîne */
+ if (!read_dex_proto_id_item(format, &addr, &proto_id))
+ goto grfdp_error;
+ /* Type de retour */
- proto_id_item proto_id; /* Information de prototypage */
- type_list args; /* Liste des arguments */
+ type = get_type_from_dex_pool(format, proto_id.return_type_idx);
+
+ /* Nom de la méthode */
+
+ name = get_string_from_dex_pool(format, proto_id.shorty_idx);
+
+ /* Liste des arguments */
+
+ pos = proto_id.parameters_off;
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
+
+ if (read_dex_type_list(format, &addr, &args))
+ for (i = 0; i < args.size; i++)
+ {
+ type = get_type_from_dex_pool(format, args.list[i].type_idx);
+ if (type == NULL) continue;
+
+ arg = g_binary_variable_new(type);
+ //g_binary_routine_add_arg(result, arg);
+
+ }
+
+ /* Mise en place finale */
+
+ format->prototypes[index] = demangle_routine(G_TYPE_DEX_DEMANGLER, name);
+
+#if 0
+ if (format->prototypes[index] != NULL)
+ g_binary_routine_set_return_type(format->prototypes[index], type);
+#endif
+
+ }
+
+ result = format->prototypes[index];
+
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+
+ grfdp_error:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = représentation interne du format DEX à compléter. *
+* *
+* Description : Charge toutes les méthodes listées dans le contenu binaire. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool load_all_dex_methods(GDexFormat *format)
+{
+ bool result; /* Bilan à retourner */
uint32_t i; /* Boucle de parcours */
- GBinVariable *arg; /* Argument reconstitué */
+ GDexMethod *method; /* Méthode récupérée */
- if (index >= format->header.method_ids_size)
- return NULL;
+ result = true;
- pos = format->header.method_ids_off + index * sizeof(method_id_item);
+ format->methods = (GDexMethod **)calloc(format->header.method_ids_size, sizeof(GDexMethod *));
- if (!read_dex_method_id_item(format, &pos, &meth_id))
- return NULL;
+ for (i = 0; i < format->header.method_ids_size && result; i++)
+ {
+ method = get_method_from_dex_pool(format, i);
+ if (method != NULL)
+ g_object_unref(G_OBJECT(method));
+ else
+ result = false;
+ }
+ return result;
+}
- type = get_type_from_dex_pool(format, meth_id.class_idx);
+/******************************************************************************
+* *
+* Paramètres : format = représentation interne du format DEX à consulter. *
+* index = index de la classe recherchée. *
+* *
+* Description : Extrait une représentation de méthode d'une table DEX. *
+* *
+* Retour : Composant GLib créé. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- /*
- if (type == NULL)
- printf("class is nil\n");
+GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index)
+{
+ GDexMethod *result; /* Instance à retourner */
+ phys_t pos; /* Tête de lecture */
+ vmpa2t addr; /* Tête de lecture générique */
+ method_id_item method_id; /* Définition de la méthode */
- else
- printf("class = '%s'\n", g_data_type_to_string(type));
- */
+ result = NULL;
- /* Nom de la méthode */
+ if (index >= format->header.method_ids_size)
+ goto gmfdp_error;
- pos = format->header.string_ids_off + meth_id.name_idx * sizeof(string_id_item);
+ if (format->methods[index] == NULL)
+ {
+ pos = format->header.method_ids_off + index * sizeof(method_id_item);
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- if (!read_dex_string_id_item(format, &pos, &str_id))
- return NULL;
+ if (!read_dex_method_id_item(format, &addr, &method_id))
+ goto gmfdp_error;
- pos = str_id.string_data_off;
+ format->methods[index] = g_dex_method_new_empty(format, &method_id);
- if (!read_dex_string_data_item(format, &pos, &str_data))
- return NULL;
+ }
+ result = format->methods[index];
- //printf("String :: '%s'\n", str_data.data);
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
+ gmfdp_error:
- result = g_binary_routine_new();
+ return result;
- g_binary_routine_set_name(result, (char *)str_data.data);
+}
- if (type != NULL)
- g_binary_routine_set_namespace(result, type);
+/******************************************************************************
+* *
+* 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)
+{
+ bool result; /* Bilan à retourner */
+ uint32_t i; /* Boucle de parcours */
+ GDexClass *class; /* Classe récupérée */
- /*
- printf(" ####\n");
- printf(" #### ROUTINE '%s'\n", g_binary_routine_to_string(result));
- printf(" ####\n");
- printf(" ####\n");
- */
+ result = true;
- //printf("==>>> routine :: '%s'\n", g_binary_routine_to_string(result));
+ format->classes = (GDexClass **)calloc(format->header.class_defs_size, sizeof(GDexClass *));
+ for (i = 0; i < format->header.class_defs_size && result; i++)
+ {
+ class = get_class_from_dex_pool(format, i);
+ if (class != NULL)
+ g_object_unref(G_OBJECT(class));
+ else
+ result = false;
+ }
+ return result;
+}
- /* Retour de la routine */
+/******************************************************************************
+* *
+* 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 : - *
+* *
+******************************************************************************/
- pos = format->header.proto_ids_off + meth_id.proto_idx * sizeof(proto_id_item);
+GDexClass *get_class_from_dex_pool(GDexFormat *format, uint32_t index)
+{
+ GDexClass *result; /* Instance à retourner */
+ phys_t pos; /* Tête de lecture */
+ vmpa2t addr; /* Tête de lecture générique */
+ class_def_item class_def; /* Définition de la classe */
- if (!read_dex_proto_id_item(format, &pos, &proto_id))
- goto no_more_info;
+ result = NULL;
- type = get_type_from_dex_pool(format, proto_id.return_type_idx);
+ if (index >= format->header.class_defs_size)
+ goto gcfdp_error;
- g_binary_routine_set_return_type(result, type);
+ if (format->classes[index] == NULL)
+ {
+ pos = format->header.class_defs_off + index * sizeof(class_def_item);
+ init_vmpa(&addr, pos, VMPA_NO_VIRTUAL);
- /* Arguments de la routine */
+ if (!read_dex_class_def_item(format, &addr, &class_def))
+ goto gcfdp_error;
- pos = proto_id.parameters_off;
+ format->classes[index] = g_dex_class_new(format, &class_def);
- if (read_dex_type_list(format, &pos, &args))
- for (i = 0; i < args.size; i++)
- {
- type = get_type_from_dex_pool(format, args.list[i].type_idx);
- if (type == NULL) continue;
+ }
- arg = g_binary_variable_new(type);
- g_binary_routine_add_arg(result, arg);
+ result = format->classes[index];
- }
+ if (result != NULL)
+ g_object_ref(G_OBJECT(result));
- no_more_info:
+ gcfdp_error:
return result;
diff --git a/src/format/dex/pool.h b/src/format/dex/pool.h
index e947465..df02ed8 100644
--- a/src/format/dex/pool.h
+++ b/src/format/dex/pool.h
@@ -25,7 +25,9 @@
#define _FORMAT_DEX_POOL_H
+#include "class.h"
#include "dex.h"
+#include "method.h"
#include "../../analysis/routine.h"
@@ -36,22 +38,39 @@ bool find_all_dex_strings(GDexFormat *);
/* Extrait une chaîne de caractères d'une table DEX. */
const char *get_string_from_dex_pool(const GDexFormat *, uint32_t);
-/* Extrait une représentation de type d'une table DEX. */
-GDataType *get_type_from_dex_pool(const GDexFormat *, uint16_t);
-/* Extrait une représentation de classe d'une table DEX. */
-GDataType *get_class_from_dex_pool(const GDexFormat *, uint32_t);
+/* Charge en mémoire l'ensemble des types du format DEX. */
+bool load_all_dex_types(GDexFormat *);
+/* Extrait une représentation de type d'une table DEX. */
+GDataType *get_type_from_dex_pool(GDexFormat *, uint32_t);
+/* Charge en mémoire l'ensemble des champs du format DEX. */
+bool load_all_dex_fields(GDexFormat *);
/* Extrait une représentation de champ d'une table DEX. */
-GBinVariable *get_field_from_dex_pool(const GDexFormat *, uint32_t);
+GBinVariable *get_field_from_dex_pool(GDexFormat *, uint32_t);
+
+/* Charge tous les prototypes listés dans le contenu binaire. */
+bool load_all_dex_prototypes(GDexFormat *);
/* Extrait une représentation de routine d'une table DEX. */
-GBinRoutine *get_routine_from_dex_pool(const GDexFormat *, uint32_t);
+GBinRoutine *get_prototype_from_dex_pool(GDexFormat *, uint32_t);
+
+/* Charge toutes les méthodes listées dans le contenu binaire. */
+bool load_all_dex_methods(GDexFormat *);
+
+/* Extrait une représentation de méthode d'une table DEX. */
+GDexMethod *get_method_from_dex_pool(GDexFormat *, uint32_t);
+
+/* Charge toutes les classes listées dans le contenu binaire. */
+bool load_all_dex_classes(GDexFormat *);
+
+/* Extrait une représentation de classe d'une table DEX. */
+GDexClass *get_class_from_dex_pool(GDexFormat *, uint32_t);