From 33880cfe5e5de8b81e8a825878b3bbe8ef736f3f Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 30 Apr 2017 21:21:29 +0200 Subject: Parsed Dex format fields using the new generic parser. --- ChangeLog | 21 ++ plugins/fmtp/def.h | 18 +- plugins/fmtp/parser.c | 39 +++- plugins/fmtp/parser.h | 2 +- plugins/readdex/class.c | 451 +++++++++++++++++-------------------- plugins/readdex/code.c | 560 ++++++++++++++++++++++++++-------------------- plugins/readdex/header.c | 311 ++++++++++++++----------- plugins/readdex/ids.c | 505 +++++++++++++++++++++++------------------ plugins/readelf/header.c | 10 +- plugins/readelf/program.c | 12 +- plugins/readelf/section.c | 12 +- src/format/dex/dex.c | 27 +++ 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 + + * 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 * 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 -#include -#include - - #include -#include -#include #include #include +#include #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 -#include -#include +#include +#include -#include -#include -#include -#include +/* 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 -#include -#include #include +#include -/****************************************************************************** -* * -* 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 #include #include +#include +/* 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. * -- cgit v0.11.2-87-g4458