/* Chrysalide - Outil d'analyse de fichiers binaires * strtab.h - présentation des chaînes liées au format des binaires ELF * * Copyright (C) 2017 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 Chrysalide. If not, see . */ #include "strtab.h" #include #include #include #include #include /* Affiche les chaînes présentes dans une zone de données. */ static void parse_elf_string_table(GElfFormat *, GPreloadInfo *, const GBinContent *, const mrange_t *, GtkStatusStack *); /****************************************************************************** * * * Paramètres : format = description de l'exécutable à compléter. * * info = informations à constituer en avance de phase. * * content = contenu binaire à analyser. * * range = espace à couvrir pendant l'analyse. * * status = barre de statut à tenir informée. * * * * Description : Affiche les chaînes présentes dans une zone de données. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void parse_elf_string_table(GElfFormat *format, GPreloadInfo *info, const GBinContent *content, const mrange_t *range, GtkStatusStack *status) { phys_t length; /* Taille de la couverture */ vmpa2t pos; /* Tête de lecture */ const bin_t *data; /* Donnés à parcourir */ bool cut; /* Séparation nette ? */ GBinFormat *base; /* Autre version du format */ phys_t i; /* Boucle de parcours */ phys_t end; /* Position de fin de chaîne */ GArchInstruction *instr; /* Instruction décodée */ bool inserted; /* Bilan d'une insertion */ const mrange_t *irange; /* Espace occupé par une chaîne*/ GBinSymbol *symbol; /* Symbole à intégrer */ length = get_mrange_length(range); copy_vmpa(&pos, get_mrange_addr(range)); data = g_binary_content_get_raw_access(content, &pos, length); /** * Si la section demandée est anormalement grande (cf. exemple de la suite de * tests "tests/format/elf/oob_section_name.asm")... */ if (data == NULL) return; /* Boucle de parcours */ cut = true; base = G_BIN_FORMAT(format); for (i = 0; i < length; i++) if (isprint(data[i])) { for (end = i + 1; end < length; end++) if (!isprint(data[end])) break; if (end < length && isspace(data[end])) end++; if (end < length && data[end] == '\0') end++; copy_vmpa(&pos, get_mrange_addr(range)); advance_vmpa(&pos, i); instr = g_raw_instruction_new_array(content, MDS_8_BITS, end - i, &pos, MDS_UNDEFINED); assert(instr != NULL); g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); inserted = g_preload_info_add_instruction(info, instr); if (inserted) { irange = g_arch_instruction_get_range(instr); symbol = g_string_symbol_new_read_only(base, irange, SET_GUESS); g_object_ref(G_OBJECT(symbol)); g_binary_format_add_symbol(base, symbol); /* Jointure avec la chaîne précédente ? */ if (cut) g_string_symbol_build_label(G_STR_SYMBOL(symbol), base); g_object_unref(G_OBJECT(symbol)); } /* Conclusion */ cut = (data[end - 1] == '\0'); i = end - 1; } else cut = true; } /****************************************************************************** * * * Paramètres : format = description de l'exécutable à compléter. * * info = informations à constituer en avance de phase. * * status = barre de statut à tenir informée. * * * * Description : Affiche les chaînes liées aux sections ELF. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void show_elf_section_string_table(GElfFormat *format, GPreloadInfo *info, GtkStatusStack *status) { GBinContent *content; /* Contenu binaire à lire */ mrange_t range; /* Espace à parcourir */ bool found; /* Détection d'une section */ content = g_binary_format_get_content(G_BIN_FORMAT(format)); found = find_elf_section_range_by_name(format, ".interp", &range); if (found) parse_elf_string_table(format, info, content, &range, status); found = find_elf_section_range_by_name(format, ".shstrtab", &range); if (found) parse_elf_string_table(format, info, content, &range, status); found = find_elf_section_range_by_name(format, ".strtab", &range); if (found) parse_elf_string_table(format, info, content, &range, status); g_object_unref(G_OBJECT(content)); }