/* Chrysalide - Outil d'analyse de fichiers binaires * ids.c - annotation des références aux chaînes de caractères et identifiants * * Copyright (C) 2016 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "ids.h" #include #include #include #include #include #include #include /****************************************************************************** * * * Paramètres : format = description de l'exécutable à compléter. * * status = barre de statut à tenir informée. * * * * Description : Commente les définitions des chaînes de caractères. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool annotate_dex_string_ids(const GDexFormat *format, GtkStatusStack *status) { 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 */ 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 */ 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; 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++) { /* Saut vers la définition */ instr = g_raw_instruction_new_array(content, MDS_32_BITS, 1, &pos, endian); SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX); asprintf(&text, _("Offset for string item #%u/%u"), i, header->string_ids_size - 1); ADD_RAW_AS_SYM(format, symbol, instr, comment, text); free(text); if (i == 0) g_binary_symbol_define_as_block_start(symbol, true); /* Description de la chaîne : taille */ operand = g_arch_instruction_get_operand(instr, 0); if (!g_imm_operand_to_phys_t(G_IMM_OPERAND(operand), &loc)) continue; if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), loc, &item_pos)) continue; copy_vmpa(&start, &item_pos); if (!g_binary_content_read_uleb128(content, &item_pos, &length)) continue; leb_size = MDS_FROM_BYTES(compute_vmpa_diff(&start, &item_pos)); assert(leb_size != MDS_UNDEFINED); instr = g_raw_instruction_new_from_value(&start, leb_size, (uint64_t)length); SET_IMM_DISPLAY(instr, operand, 0, IOD_DEC); ADD_RAW_AS_SYM(format, symbol, instr, comment, _("String length")); /* Description de la chaîne : contenu */ if (length > 0) { instr = g_raw_instruction_new_array(content, MDS_8_BITS, length, &item_pos, endian); g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); ADD_STR_AS_SYM(format, symbol, instr); } gtk_status_stack_update_activity_value(status, msg, 1); } gtk_status_stack_remove_activity(status, msg); g_object_unref(G_OBJECT(content)); return true; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à compléter. * * status = barre de statut à tenir informée. * * * * Description : Commente les définitions des identifiants de types. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool annotate_dex_type_ids(const GDexFormat *format, GtkStatusStack *status) { 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 */ 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; 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); 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); gtk_status_stack_update_activity_value(status, msg, 1); } gtk_status_stack_remove_activity(status, msg); g_object_unref(G_OBJECT(content)); return true; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à compléter. * * status = barre de statut à tenir informée. * * * * Description : Commente les définitions des identifiants de prototypes. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool annotate_dex_proto_ids(const GDexFormat *format, GtkStatusStack *status) { 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 */ 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; 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 */ 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); gtk_status_stack_update_activity_value(status, msg, 1); } gtk_status_stack_remove_activity(status, msg); g_object_unref(G_OBJECT(content)); return true; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à compléter. * * status = barre de statut à tenir informée. * * * * Description : Commente les définitions des identifiants de champs. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool annotate_dex_field_ids(const GDexFormat *format, GtkStatusStack *status) { 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 */ 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; 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 */ 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); gtk_status_stack_update_activity_value(status, msg, 1); } gtk_status_stack_remove_activity(status, msg); g_object_unref(G_OBJECT(content)); return true; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à compléter. * * status = barre de statut à tenir informée. * * * * Description : Commente les définitions des identifiants de méthodes. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ bool annotate_dex_method_ids(const GDexFormat *format, GtkStatusStack *status) { 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*/ 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)); 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; 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); 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); gtk_status_stack_update_activity_value(status, msg, 1); } gtk_status_stack_remove_activity(status, msg); g_object_unref(G_OBJECT(content)); return true; }