diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2017-04-30 19:21:29 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2017-04-30 19:21:29 (GMT) |
commit | 33880cfe5e5de8b81e8a825878b3bbe8ef736f3f (patch) | |
tree | 9dcbe3e9e9903e447eeac916be689cd2d39614de /plugins/readdex/ids.c | |
parent | b16071a35adaf95d5e67b0dd984e9ba9d7ba28f9 (diff) |
Parsed Dex format fields using the new generic parser.
Diffstat (limited to 'plugins/readdex/ids.c')
-rw-r--r-- | plugins/readdex/ids.c | 505 |
1 files changed, 284 insertions, 221 deletions
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; } |