summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-04-30 19:21:29 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-04-30 19:21:29 (GMT)
commit33880cfe5e5de8b81e8a825878b3bbe8ef736f3f (patch)
tree9dcbe3e9e9903e447eeac916be689cd2d39614de
parentb16071a35adaf95d5e67b0dd984e9ba9d7ba28f9 (diff)
Parsed Dex format fields using the new generic parser.
-rw-r--r--ChangeLog21
-rw-r--r--plugins/fmtp/def.h18
-rw-r--r--plugins/fmtp/parser.c39
-rw-r--r--plugins/fmtp/parser.h2
-rw-r--r--plugins/readdex/class.c451
-rw-r--r--plugins/readdex/code.c560
-rw-r--r--plugins/readdex/header.c311
-rw-r--r--plugins/readdex/ids.c505
-rw-r--r--plugins/readelf/header.c10
-rw-r--r--plugins/readelf/program.c12
-rw-r--r--plugins/readelf/section.c12
-rwxr-xr-xsrc/format/dex/dex.c27
12 files changed, 1103 insertions, 865 deletions
diff --git a/ChangeLog b/ChangeLog
index a005921..fe4f659 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+17-04-30 Cyrille Bagard <nocbos@gmail.com>
+
+ * plugins/fmtp/def.h:
+ * plugins/fmtp/parser.c:
+ * plugins/fmtp/parser.h:
+ Extend the generic parser features.
+
+ * plugins/readdex/class.c:
+ * plugins/readdex/code.c:
+ * plugins/readdex/header.c:
+ * plugins/readdex/ids.c:
+ Parse Dex format fields using the new generic parser.
+
+ * plugins/readelf/header.c:
+ * plugins/readelf/program.c:
+ * plugins/readelf/section.c:
+ Update code.
+
+ * src/format/dex/dex.c:
+ Provide the endianness of (most) Dex files.
+
17-04-29 Cyrille Bagard <nocbos@gmail.com>
* plugins/fmtp/parser.c:
diff --git a/plugins/fmtp/def.h b/plugins/fmtp/def.h
index d69d20a..f1ec7c7 100644
--- a/plugins/fmtp/def.h
+++ b/plugins/fmtp/def.h
@@ -34,16 +34,24 @@
/**
- * Assurément utile pour les déclarations...
+ * Assurément utile pour les déclarations ou les appels...
*/
#define __(s) s
+#define PARSING_DEFS(a) a, ARRAY_SIZE(a)
+
/**
* Méthodes de définitions des déclarations.
*/
+/* Définition générale */
+typedef struct _fmt_field_def fmt_field_def;
+
+/* Eventuel appel préalable */
+typedef bool (* get_fdef_value_cb) (const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, void *);
+
/* Possibilités pour un champ à commenter */
typedef struct _field_desc_switch
{
@@ -89,10 +97,14 @@ typedef enum _FieldCommentType
} FieldCommentType;
/* Définition générale */
-typedef struct _fmt_field_def
+struct _fmt_field_def
{
const char *name; /* Nom du champ */
+ get_fdef_value_cb get_value; /* Obtention de la valeur */
+
+ bool is_uleb128; /* Element de type uleb128 */
+ bool is_leb128; /* Element de type sleb128 */
MemoryDataSize size; /* Taille d'un élément */
size_t repeat; /* Quantité d'éléments présents*/
@@ -122,7 +134,7 @@ typedef struct _fmt_field_def
} comment;
-} fmt_field_def;
+};
/* Règles d'affichage */
diff --git a/plugins/fmtp/parser.c b/plugins/fmtp/parser.c
index b484a0e..8fc693f 100644
--- a/plugins/fmtp/parser.c
+++ b/plugins/fmtp/parser.c
@@ -33,8 +33,7 @@
/* Effectue l'interprétation d'une définition de champ. */
-static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *);
-
+static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *, void *);
@@ -43,6 +42,7 @@ static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *
* Paramètres : def = définition de champ à considérer. *
* format = description de l'exécutable à compléter. *
* pos = tête de lecture pour les données. *
+* data = infos complémentaires éventuellement fournies. *
* *
* Description : Effectue l'interprétation d'une définition de champ. *
* *
@@ -52,10 +52,11 @@ static bool parse_field_definition(const fmt_field_def *, GBinFormat *, vmpa2t *
* *
******************************************************************************/
-static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos)
+static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format, vmpa2t *pos, void *data)
{
GBinContent *content; /* Contenu binaire à lire */
SourceEndian endian; /* Boutisme utilisé */
+ vmpa2t mod; /* Position modifiable */
bool result; /* Bilan à retourner */
GArchInstruction *instr; /* Instruction décodée */
GImmOperand *imm; /* Opérande à transformer */
@@ -74,9 +75,28 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
content = g_binary_format_get_content(format);
endian = g_binary_format_get_endianness(format);
- assert(def->repeat > 0);
+ if (def->get_value != NULL)
+ {
+ copy_vmpa(&mod, pos);
+
+ result = def->get_value(def, content, &mod, endian, data);
+
+ if (!result)
+ goto pfd_exit;
+
+ }
+
+ if (def->is_uleb128)
+ instr = g_raw_instruction_new_uleb128(content, pos);
+
+ else if (def->is_leb128)
+ instr = g_raw_instruction_new_sleb128(content, pos);
- instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian);
+ else
+ {
+ assert(def->repeat > 0);
+ instr = g_raw_instruction_new_array(content, def->size, def->repeat, pos, endian);
+ }
result = (instr != NULL);
@@ -88,7 +108,9 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
if (def->has_display_rules)
{
- assert(def->disp_count <= def->repeat);
+ assert((def->is_uleb128 && def->disp_count == 1)
+ || (def->is_leb128 && def->disp_count == 1)
+ || (!def->is_uleb128 && !def->is_leb128 && def->disp_count <= def->repeat));
for (i = 0; i < def->disp_count; i++)
{
@@ -198,6 +220,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
* count = taille de cette liste. *
* format = description de l'exécutable à compléter. *
* pos = tête de lecture pour les données. *
+* data = infos complémentaires éventuellement fournies. *
* *
* Description : Lance l'interprétation d'une série de définitions de champs. *
* *
@@ -207,7 +230,7 @@ static bool parse_field_definition(const fmt_field_def *def, GBinFormat *format,
* *
******************************************************************************/
-bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos)
+bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat *format, vmpa2t *pos, void *data)
{
bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
@@ -215,7 +238,7 @@ bool parse_field_definitions(const fmt_field_def *defs, size_t count, GBinFormat
result = true;
for (i = 0; i < count && result; i++)
- result = parse_field_definition(defs + i, format, pos);
+ result = parse_field_definition(defs + i, format, pos, data);
return result;
diff --git a/plugins/fmtp/parser.h b/plugins/fmtp/parser.h
index dcd9bf2..0d5dff3 100644
--- a/plugins/fmtp/parser.h
+++ b/plugins/fmtp/parser.h
@@ -36,7 +36,7 @@
/* Lance l'interprétation d'une série de définitions de champs. */
-bool parse_field_definitions(const fmt_field_def *, size_t, GBinFormat *, vmpa2t *);
+bool parse_field_definitions(const fmt_field_def *, size_t, GBinFormat *, vmpa2t *, void *);
diff --git a/plugins/readdex/class.c b/plugins/readdex/class.c
index c08fe4a..7b7b253 100644
--- a/plugins/readdex/class.c
+++ b/plugins/readdex/class.c
@@ -24,206 +24,232 @@
#include "class.h"
-#include <assert.h>
-#include <malloc.h>
-#include <stdio.h>
-
-
#include <i18n.h>
-#include <arch/raw.h>
-#include <format/symbol.h>
#include <format/dex/class.h>
#include <format/dex/dex_def.h>
+#include <plugins/fmtp/parser.h>
#include "code.h"
-/* Commente les définitions des classes pour la VM Dalvik. */
-static bool annotate_dex_class_data(const GDexFormat *, const GDexClass *, uint32_t );
+/* Définition des champs */
-/* Commente les définitions des champs encodés. */
-static bool annotate_dex_encoded_field(const GDexFormat *, vmpa2t *);
+static fmt_field_def _dex_class_defs[] = {
-/* Commente les définitions des méthodes encodées. */
-static bool annotate_dex_encoded_method(const GDexFormat *, const encoded_method *, vmpa2t *);
+ {
+ .name = "class_idx",
+ .size = MDS_32_BITS,
+ .repeat = 1,
+ DISPLAY_RULES(IOD_DEC),
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* status = barre de statut à tenir informée. *
-* *
-* Description : Commente les définitions des classes pour la VM Dalvik. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+ PLAIN_COMMENT(__("Index into the type_ids list for this class"))
-bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
-{
- bool result; /* Bilan à retourner */
- GBinContent *content; /* Contenu binaire à lire */
- const dex_header *header; /* En-tête principale */
- SourceEndian endian; /* Boutisme utilisé */
- vmpa2t pos; /* Tête de lecture des symboles*/
- activity_id_t msg; /* Message de progression */
- uint32_t i; /* Boucle de parcours */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
- GDexClass *class; /* Classe chargée à manipuler */
- const class_def_item *def; /* Définition brute à lire */
+ },
- result = true;
+ {
+ .name = "access_flags",
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
+ .size = MDS_32_BITS,
+ .repeat = 1,
- header = g_dex_format_get_header(format);
- endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
+ PLAIN_COMMENT(__("Access flags for the class"))
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->class_defs_off, &pos))
- return false;
+ },
- msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex classes..."),
- header->class_defs_size);
+ {
+ .name = "superclass_idx",
+
+ .size = MDS_32_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the superclass or NO_INDEX if this class has no superclass"))
+
+ },
+
+ {
+ .name = "interfaces_off",
+
+ .size = MDS_32_BITS,
+ .repeat = 1,
+
+ PLAIN_COMMENT(__("Offset to the list of interfaces"))
+
+ },
- for (i = 0; i < header->class_defs_size && result; i++)
{
- /* class_idx */
+ .name = "source_file_idx",
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ DISPLAY_RULES(IOD_DEC),
- asprintf(&text, _("Index into the type_ids list for this class"));
+ PLAIN_COMMENT(__("Index for the name of the file containing the original source or NO_INDEX"))
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ },
- free(text);
+ {
+ .name = "annotations_off",
- if (i == 0)
- g_binary_symbol_define_as_block_start(symbol, true);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- /* access_flags */
+ PLAIN_COMMENT(__("Offset to the annotations structure for this class"))
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ },
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ {
+ .name = "class_data_off",
- asprintf(&text, _("Access flags for the class"));
+ .size = MDS_32_BITS,
+ .repeat = 1,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ PLAIN_COMMENT(__("Offset to the associated class data for this item"))
- free(text);
+ },
- /* superclass_idx */
+ {
+ .name = "static_values_off",
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ PLAIN_COMMENT(__("Offset to the list of initial values for static fields"))
- asprintf(&text, _("Index for the superclass or NO_INDEX if this class has no superclass"));
+ }
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+};
- free(text);
+static fmt_field_def _dex_class_data[] = {
- /* interfaces_off */
+ {
+ .name = "static_fields_size",
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ .is_uleb128 = true,
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ DISPLAY_RULES(IOD_DEC),
- asprintf(&text, _("Offset to the list of interfaces"));
+ PLAIN_COMMENT(__("Number of static fields defined in this item"))
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ },
- free(text);
+ {
+ .name = "instance_fields_size",
- /* source_file_idx */
+ .is_uleb128 = true,
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ DISPLAY_RULES(IOD_DEC),
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ PLAIN_COMMENT(__("Number of instance fields defined in this item"))
- asprintf(&text, _("Index for the name of the file containing the original source or NO_INDEX"));
+ },
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ {
+ .name = "direct_methods_size",
- free(text);
+ .is_uleb128 = true,
- /* annotations_off */
+ DISPLAY_RULES(IOD_DEC),
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ PLAIN_COMMENT(__("Number of direct methods defined in this item"))
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ },
- asprintf(&text, _("Offset to the annotations structure for this class"));
+ {
+ .name = "virtual_methods_size",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ .is_uleb128 = true,
- free(text);
+ DISPLAY_RULES(IOD_DEC),
- /* class_data_off */
+ PLAIN_COMMENT(__("Number of virtual methods defined in this item"))
+
+ }
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+};
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+static fmt_field_def _dex_encoded_field[] = {
- asprintf(&text, _("Offset to the associated class data for this item"));
+ {
+ .name = "field_idx_diff",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ .is_uleb128 = true,
- free(text);
+ DISPLAY_RULES(IOD_DEC),
- /* static_values_off */
+ PLAIN_COMMENT(__("Index into the field_ids list for the identity of this field"))
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ },
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ {
+ .name = "access_flags",
- asprintf(&text, _("Offset to the list of initial values for static fields"));
+ .is_uleb128 = true,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ PLAIN_COMMENT(__("Access flags for the field"))
- free(text);
+ }
- /* Annotations supplémentaires */
+};
- class = g_dex_format_get_class(format, i);
+static fmt_field_def _dex_encoded_method[] = {
- def = g_dex_class_get_definition(class);
+ {
+ .name = "method_idx_diff",
- if (def->class_data_off > 0)
- result = annotate_dex_class_data(format, class, def->class_data_off);
+ .is_uleb128 = true,
- /* TODO : g_object_unref(G_OBJECT(class));*/
+ DISPLAY_RULES(IOD_DEC),
- gtk_status_stack_update_activity_value(status, msg, 1);
+ PLAIN_COMMENT(__("Index into the method_ids list for the identity of this method"))
+
+ },
+
+ {
+ .name = "access_flags",
+
+ .is_uleb128 = true,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Access flags for the method"))
+
+ },
+
+ {
+ .name = "code_off",
+
+ .is_uleb128 = true,
+
+ PLAIN_COMMENT(__("Offset to the code structure for this method"))
}
- gtk_status_stack_remove_activity(status, msg);
+};
- g_object_unref(G_OBJECT(content));
- return result;
-}
+/* Commente les définitions des classes pour la VM Dalvik. */
+static bool annotate_dex_class_data(const GDexFormat *, const GDexClass *, uint32_t );
+
+/* Commente les définitions des champs encodés. */
+static bool annotate_dex_encoded_field(const GDexFormat *, vmpa2t *);
+
+/* Commente les définitions des méthodes encodées. */
+static bool annotate_dex_encoded_method(const GDexFormat *, const encoded_method *, vmpa2t *);
+
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
-* class = classe Dex dont les données sont à commenter. *
-* offset = tête de lecture physique des symboles. *
+* status = barre de statut à tenir informée. *
* *
* Description : Commente les définitions des classes pour la VM Dalvik. *
* *
@@ -233,78 +259,94 @@ bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
* *
******************************************************************************/
-static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *class, uint32_t offset)
+bool annotate_dex_class_defs(const GDexFormat *format, GtkStatusStack *status)
{
bool result; /* Bilan à retourner */
- GBinContent *content; /* Contenu binaire à lire */
+ const dex_header *header; /* En-tête principale */
vmpa2t pos; /* Tête de lecture des symboles*/
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
- const class_data_item *data; /* Données chargées à lire */
- uleb128_t i; /* Boucle de parcours */
-
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
-
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos))
- return false;
+ activity_id_t msg; /* Message de progression */
+ GBinFormat *bformat; /* Autre version du format */
+ uint32_t i; /* Boucle de parcours */
+ GDexClass *class; /* Classe chargée à manipuler */
+ const class_def_item *def; /* Définition brute à lire */
- /* static_fields_size */
+ header = g_dex_format_get_header(format);
- instr = g_raw_instruction_new_uleb128(content, &pos);
+ result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->class_defs_off, &pos);
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ if (!result)
+ goto adcd_exit;
- asprintf(&text, _("Number of static fields defined in this item"));
+ msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex classes..."),
+ header->class_defs_size);
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ bformat = G_BIN_FORMAT(format);
- free(text);
+ for (i = 0; i < header->class_defs_size && result; i++)
+ {
+ result = parse_field_definitions(PARSING_DEFS(_dex_class_defs), bformat, &pos, NULL);
+ if (!result) break;
- g_binary_symbol_define_as_block_start(symbol, true);
+ /* Annotations supplémentaires */
- /* instance_fields_size */
+ class = g_dex_format_get_class(format, i);
- instr = g_raw_instruction_new_uleb128(content, &pos);
+ def = g_dex_class_get_definition(class);
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ if (def->class_data_off > 0)
+ result = annotate_dex_class_data(format, class, def->class_data_off);
- asprintf(&text, _("Number of instance fields defined in this item"));
+ /* TODO : g_object_unref(G_OBJECT(class));*/
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ gtk_status_stack_update_activity_value(status, msg, 1);
- free(text);
+ }
- /* direct_methods_size */
+ gtk_status_stack_remove_activity(status, msg);
- instr = g_raw_instruction_new_uleb128(content, &pos);
+ adcd_exit:
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ return result;
- asprintf(&text, _("Number of direct methods defined in this item"));
+}
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
- free(text);
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* class = classe Dex dont les données sont à commenter. *
+* offset = tête de lecture physique des symboles. *
+* *
+* Description : Commente les définitions des classes pour la VM Dalvik. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- /* virtual_methods_size */
+static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *class, uint32_t offset)
+{
+ bool result; /* Bilan à retourner */
+ vmpa2t pos; /* Tête de lecture des symboles*/
+ GBinFormat *bformat; /* Autre version du format */
+ const class_data_item *data; /* Données chargées à lire */
+ uleb128_t i; /* Boucle de parcours */
- instr = g_raw_instruction_new_uleb128(content, &pos);
+ result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos);
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ if (!result)
+ goto adcd_exit;
- asprintf(&text, _("Number of virtual methods defined in this item"));
+ bformat = G_BIN_FORMAT(format);
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ result = parse_field_definitions(PARSING_DEFS(_dex_class_data), bformat, &pos, NULL);
- free(text);
+ if (!result)
+ goto adcd_exit;
/* Chargements complémentaires */
- result = true;
-
data = g_dex_class_get_data(class);
if (data != NULL)
@@ -323,9 +365,7 @@ static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *c
}
- /* Nettoyage final */
-
- g_object_unref(G_OBJECT(content));
+ adcd_exit:
return result;
@@ -347,46 +387,14 @@ static bool annotate_dex_class_data(const GDexFormat *format, const GDexClass *c
static bool annotate_dex_encoded_field(const GDexFormat *format, vmpa2t *pos)
{
- GBinContent *content; /* Contenu binaire à lire */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
-
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
-
- /* field_idx_diff */
-
- instr = g_raw_instruction_new_uleb128(content, pos);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index into the field_ids list for the identity of this field"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
-
- g_binary_symbol_define_as_block_start(symbol, true);
-
- /* access_flags */
-
- instr = g_raw_instruction_new_uleb128(content, pos);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
-
- asprintf(&text, _("Access flags for the field"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
+ bool result; /* Bilan à retourner */
+ GBinFormat *bformat; /* Autre version du format */
- /* Nettoyage final */
+ bformat = G_BIN_FORMAT(format);
- g_object_unref(G_OBJECT(content));
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_field), bformat, pos, NULL);
- return true;
+ return result;
}
@@ -408,63 +416,16 @@ static bool annotate_dex_encoded_field(const GDexFormat *format, vmpa2t *pos)
static bool annotate_dex_encoded_method(const GDexFormat *format, const encoded_method *method, vmpa2t *pos)
{
bool result; /* Bilan à retourner */
- GBinContent *content; /* Contenu binaire à lire */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
-
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
-
- /* method_idx_diff */
-
- instr = g_raw_instruction_new_uleb128(content, pos);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index into the method_ids list for the identity of this method"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
-
- g_binary_symbol_define_as_block_start(symbol, true);
-
- /* access_flags */
+ GBinFormat *bformat; /* Autre version du format */
- instr = g_raw_instruction_new_uleb128(content, pos);
+ bformat = G_BIN_FORMAT(format);
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
-
- asprintf(&text, _("Access flags for the method"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
-
- /* code_off */
-
- instr = g_raw_instruction_new_uleb128(content, pos);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
-
- asprintf(&text, _("Offset to the code structure for this method"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_method), bformat, pos, NULL);
/* Chargements complémentaires, si non abstraite ni native */
- if (method->code_off > 0)
+ if (result && method->code_off > 0)
result = annotate_dex_code_item(format, method->code_off);
- else
- result = true;
-
- /* Nettoyage final */
-
- g_object_unref(G_OBJECT(content));
return result;
diff --git a/plugins/readdex/code.c b/plugins/readdex/code.c
index 2f43e86..23e82ac 100644
--- a/plugins/readdex/code.c
+++ b/plugins/readdex/code.c
@@ -24,254 +24,271 @@
#include "code.h"
-#include <assert.h>
-#include <malloc.h>
-#include <stdio.h>
+#include <format/dex/dex_def.h>
+#include <plugins/fmtp/parser.h>
-#include <i18n.h>
-#include <arch/raw.h>
-#include <format/symbol.h>
-#include <format/dex/dex_def.h>
+/* Définition des champs */
+typedef struct _code_item_data
+{
+ uint16_t tries_size; /* Nombre de gestionnaires */
+ uint32_t insns_size; /* Nombre d'instructions */
-/* Commente les définitions d'une protection contre exceptions. */
-static bool annotate_dex_try_item(const GDexFormat *, vmpa2t *);
+} code_item_data;
-/*Commente les définitions des listes de gestion d'exceptions. */
-static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *, vmpa2t *);
+/* Récupère le nombre de couvertures pour exceptions. */
+static bool get_code_tries_size_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, code_item_data *);
-/* Commente les définitions d'une prise en compte d'exceptions. */
-static bool annotate_dex_encoded_catch_handler(const GDexFormat *, vmpa2t *);
+/* Récupère le nombre de blocs d'instructions. */
+static bool get_code_insns_size_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, code_item_data *);
-/* Commente les définitions des gestions d'exceptions par type. */
-static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *, vmpa2t *);
+/* Récupère le nombre d'éléments d'une liste de couvertures. */
+static bool get_encoded_catch_handler_list_size_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, uleb128_t *);
+/* Récupère le nombre d'exécptions gérées dans une couverture. */
+static bool get_encoded_catch_handler_size_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, leb128_t *);
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* *
-* Description : Commente les définitions d'un corps de méthode. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+static fmt_field_def _dex_code_item[] = {
-bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset)
-{
- bool result; /* Bilan à retourner */
- GBinContent *content; /* Contenu binaire à lire */
- SourceEndian endian; /* Boutisme utilisé */
- vmpa2t pos; /* Tête de lecture des symboles*/
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
- uint16_t tries_size; /* Nombre de gestionnaires */
- uint32_t insns_size; /* Nombre d'instructions */
- uint16_t i; /* Boucle de parcours */
+ {
+ .name = "registers_size",
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
+ .size = MDS_16_BITS,
+ .repeat = 1,
- endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
+ DISPLAY_RULES(IOD_DEC),
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos))
- return false;
+ PLAIN_COMMENT(__("Number of registers used by this code"))
- /* registers_size */
+ },
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+ {
+ .name = "ins_size",
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ .size = MDS_16_BITS,
+ .repeat = 1,
- asprintf(&text, _("Number of registers used by this code"));
+ DISPLAY_RULES(IOD_DEC),
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ PLAIN_COMMENT(__("Number of words of incoming arguments to the method that this code is for"))
- free(text);
+ },
- g_binary_symbol_define_as_block_start(symbol, true);
+ {
+ .name = "outs_size",
- /* ins_size */
+ .size = MDS_16_BITS,
+ .repeat = 1,
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+ DISPLAY_RULES(IOD_DEC),
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ PLAIN_COMMENT(__("Number of words of outgoing argument space required by this code for method invocation"))
- asprintf(&text, _("Number of words of incoming arguments to the method that this code is for"));
+ },
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ {
+ .name = "tries_size",
- free(text);
+ .get_value = (get_fdef_value_cb)get_code_tries_size_value,
- /* outs_size */
+ .size = MDS_16_BITS,
+ .repeat = 1,
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+ DISPLAY_RULES(IOD_DEC),
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ PLAIN_COMMENT(__("Number of try_items for this instance"))
- asprintf(&text, _("Number of words of outgoing argument space required by this code for method invocation"));
+ },
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ {
+ .name = "debug_info_off",
- free(text);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- /* tries_size */
+ PLAIN_COMMENT(__("Offset to the debug info sequence for this code"))
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+ },
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ {
+ .name = "insns_size",
- asprintf(&text, _("Number of try_items for this instance"));
+ .get_value = (get_fdef_value_cb)get_code_insns_size_value,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- free(text);
+ DISPLAY_RULES(IOD_DEC),
- g_imm_operand_get_value(G_IMM_OPERAND(operand), MDS_16_BITS, &tries_size);
+ PLAIN_COMMENT(__("Size of the instructions list, in 16-bit code units"))
- /* debug_info_off */
+ }
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+};
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+static fmt_field_def _dex_code_item_padding[] = {
- asprintf(&text, _("Offset to the debug info sequence for this code"));
+ {
+ .name = "padding",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ .size = MDS_16_BITS,
+ .repeat = 1,
- free(text);
+ PLAIN_COMMENT(__("Padding"))
- /* insns_size */
+ }
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+};
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+static fmt_field_def _dex_try_item[] = {
- asprintf(&text, _("Size of the instructions list, in 16-bit code units"));
+ {
+ .name = "start_addr",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- free(text);
+ PLAIN_COMMENT(__("Start address of the block of code covered by this entry"))
- /* insns */
+ },
- g_imm_operand_get_value(G_IMM_OPERAND(operand), MDS_32_BITS, &insns_size);
+ {
+ .name = "insn_count",
- advance_vmpa(&pos, insns_size * 2);
+ .size = MDS_16_BITS,
+ .repeat = 1,
- /* padding */
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Number of 16-bit code units covered by this entry"))
+
+ },
- if (insns_size % 2 != 0)
{
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
+ .name = "handler_off",
+
+ .size = MDS_16_BITS,
+ .repeat = 1,
+
+ PLAIN_COMMENT(__("Offset to the encoded_catch_handler for this entry"))
+
+ }
+
+};
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+static fmt_field_def _dex_encoded_catch_handler_list[] = {
+
+ {
+ .name = "size",
- asprintf(&text, _("Pading"));
+ .get_value = (get_fdef_value_cb)get_encoded_catch_handler_list_size_value,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ .is_uleb128 = true,
- free(text);
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Size of the list, in entries"))
}
- /* tries */
+};
- result = true;
+static fmt_field_def _dex_encoded_catch_handler[] = {
- for (i = 0; i < tries_size && result; i++)
- result = annotate_dex_try_item(format, &pos);
+ {
+ .name = "size",
- if (tries_size > 0 && result)
- result = annotate_dex_encoded_catch_handler_list(format, &pos);
+ .get_value = (get_fdef_value_cb)get_encoded_catch_handler_size_value,
- /* Nettoyage final */
+ .is_leb128 = true,
- g_object_unref(G_OBJECT(content));
+ DISPLAY_RULES(IOD_DEC),
- return result;
+ PLAIN_COMMENT(__("Number of static fields defined in this item"))
-}
+ }
+};
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* pos = tête de lecture pour les symboles. *
-* *
-* Description : Commente les définitions d'une protection contre exceptions. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+static fmt_field_def _dex_encoded_catch_handler_all[] = {
-static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
-{
- bool result; /* Bilan à retourner */
- GBinContent *content; /* Contenu binaire à lire */
- SourceEndian endian; /* Boutisme utilisé */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
+ {
+ .name = "catch_all_addr",
- result = true;
+ .is_uleb128 = true,
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
+ PLAIN_COMMENT(__("Bytecode address of the catch-all handler"))
- endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
+ }
- /* start_addr */
+};
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, pos, endian);
+static fmt_field_def _dex_encoded_type_addr_pair[] = {
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ {
+ .name = "type_idx",
- asprintf(&text, _("Start address of the block of code covered by this entry"));
+ .is_uleb128 = true,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ DISPLAY_RULES(IOD_DEC),
- free(text);
+ PLAIN_COMMENT(__("Index for the type of the exception to catch"))
- g_binary_symbol_define_as_block_start(symbol, true);
+ },
- /* insn_count */
+ {
+ .name = "addr",
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, endian);
+ .is_uleb128 = true,
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ DISPLAY_RULES(IOD_DEC),
- asprintf(&text, _("Number of 16-bit code units covered by this entry"));
+ PLAIN_COMMENT(__("Bytecode address of the associated exception handler"))
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ }
- free(text);
+};
- /* handler_off */
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, pos, endian);
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+/* Commente les définitions d'une protection contre exceptions. */
+static bool annotate_dex_try_item(const GDexFormat *, vmpa2t *);
- asprintf(&text, _("Offset to the encoded_catch_handler for this entry"));
+/*Commente les définitions des listes de gestion d'exceptions. */
+static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *, vmpa2t *);
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+/* Commente les définitions d'une prise en compte d'exceptions. */
+static bool annotate_dex_encoded_catch_handler(const GDexFormat *, vmpa2t *);
- free(text);
+/* Commente les définitions des gestions d'exceptions par type. */
+static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *, vmpa2t *);
- /* Nettoyage final */
- g_object_unref(G_OBJECT(content));
+
+/******************************************************************************
+* *
+* Paramètres : def = définition à l'origine de l'appel. *
+* content = contenu binaire à venir lire. *
+* pos = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* data = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Récupère le nombre de couvertures pour exceptions. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool get_code_tries_size_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, code_item_data *data)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_binary_content_read_u16(content, pos, endian, &data->tries_size);
return result;
@@ -280,10 +297,13 @@ static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
/******************************************************************************
* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* pos = tête de lecture physique des symboles. *
+* Paramètres : def = définition à l'origine de l'appel. *
+* content = contenu binaire à venir lire. *
+* pos = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* data = lieu d'enregistrement de la lecture. [OUT] *
* *
-* Description : Commente les définitions des listes de gestion d'exceptions. *
+* Description : Récupère le nombre de blocs d'instructions. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -291,46 +311,65 @@ static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
* *
******************************************************************************/
-static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vmpa2t *pos)
+static bool get_code_insns_size_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, code_item_data *data)
{
bool result; /* Bilan à retourner */
- GBinContent *content; /* Contenu binaire à lire */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
- uleb128_t size; /* Nombre d'entrées */
- uleb128_t i; /* Boucle de parcours */
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
+ result = g_binary_content_read_u32(content, pos, endian, &data->insns_size);
- /* static_fields_size */
-
- instr = g_raw_instruction_new_uleb128(content, pos);
+ return result;
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+}
- asprintf(&text, _("Size of the list, in entries"));
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+/******************************************************************************
+* *
+* Paramètres : def = définition à l'origine de l'appel. *
+* content = contenu binaire à venir lire. *
+* pos = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* size = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Récupère le nombre d'éléments d'une liste de couvertures. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- free(text);
+static bool get_encoded_catch_handler_list_size_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, uleb128_t *size)
+{
+ bool result; /* Bilan à retourner */
- g_binary_symbol_define_as_block_start(symbol, true);
+ result = g_binary_content_read_uleb128(content, pos, size);
- /* instance_fields_size */
+ return result;
- g_imm_operand_as_uleb128(G_IMM_OPERAND(operand), &size);
+}
- result = true;
- for (i = 0; i < size && result; i++)
- result = annotate_dex_encoded_catch_handler(format, pos);
+/******************************************************************************
+* *
+* Paramètres : def = définition à l'origine de l'appel. *
+* content = contenu binaire à venir lire. *
+* pos = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* size = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Récupère le nombre d'exécptions gérées dans une couverture. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- /* Nettoyage final */
+static bool get_encoded_catch_handler_size_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, leb128_t *size)
+{
+ bool result; /* Bilan à retourner */
- g_object_unref(G_OBJECT(content));
+ result = g_binary_content_read_leb128(content, pos, size);
return result;
@@ -340,9 +379,8 @@ static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vm
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
-* pos = tête de lecture physique des symboles. *
* *
-* Description : Commente les définitions d'une prise en compte d'exceptions. *
+* Description : Commente les définitions d'un corps de méthode. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -350,68 +388,95 @@ static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vm
* *
******************************************************************************/
-static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t *pos)
+bool annotate_dex_code_item(const GDexFormat *format, uleb128_t offset)
{
bool result; /* Bilan à retourner */
- GBinContent *content; /* Contenu binaire à lire */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
- leb128_t size; /* Nombre de gestionnaires */
- bool has_catch_all; /* Gestion par défaut ? */
- uleb128_t i; /* Boucle de parcours */
+ vmpa2t pos; /* Tête de lecture des symboles*/
+ code_item_data data; /* Valeurs brutes lues */
+ uint16_t i; /* Boucle de parcours */
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
+ result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), offset, &pos);
- /* size */
+ if (!result)
+ goto adci_exit;
- instr = g_raw_instruction_new_sleb128(content, pos);
+ result = parse_field_definitions(PARSING_DEFS(_dex_code_item), G_BIN_FORMAT(format), &pos, &data);
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ if (!result)
+ goto adci_exit;
- asprintf(&text, _("Number of static fields defined in this item"));
+ /* insns */
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ advance_vmpa(&pos, data.insns_size * 2);
- free(text);
+ /* padding */
- g_binary_symbol_define_as_block_start(symbol, true);
+ if (data.insns_size % 2 != 0)
+ result = parse_field_definitions(PARSING_DEFS(_dex_code_item_padding), G_BIN_FORMAT(format), &pos, NULL);
- g_imm_operand_as_leb128(G_IMM_OPERAND(operand), &size);
+ /* tries */
- has_catch_all = (size <= 0);
+ for (i = 0; i < data.tries_size && result; i++)
+ result = annotate_dex_try_item(format, &pos);
- if (size < 0)
- size *= -1;
+ if (data.tries_size > 0 && result)
+ result = annotate_dex_encoded_catch_handler_list(format, &pos);
- /* handlers */
+ adci_exit:
- result = true;
+ return result;
- for (i = 0; i < size && result; i++)
- result = annotate_dex_encoded_type_addr_pair(format, pos);
+}
- /* catch_all_addr */
- if (has_catch_all)
- {
- instr = g_raw_instruction_new_uleb128(content, pos);
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* pos = tête de lecture pour les symboles. *
+* *
+* Description : Commente les définitions d'une protection contre exceptions. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool annotate_dex_try_item(const GDexFormat *format, vmpa2t *pos)
+{
+ bool result; /* Bilan à retourner */
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ result = parse_field_definitions(PARSING_DEFS(_dex_try_item), G_BIN_FORMAT(format), pos, NULL);
- asprintf(&text, _("Bytecode address of the catch-all handler"));
+ return result;
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+}
- free(text);
- }
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* pos = tête de lecture physique des symboles. *
+* *
+* Description : Commente les définitions des listes de gestion d'exceptions. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- /* Nettoyage final */
+static bool annotate_dex_encoded_catch_handler_list(const GDexFormat *format, vmpa2t *pos)
+{
+ bool result; /* Bilan à retourner */
+ uleb128_t size; /* Nombre d'entrées */
+ uleb128_t i; /* Boucle de parcours */
- g_object_unref(G_OBJECT(content));
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler_list),
+ G_BIN_FORMAT(format), pos, &size);
+
+ for (i = 0; i < size && result; i++)
+ result = annotate_dex_encoded_catch_handler(format, pos);
return result;
@@ -421,9 +486,9 @@ static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
-* pos = tête de lecture des symboles. *
+* pos = tête de lecture physique des symboles. *
* *
-* Description : Commente les définitions des gestions d'exceptions par type. *
+* Description : Commente les définitions d'une prise en compte d'exceptions. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -431,45 +496,60 @@ static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t
* *
******************************************************************************/
-static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *format, vmpa2t *pos)
+static bool annotate_dex_encoded_catch_handler(const GDexFormat *format, vmpa2t *pos)
{
- GBinContent *content; /* Contenu binaire à lire */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
+ bool result; /* Bilan à retourner */
+ leb128_t size; /* Nombre de gestionnaires */
+ bool has_catch_all; /* Gestion par défaut ? */
+ uleb128_t i; /* Boucle de parcours */
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler), G_BIN_FORMAT(format), pos, &size);
- /* type_idx */
+ if (!result)
+ goto adech_exit;
- instr = g_raw_instruction_new_uleb128(content, pos);
+ has_catch_all = (size <= 0);
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ if (size < 0)
+ size *= -1;
- asprintf(&text, _("Index for the type of the exception to catch"));
+ /* handlers */
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ for (i = 0; i < size && result; i++)
+ result = annotate_dex_encoded_type_addr_pair(format, pos);
- free(text);
+ /* catch_all_addr */
- /* addr */
+ if (result && has_catch_all)
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_catch_handler_all),
+ G_BIN_FORMAT(format), pos, &size);
- instr = g_raw_instruction_new_uleb128(content, pos);
+ adech_exit:
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ return result;
- asprintf(&text, _("Bytecode address of the associated exception handler"));
+}
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
- free(text);
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* pos = tête de lecture des symboles. *
+* *
+* Description : Commente les définitions des gestions d'exceptions par type. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- /* Nettoyage final */
+static bool annotate_dex_encoded_type_addr_pair(const GDexFormat *format, vmpa2t *pos)
+{
+ bool result; /* Bilan à retourner */
- g_object_unref(G_OBJECT(content));
+ result = parse_field_definitions(PARSING_DEFS(_dex_encoded_type_addr_pair), G_BIN_FORMAT(format), pos, NULL);
- return true;
+ return result;
}
diff --git a/plugins/readdex/header.c b/plugins/readdex/header.c
index f3928ca..d0d0cd7 100644
--- a/plugins/readdex/header.c
+++ b/plugins/readdex/header.c
@@ -25,241 +25,294 @@
#include <i18n.h>
-#include <arch/raw.h>
-#include <format/symbol.h>
#include <format/dex/dex_def.h>
+#include <plugins/fmtp/parser.h>
-/******************************************************************************
-* *
-* Paramètres : format = description de l'exécutable à compléter. *
-* *
-* Description : Charge tous les symboles de l'en-tête DEX. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
+/* Définition des champs */
-bool annotate_dex_header(GDexFormat *format)
-{
- GBinContent *content; /* Contenu binaire à lire */
- SourceEndian endian; /* Boutisme utilisé */
- vmpa2t pos; /* Tête de lecture des symboles*/
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
+static fmt_field_def _dex_header[] = {
+
+ {
+ .name = "magic",
+
+ .size = MDS_8_BITS,
+ .repeat = DEX_FILE_MAGIC_LEN ,
+
+ DISPLAY_RULES(IOD_CHAR, IOD_CHAR, IOD_CHAR, IOD_HEX, IOD_CHAR, IOD_CHAR, IOD_CHAR, IOD_HEX),
+
+ PLAIN_COMMENT(__("DEX magic number"))
+
+ },
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
+ {
+ .name = "checksum",
- endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos))
- return false;
+ PLAIN_COMMENT(__("adler32 checksum used to detect file corruption"))
- /* magic */
+ },
- instr = g_raw_instruction_new_array(content, MDS_8_BITS, DEX_FILE_MAGIC_LEN, &pos, endian);
+ {
+ .name = "signature",
- g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true);
+ .size = MDS_32_BITS,
+ .repeat = 5,
- SET_IMM_DISPLAY(instr, operand, 0, IOD_CHAR);
- SET_IMM_DISPLAY(instr, operand, 1, IOD_CHAR);
- SET_IMM_DISPLAY(instr, operand, 2, IOD_CHAR);
+ PLAIN_COMMENT(__("SHA-1 signature used to uniquely identify files"))
- SET_IMM_DISPLAY(instr, operand, 3, IOD_HEX);
+ },
- SET_IMM_DISPLAY(instr, operand, 4, IOD_CHAR);
- SET_IMM_DISPLAY(instr, operand, 5, IOD_CHAR);
- SET_IMM_DISPLAY(instr, operand, 6, IOD_CHAR);
+ {
+ .name = "file_size",
- SET_IMM_DISPLAY(instr, operand, 7, IOD_HEX);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("DEX magic number"));
+ DISPLAY_RULES(IOD_DEC),
- g_binary_symbol_define_as_block_start(symbol, true);
+ PLAIN_COMMENT(__("Size of the entire file in bytes"))
- /* checksum */
+ },
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ {
+ .name = "header_size",
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("adler32 checksum used to detect file corruption"));
+ DISPLAY_RULES(IOD_DEC),
- /* signature */
+ PLAIN_COMMENT(__("Size of the header in bytes"))
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 5, &pos, endian);
+ },
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ {
+ .name = "endian_tag",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("SHA-1 signature used to uniquely identify files"));
+ .size = MDS_32_BITS,
+ .repeat = 1,
- /* file_size */
+ PLAIN_COMMENT(__("Endianness tag ; 0x12345678 for little-endian"))
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ },
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ {
+ .name = "link_size",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Size of the entire file in bytes"));
+ .size = MDS_32_BITS,
+ .repeat = 1,
- /* header_size */
+ DISPLAY_RULES(IOD_DEC),
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ PLAIN_COMMENT(__("Size of the link section"))
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ },
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Size of the header in bytes"));
+ {
+ .name = "link_off",
- /* endian_tag */
+ .size = MDS_32_BITS,
+ .repeat = 1,
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ PLAIN_COMMENT(__("Offset to the link section"))
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ },
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Endianness tag ; 0x12345678 for little-endian"));
+ {
+ .name = "map_off",
- /* link_size */
+ .size = MDS_32_BITS,
+ .repeat = 1,
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ PLAIN_COMMENT(__("Offset to the map item"))
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ },
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Size of the link section"));
+ {
+ .name = "string_ids_size",
- /* link_off */
+ .size = MDS_32_BITS,
+ .repeat = 1,
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ DISPLAY_RULES(IOD_DEC),
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ PLAIN_COMMENT(__("Count of strings in the string identifiers list"))
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the link section"));
+ },
- /* map_off */
+ {
+ .name = "string_ids_off",
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ PLAIN_COMMENT(__("Offset to the string identifiers list"))
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the map item"));
+ },
- /* string_ids_size */
+ {
+ .name = "type_ids_size",
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ DISPLAY_RULES(IOD_DEC),
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of strings in the string identifiers list"));
+ PLAIN_COMMENT(__("Count of elements in the type identifiers list"))
- /* string_ids_off */
+ },
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ {
+ .name = "type_ids_off",
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the string identifiers list"));
+ PLAIN_COMMENT(__("Offset to the type identifiers list"))
- /* type_ids_size */
+ },
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ {
+ .name = "proto_ids_size",
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the type identifiers list"));
+ DISPLAY_RULES(IOD_DEC),
- /* type_ids_off */
+ PLAIN_COMMENT(__("Count of elements in the prototype identifiers list"))
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ },
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ {
+ .name = "proto_ids_off",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the type identifiers list"));
+ .size = MDS_32_BITS,
+ .repeat = 1,
- /* proto_ids_size */
+ PLAIN_COMMENT(__("Offset to the prototype identifiers list"))
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ },
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ {
+ .name = "field_ids_size",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the prototype identifiers list"));
+ .size = MDS_32_BITS,
+ .repeat = 1,
- /* proto_ids_off */
+ DISPLAY_RULES(IOD_DEC),
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ PLAIN_COMMENT(__("Count of elements in the field identifiers list"))
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ },
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the prototype identifiers list"));
+ {
+ .name = "field_ids_off",
- /* field_ids_size */
+ .size = MDS_32_BITS,
+ .repeat = 1,
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ PLAIN_COMMENT(__("Offset to the field identifiers list"))
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ },
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the field identifiers list"));
+ {
+ .name = "method_ids_size",
- /* field_ids_off */
+ .size = MDS_32_BITS,
+ .repeat = 1,
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ DISPLAY_RULES(IOD_DEC),
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ PLAIN_COMMENT(__("Count of elements in the method identifiers list"))
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the field identifiers list"));
+ },
- /* method_ids_size */
+ {
+ .name = "method_ids_off",
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ DISPLAY_RULES(IOD_DEC),
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the method identifiers list"));
+ PLAIN_COMMENT(__("Offset to the method identifiers list"))
- /* method_ids_off */
+ },
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ {
+ .name = "class_defs_size",
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ .size = MDS_32_BITS,
+ .repeat = 1,
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the method identifiers list"));
+ DISPLAY_RULES(IOD_DEC),
- /* class_defs_size */
+ PLAIN_COMMENT(__("Count of elements in the class definitions list"))
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ },
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ {
+ .name = "class_defs_off",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Count of elements in the class definitions list"));
+ .size = MDS_32_BITS,
+ .repeat = 1,
- /* class_defs_off */
+ PLAIN_COMMENT(__("Offset to the class definitions list"))
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ },
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ {
+ .name = "data_size",
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the class definitions list"));
+ .size = MDS_32_BITS,
+ .repeat = 1,
- /* data_size */
+ DISPLAY_RULES(IOD_DEC),
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ PLAIN_COMMENT(__("Size of data section in bytes"))
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ },
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Size of data section in bytes"));
+ {
+ .name = "data_off",
- /* data_off */
+ .size = MDS_32_BITS,
+ .repeat = 1,
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ PLAIN_COMMENT(__("Offset to the start of the data section"))
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ }
+
+};
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à compléter. *
+* *
+* Description : Charge tous les symboles de l'en-tête DEX. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool annotate_dex_header(GDexFormat *format)
+{
+ bool result; /* Bilan à retourner */
+ vmpa2t pos; /* Tête de lecture des symboles*/
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("Offset to the start of the data section"));
+ result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos);
- g_object_unref(G_OBJECT(content));
+ if (result)
+ result = parse_field_definitions(PARSING_DEFS(_dex_header), G_BIN_FORMAT(format), &pos, NULL);
- return true;
+ return result;
}
diff --git a/plugins/readdex/ids.c b/plugins/readdex/ids.c
index cb24e7d..2586eaf 100644
--- a/plugins/readdex/ids.c
+++ b/plugins/readdex/ids.c
@@ -33,9 +33,197 @@
#include <arch/raw.h>
#include <format/symbol.h>
#include <format/dex/dex_def.h>
+#include <plugins/fmtp/parser.h>
+/* Définition des champs */
+
+
+/* Récupère la taille d'une chaîne de caractères. */
+static bool get_dex_string_length_value(const fmt_field_def *, GBinContent *, vmpa2t *, SourceEndian, uleb128_t *);
+
+
+static fmt_field_def _dex_string_ids_length[] = {
+
+ {
+ .name = "length",
+
+ .get_value = (get_fdef_value_cb)get_dex_string_length_value,
+
+ .is_uleb128 = true,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("String length"))
+
+ }
+
+};
+
+static fmt_field_def _dex_type_ids[] = {
+
+ {
+ .name = "descriptor_idx",
+
+ .size = MDS_32_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the descriptor string of this type"))
+
+ }
+
+};
+
+static fmt_field_def _dex_proto_ids[] = {
+
+ {
+ .name = "shorty_idx",
+
+ .size = MDS_32_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the short-form descriptor string of this prototype"))
+
+ },
+
+ {
+ .name = "return_type_idx",
+
+ .size = MDS_32_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the return type of this prototype"))
+
+ },
+
+ {
+ .name = "parameters_off",
+
+ .size = MDS_32_BITS,
+ .repeat = 1,
+
+ PLAIN_COMMENT(__("Offset to the list of parameter types for this prototype"))
+
+ }
+
+};
+
+static fmt_field_def _dex_field_ids[] = {
+
+ {
+ .name = "class_idx",
+
+ .size = MDS_16_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the definer of this field"))
+
+ },
+
+ {
+ .name = "type_idx",
+
+ .size = MDS_16_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the type of this field"))
+
+ },
+
+ {
+ .name = "name_idx",
+
+ .size = MDS_32_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the name of this field"))
+
+ }
+
+};
+
+static fmt_field_def _dex_method_ids[] = {
+
+ {
+ .name = "class_idx",
+
+ .size = MDS_16_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the definer of this field"))
+
+ },
+
+ {
+ .name = "proto_idx",
+
+ .size = MDS_16_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the prototype of this method"))
+
+ },
+
+ {
+ .name = "name_idx",
+
+ .size = MDS_32_BITS,
+ .repeat = 1,
+
+ DISPLAY_RULES(IOD_DEC),
+
+ PLAIN_COMMENT(__("Index for the name of this method"))
+
+ }
+
+};
+
+
+
+/******************************************************************************
+* *
+* Paramètres : def = définition à l'origine de l'appel. *
+* content = contenu binaire à venir lire. *
+* pos = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* data = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Récupère la taille d'une chaîne de caractères. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool get_dex_string_length_value(const fmt_field_def *def, GBinContent *content, vmpa2t *pos, SourceEndian endian, uleb128_t *length)
+{
+ bool result; /* Bilan à retourner */
+
+ result = g_binary_content_read_uleb128(content, pos, length);
+
+ return result;
+
+}
+
+
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à compléter. *
@@ -51,78 +239,89 @@
bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
{
+ bool result; /* Bilan à retourner */
GBinContent *content; /* Contenu binaire à lire */
const dex_header *header; /* En-tête principale */
SourceEndian endian; /* Boutisme utilisé */
vmpa2t pos; /* Tête de lecture des symboles*/
activity_id_t msg; /* Message de progression */
+ GBinFormat *bformat; /* Autre version du format */
uint32_t i; /* Boucle de parcours */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
+ fmt_field_def field; /* Définition de position */
+ comment_part parts[2]; /* Mise en place des parties */
phys_t loc; /* Localisation physique */
vmpa2t item_pos; /* Position d'un élément */
- vmpa2t start; /* Sauvagarde d'une position */
uleb128_t length; /* Taille de la chaîne en cours*/
- MemoryDataSize leb_size; /* Taille de la taille */
+ GArchInstruction *instr; /* Instruction décodée */
+ GBinSymbol *symbol; /* Symbole à intégrer */
content = g_binary_format_get_content(G_BIN_FORMAT(format));
header = g_dex_format_get_header(format);
endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->string_ids_off, &pos))
- return false;
+ result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->string_ids_off, &pos);
+
+ if (!result)
+ goto adsi_exit;
msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex strings..."),
header->string_ids_size);
- for (i = 0; i < header->string_ids_size; i++)
+ bformat = G_BIN_FORMAT(format);
+
+ bool get_string_offset_value(const fmt_field_def *d, GBinContent *c, vmpa2t *p, SourceEndian e, phys_t *val)
{
- /* Saut vers la définition */
+ bool status; /* Bilan à retourner */
+ uint32_t offset; /* Position trouvée */
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
+ status = g_binary_content_read_u32(c, p, e, &offset);
- SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
+ if (status)
+ *val = offset;
- asprintf(&text, _("Offset for string item #%u/%u"), i, header->string_ids_size - 1);
+ return status;
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
+ }
- free(text);
+ for (i = 0; i < header->string_ids_size && result; i++)
+ {
+ /* Saut vers la définition */
- if (i == 0)
- g_binary_symbol_define_as_block_start(symbol, true);
+ memset(&field, 0, sizeof(field));
- /* Description de la chaîne : taille */
+ field.name = "p_flags";
- operand = g_arch_instruction_get_operand(instr, 0);
+ field.get_value = (get_fdef_value_cb)get_string_offset_value;
- if (!g_imm_operand_to_phys_t(G_IMM_OPERAND(operand), &loc))
- continue;
+ field.size = MDS_32_BITS;
+ field.repeat = 1;
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), loc, &item_pos))
- continue;
+ parts[0].is_static = true;
+ parts[0].static_text = __("Offset for string item #");
- copy_vmpa(&start, &item_pos);
+ parts[1].is_static = false;
+ asprintf(&parts[1].dynamic_text, "%u/%u", i, header->string_ids_size - 1);
- if (!g_binary_content_read_uleb128(content, &item_pos, &length))
- continue;
+ field.ctype = FCT_MULTI;
+ field.comment.parts = parts;
+ field.comment.pcount = ARRAY_SIZE(parts);
+
+ result = parse_field_definitions(&field, 1, bformat, &pos, &loc);
- leb_size = MDS_FROM_BYTES(compute_vmpa_diff(&start, &item_pos));
- assert(leb_size != MDS_UNDEFINED);
+ if (!result)
+ break;
- instr = g_raw_instruction_new_from_value(&start, leb_size, (uint64_t)length);
+ /* Description de la chaîne : taille */
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), loc, &item_pos))
+ continue;
- ADD_RAW_AS_SYM(format, symbol, instr, comment, _("String length"));
+ result = parse_field_definitions(PARSING_DEFS(_dex_string_ids_length), bformat, &item_pos, &length);
/* Description de la chaîne : contenu */
- if (length > 0)
+ if (result && length > 0)
{
instr = g_raw_instruction_new_array(content, MDS_8_BITS, length, &item_pos, endian);
@@ -140,7 +339,9 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
g_object_unref(G_OBJECT(content));
- return true;
+ adsi_exit:
+
+ return result;
}
@@ -160,43 +361,28 @@ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status)
bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
{
- GBinContent *content; /* Contenu binaire à lire */
+ bool result; /* Bilan à retourner */
const dex_header *header; /* En-tête principale */
- SourceEndian endian; /* Boutisme utilisé */
vmpa2t pos; /* Tête de lecture des symboles*/
activity_id_t msg; /* Message de progression */
+ GBinFormat *bformat; /* Autre version du format */
uint32_t i; /* Boucle de parcours */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
-
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
header = g_dex_format_get_header(format);
- endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->type_ids_off, &pos))
- return false;
+ result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->type_ids_off, &pos);
+
+ if (!result)
+ goto adti_exit;
msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex types..."),
header->type_ids_size);
- for (i = 0; i < header->type_ids_size; i++)
- {
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
+ bformat = G_BIN_FORMAT(format);
- asprintf(&text, _("Index for the descriptor string of this type"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
-
- if (i == 0)
- g_binary_symbol_define_as_block_start(symbol, true);
+ for (i = 0; i < header->type_ids_size && result; i++)
+ {
+ result = parse_field_definitions(PARSING_DEFS(_dex_type_ids), bformat, &pos, NULL);
gtk_status_stack_update_activity_value(status, msg, 1);
@@ -204,9 +390,9 @@ bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
gtk_status_stack_remove_activity(status, msg);
- g_object_unref(G_OBJECT(content));
+ adti_exit:
- return true;
+ return result;
}
@@ -226,69 +412,28 @@ bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status)
bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
{
- GBinContent *content; /* Contenu binaire à lire */
+ bool result; /* Bilan à retourner */
const dex_header *header; /* En-tête principale */
- SourceEndian endian; /* Boutisme utilisé */
vmpa2t pos; /* Tête de lecture des symboles*/
activity_id_t msg; /* Message de progression */
+ GBinFormat *bformat; /* Autre version du format */
uint32_t i; /* Boucle de parcours */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
-
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
header = g_dex_format_get_header(format);
- endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->proto_ids_off, &pos))
- return false;
+ result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->proto_ids_off, &pos);
+
+ if (!result)
+ goto adpi_exit;
msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex prototypes..."),
header->proto_ids_size);
- for (i = 0; i < header->proto_ids_size; i++)
- {
- /* shorty_idx */
-
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index for the short-form descriptor string of this prototype"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
-
- if (i == 0)
- g_binary_symbol_define_as_block_start(symbol, true);
-
- /* return_type_idx */
+ bformat = G_BIN_FORMAT(format);
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index for the return type of this prototype"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
-
- /* parameters_off */
-
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Offset to the list of parameter types for this prototype"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
+ for (i = 0; i < header->proto_ids_size && result; i++)
+ {
+ result = parse_field_definitions(PARSING_DEFS(_dex_proto_ids), bformat, &pos, NULL);
gtk_status_stack_update_activity_value(status, msg, 1);
@@ -296,9 +441,9 @@ bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
gtk_status_stack_remove_activity(status, msg);
- g_object_unref(G_OBJECT(content));
+ adpi_exit:
- return true;
+ return result;
}
@@ -318,69 +463,28 @@ bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status)
bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
{
- GBinContent *content; /* Contenu binaire à lire */
+ bool result; /* Bilan à retourner */
const dex_header *header; /* En-tête principale */
- SourceEndian endian; /* Boutisme utilisé */
vmpa2t pos; /* Tête de lecture des symboles*/
activity_id_t msg; /* Message de progression */
+ GBinFormat *bformat; /* Autre version du format */
uint32_t i; /* Boucle de parcours */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
-
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
header = g_dex_format_get_header(format);
- endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->field_ids_off, &pos))
- return false;
+ result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->field_ids_off, &pos);
+
+ if (!result)
+ goto adfi_exit;
msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex fields..."),
header->field_ids_size);
- for (i = 0; i < header->field_ids_size; i++)
- {
- /* class_idx */
-
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index for the definer of this field"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
-
- if (i == 0)
- g_binary_symbol_define_as_block_start(symbol, true);
-
- /* type_idx */
+ bformat = G_BIN_FORMAT(format);
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index for the type of this field"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
-
- /* name_idx */
-
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index for the name of this field"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
+ for (i = 0; i < header->field_ids_size && result; i++)
+ {
+ result = parse_field_definitions(PARSING_DEFS(_dex_field_ids), bformat, &pos, NULL);
gtk_status_stack_update_activity_value(status, msg, 1);
@@ -388,9 +492,9 @@ bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
gtk_status_stack_remove_activity(status, msg);
- g_object_unref(G_OBJECT(content));
+ adfi_exit:
- return true;
+ return result;
}
@@ -410,69 +514,28 @@ bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status)
bool annotate_dex_method_ids(const GDexFormat *format, GtkStatusStack *status)
{
- GBinContent *content; /* Contenu binaire à lire */
+ bool result; /* Bilan à retourner */
const dex_header *header; /* En-tête principale */
- SourceEndian endian; /* Boutisme utilisé */
vmpa2t pos; /* Tête de lecture des symboles*/
- uint32_t i; /* Boucle de parcours */
activity_id_t msg; /* Message de progression */
- GArchInstruction *instr; /* Instruction décodée */
- GArchOperand *operand; /* Opérande à venir modifier */
- GDbComment *comment; /* Définition de commentaire */
- GBinSymbol *symbol; /* Symbole à intégrer */
- char *text; /* Texte constant à insérer */
-
- content = g_binary_format_get_content(G_BIN_FORMAT(format));
+ GBinFormat *bformat; /* Autre version du format */
+ uint32_t i; /* Boucle de parcours */
header = g_dex_format_get_header(format);
- endian = SRE_LITTLE;//g_dex_format_get_endianness(format);
- if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->method_ids_off, &pos))
- return false;
+ result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), header->method_ids_off, &pos);
+
+ if (!result)
+ goto admi_exit;
msg = gtk_status_stack_add_activity(status, _("Writing annotations for all Dex methods..."),
header->method_ids_size);
- for (i = 0; i < header->method_ids_size; i++)
- {
- /* class_idx */
-
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index for the definer of this field"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
+ bformat = G_BIN_FORMAT(format);
- if (i == 0)
- g_binary_symbol_define_as_block_start(symbol, true);
-
- /* proto_idx */
-
- instr = g_raw_instruction_new_array(content, MDS_16_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index for the prototype of this method"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
-
- /* name_idx */
-
- instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian);
-
- SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC);
-
- asprintf(&text, _("Index for the name of this method"));
-
- ADD_RAW_AS_SYM(format, symbol, instr, comment, text);
-
- free(text);
+ for (i = 0; i < header->method_ids_size && result; i++)
+ {
+ result = parse_field_definitions(PARSING_DEFS(_dex_method_ids), bformat, &pos, NULL);
gtk_status_stack_update_activity_value(status, msg, 1);
@@ -480,8 +543,8 @@ bool annotate_dex_method_ids(const GDexFormat *format, GtkStatusStack *status)
gtk_status_stack_remove_activity(status, msg);
- g_object_unref(G_OBJECT(content));
+ admi_exit:
- return true;
+ return result;
}
diff --git a/plugins/readelf/header.c b/plugins/readelf/header.c
index 21884a3..4b3cdbc 100644
--- a/plugins/readelf/header.c
+++ b/plugins/readelf/header.c
@@ -471,17 +471,15 @@ bool annotate_elf_header(GBinFormat *format)
result = g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), 0, &pos);
if (result)
- result = parse_field_definitions(_elf_header_base, ARRAY_SIZE(_elf_header_base), format, &pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_header_base), format, &pos, NULL);
if (result)
{
if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS32)
- result = parse_field_definitions(_elf_header_offset_32, ARRAY_SIZE(_elf_header_offset_32),
- format, &pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_header_offset_32), format, &pos, NULL);
else if (header->hdr32.e_ident[EI_CLASS] == ELFCLASS64)
- result = parse_field_definitions(_elf_header_offset_64, ARRAY_SIZE(_elf_header_offset_64),
- format, &pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_header_offset_64), format, &pos, NULL);
else
result = false;
@@ -489,7 +487,7 @@ bool annotate_elf_header(GBinFormat *format)
}
if (result)
- result = parse_field_definitions(_elf_header_ending, ARRAY_SIZE(_elf_header_ending), format, &pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_header_ending), format, &pos, NULL);
return result;
diff --git a/plugins/readelf/program.c b/plugins/readelf/program.c
index ba47639..b1e253a 100644
--- a/plugins/readelf/program.c
+++ b/plugins/readelf/program.c
@@ -287,28 +287,28 @@ static bool annotate_elf_program_header(GElfFormat *format, SourceEndian endian,
bformat = G_BIN_FORMAT(format);
- result = parse_field_definitions(_elf_phdr_base, ARRAY_SIZE(_elf_phdr_base), bformat, pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_phdr_base), bformat, pos, NULL);
if (format->is_32b)
{
if (result)
- result = parse_field_definitions(_elf_phdr_32b_a, ARRAY_SIZE(_elf_phdr_32b_a), bformat, pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_phdr_32b_a), bformat, pos, NULL);
if (result)
- result = parse_field_definitions(&flags_field, 1, bformat, pos);
+ result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
if (result)
- result = parse_field_definitions(_elf_phdr_32b_b, ARRAY_SIZE(_elf_phdr_32b_b), bformat, pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_phdr_32b_b), bformat, pos, NULL);
}
else
{
if (result)
- result = parse_field_definitions(&flags_field, 1, bformat, pos);
+ result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
if (result)
- result = parse_field_definitions(_elf_phdr_64b, ARRAY_SIZE(_elf_phdr_64b), bformat, pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_phdr_64b), bformat, pos, NULL);
}
diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c
index e689aac..6161892 100644
--- a/plugins/readelf/section.c
+++ b/plugins/readelf/section.c
@@ -370,21 +370,21 @@ static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian,
bformat = G_BIN_FORMAT(format);
- result = parse_field_definitions(&name_field, 1, bformat, pos);
+ result = parse_field_definitions(&name_field, 1, bformat, pos, NULL);
if (result)
- result = parse_field_definitions(_elf_sh_type, ARRAY_SIZE(_elf_sh_type), bformat, pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_sh_type), bformat, pos, NULL);
if (format->is_32b)
{
if (result)
{
flags_field.size = MDS_32_BITS;
- result = parse_field_definitions(&flags_field, 1, bformat, pos);
+ result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
}
if (result)
- result = parse_field_definitions(_elf_shdr_32b, ARRAY_SIZE(_elf_shdr_32b), bformat, pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_shdr_32b), bformat, pos, NULL);
}
else
@@ -392,11 +392,11 @@ static bool annotate_elf_section_header(GElfFormat *format, SourceEndian endian,
if (result)
{
flags_field.size = MDS_64_BITS;
- result = parse_field_definitions(&flags_field, 1, bformat, pos);
+ result = parse_field_definitions(&flags_field, 1, bformat, pos, NULL);
}
if (result)
- result = parse_field_definitions(_elf_shdr_64b, ARRAY_SIZE(_elf_shdr_64b), bformat, pos);
+ result = parse_field_definitions(PARSING_DEFS(_elf_shdr_64b), bformat, pos, NULL);
}
diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c
index b638b8a..e34318f 100755
--- a/src/format/dex/dex.c
+++ b/src/format/dex/dex.c
@@ -54,6 +54,9 @@ static void g_dex_format_dispose(GDexFormat *);
/* Procède à la libération totale de la mémoire. */
static void g_dex_format_finalize(GDexFormat *);
+/* Informe quant au boutisme utilisé. */
+static SourceEndian g_dex_format_get_endianness(const GDexFormat *);
+
/* Indique le type d'architecture visée par le format. */
static const char *g_dex_format_get_target_machine(const GDexFormat *);
@@ -148,6 +151,7 @@ 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 */
+ GBinFormatClass *fmt; /* Version en format basique */
GExeFormatClass *exe; /* Version en exécutable */
object = G_OBJECT_CLASS(klass);
@@ -155,6 +159,10 @@ static void g_dex_format_class_init(GDexFormatClass *klass)
object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_format_dispose;
object->finalize = (GObjectFinalizeFunc)g_dex_format_finalize;
+ fmt = G_BIN_FORMAT_CLASS(klass);
+
+ fmt->get_endian = (format_get_endian_fc)g_dex_format_get_endianness;
+
exe = G_EXE_FORMAT_CLASS(klass);
exe->get_machine = (get_target_machine_fc)g_dex_format_get_target_machine;
@@ -297,6 +305,25 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus
* *
* Paramètres : format = informations chargées à consulter. *
* *
+* Description : Informe quant au boutisme utilisé. *
+* *
+* Retour : Indicateur de boutisme. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static SourceEndian g_dex_format_get_endianness(const GDexFormat *format)
+{
+ return SRE_LITTLE;
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *