diff options
Diffstat (limited to 'plugins/readelf/strtab.c')
-rw-r--r-- | plugins/readelf/strtab.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/plugins/readelf/strtab.c b/plugins/readelf/strtab.c new file mode 100644 index 0000000..c94deed --- /dev/null +++ b/plugins/readelf/strtab.c @@ -0,0 +1,164 @@ + +/* 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "strtab.h" + + +#include <ctype.h> + + +#include <arch/raw.h> +#include <format/elf/section.h> + + + +/* Affiche les chaînes présentes dans une zone de données. */ +static void parse_elf_string_table(GElfFormat *, const GBinContent *, const mrange_t *, GtkStatusStack *); + + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* 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, 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 ? */ + phys_t i; /* Boucle de parcours */ + phys_t end; /* Position de fin de chaîne */ + GArchInstruction *instr; /* Instruction décodée */ + GBinSymbol *symbol; /* Symbole à intégrer */ + char *label; /* Désignation de la chaîne */ + + length = get_mrange_length(range); + + copy_vmpa(&pos, get_mrange_addr(range)); + data = g_binary_content_get_raw_access(content, &pos, length); + + cut = true; + + /* Boucle de parcours */ + + cut = true; + + 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); + + g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true); + + ADD_STR_AS_SYM(format, symbol, instr); + + /* Jointure avec la chaîne précédente ? */ + + if (cut) + { + copy_vmpa(&pos, get_mrange_addr(range)); + advance_vmpa(&pos, i); + + label = create_string_label(G_BIN_FORMAT(format), &pos, end - i); + + g_binary_symbol_set_alt_label(symbol, label); + + free(label); + + } + + /* Conclusion */ + + cut = (data[end - 1] == '\0'); + + i = end - 1; + + } + else cut = true; + +} + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à compléter. * +* 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, 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, content, &range, status); + + found = find_elf_section_range_by_name(format, ".shstrtab", &range); + + if (found) + parse_elf_string_table(format, content, &range, status); + + found = find_elf_section_range_by_name(format, ".strtab", &range); + + if (found) + parse_elf_string_table(format, content, &range, status); + + g_object_unref(G_OBJECT(content)); + +} |