summaryrefslogtreecommitdiff
path: root/plugins/readelf/strtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/readelf/strtab.c')
-rw-r--r--plugins/readelf/strtab.c164
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));
+
+}