summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2017-03-31 17:50:08 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2017-03-31 17:50:08 (GMT)
commitebe248fe406de9565c8c7787187a1d439e68cd84 (patch)
tree8126ea63a5b753f549a90a107d6428db2b299ff2
parent24096140aaa73db9e982db4437bc42a013812658 (diff)
Extracted strings from some extra ELF sections.
-rw-r--r--ChangeLog30
-rw-r--r--plugins/readelf/Makefile.am3
-rw-r--r--plugins/readelf/program.c4
-rw-r--r--plugins/readelf/program.h2
-rw-r--r--plugins/readelf/reader.c3
-rw-r--r--plugins/readelf/section.c4
-rw-r--r--plugins/readelf/section.h2
-rw-r--r--plugins/readelf/strtab.c164
-rw-r--r--plugins/readelf/strtab.h37
-rw-r--r--src/format/elf/elf.c5
-rw-r--r--src/format/elf/section.c60
-rw-r--r--src/format/elf/section.h6
-rw-r--r--src/format/elf/strings.c4
13 files changed, 313 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 2080976..b141036 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
17-03-31 Cyrille Bagard <nocbos@gmail.com>
+ * plugins/readelf/Makefile.am:
+ Add the 'strtab.[ch]' files to libreadelf_la_SOURCES.
+
+ * plugins/readelf/program.c:
+ * plugins/readelf/program.h:
+ Typo.
+
+ * plugins/readelf/reader.c:
+ Update code.
+
+ * plugins/readelf/section.c:
+ * plugins/readelf/section.h:
+ Typo.
+
+ * plugins/readelf/strtab.c:
+ * plugins/readelf/strtab.h:
+ New entries: extract strings from some extra ELF sections.
+
+ * src/format/elf/elf.c:
+ Update code.
+
+ * src/format/elf/section.c:
+ * src/format/elf/section.h:
+ Provide direct information about the range covered by a given section.
+
+ * src/format/elf/strings.c:
+ Typo.
+
+17-03-31 Cyrille Bagard <nocbos@gmail.com>
+
* src/glibext/gbinportion.c:
* src/glibext/gbinportion.h:
Handle many special cases of binary portion inclusion to get a clean tree.
diff --git a/plugins/readelf/Makefile.am b/plugins/readelf/Makefile.am
index f6b3d5e..13f45f8 100644
--- a/plugins/readelf/Makefile.am
+++ b/plugins/readelf/Makefile.am
@@ -5,7 +5,8 @@ libreadelf_la_SOURCES = \
header.h header.c \
program.h program.c \
reader.h reader.c \
- section.h section.c
+ section.h section.c \
+ strtab.h strtab.c
libreadelf_la_CFLAGS = $(AM_CFLAGS)
diff --git a/plugins/readelf/program.c b/plugins/readelf/program.c
index 97c0c4e..6bf117c 100644
--- a/plugins/readelf/program.c
+++ b/plugins/readelf/program.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * header.c - annotation des en-têtes de programme de binaires ELF
+ * program.c - annotation des en-têtes de programme de binaires ELF
*
* Copyright (C) 2015-2017 Cyrille Bagard
*
@@ -354,6 +354,6 @@ bool annotate_elf_program_header_table(GElfFormat *format, GtkStatusStack *statu
gtk_status_stack_remove_activity(status, msg);
- return true;
+ return result;
}
diff --git a/plugins/readelf/program.h b/plugins/readelf/program.h
index 8a4e3fa..bee0fa0 100644
--- a/plugins/readelf/program.h
+++ b/plugins/readelf/program.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * header.h - prototypes pour l'annotation des en-têtes de programme de binaires ELF
+ * program.h - prototypes pour l'annotation des en-têtes de programme de binaires ELF
*
* Copyright (C) 2015-2017 Cyrille Bagard
*
diff --git a/plugins/readelf/reader.c b/plugins/readelf/reader.c
index 238b3a3..01d5d90 100644
--- a/plugins/readelf/reader.c
+++ b/plugins/readelf/reader.c
@@ -30,6 +30,7 @@
#include "header.h"
#include "program.h"
#include "section.h"
+#include "strtab.h"
@@ -71,6 +72,8 @@ G_MODULE_EXPORT bool handle_binary_format(const GPluginModule *plugin, PluginAct
result &= annotate_elf_section_header_table(elf_fmt, status);
+ show_elf_section_string_table(elf_fmt, status);
+
hbf_exit:
return result;
diff --git a/plugins/readelf/section.c b/plugins/readelf/section.c
index 89b13c4..f2cae76 100644
--- a/plugins/readelf/section.c
+++ b/plugins/readelf/section.c
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * header.c - annotation des en-têtes de section de binaires ELF
+ * section.c - annotation des en-têtes de section de binaires ELF
*
* Copyright (C) 2015-2017 Cyrille Bagard
*
@@ -431,6 +431,6 @@ bool annotate_elf_section_header_table(GElfFormat *format, GtkStatusStack *statu
gtk_status_stack_remove_activity(status, msg);
- return true;
+ return result;
}
diff --git a/plugins/readelf/section.h b/plugins/readelf/section.h
index d91730d..3168dab 100644
--- a/plugins/readelf/section.h
+++ b/plugins/readelf/section.h
@@ -1,6 +1,6 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * header.h - prototypes pour l'annotation des en-têtes de section de binaires ELF
+ * section.h - prototypes pour l'annotation des en-têtes de section de binaires ELF
*
* Copyright (C) 2015-2017 Cyrille Bagard
*
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));
+
+}
diff --git a/plugins/readelf/strtab.h b/plugins/readelf/strtab.h
new file mode 100644
index 0000000..a3c8c8b
--- /dev/null
+++ b/plugins/readelf/strtab.h
@@ -0,0 +1,37 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * strtab.h - prototypes pour la 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/>.
+ */
+
+
+#ifndef _PLUGINS_READELF_STRTAB_H
+#define _PLUGINS_READELF_STRTAB_H
+
+
+#include <format/elf/elf.h>
+
+
+
+/* Affiche les chaînes liées aux sections ELF. */
+void show_elf_section_string_table(GElfFormat *, GtkStatusStack *);
+
+
+
+#endif /* _PLUGINS_READELF_STRTAB_H */
diff --git a/src/format/elf/elf.c b/src/format/elf/elf.c
index 0ad90ff..bc48eb5 100644
--- a/src/format/elf/elf.c
+++ b/src/format/elf/elf.c
@@ -411,6 +411,7 @@ static void g_elf_format_refine_portions(GElfFormat *format)
bool has_strings; /* Section trouvée ? */
elf_shdr shdr; /* En-tête de section ELF */
uint64_t sh_flags; /* Droits associés à une partie*/
+ mrange_t range; /* Emplacement d'une section */
const char *name; /* Nom trouvé ou NULL */
exe_format = G_EXE_FORMAT(format);
@@ -494,9 +495,9 @@ static void g_elf_format_refine_portions(GElfFormat *format)
else if (sh_flags & SHF_WRITE) background = BPC_DATA;
else background = BPC_DATA_RO;
- init_vmpa(&addr, ELF_SHDR(format, shdr, sh_offset), ELF_SHDR(format, shdr, sh_addr));
+ get_elf_section_range(format, &shdr, &range);
- new = g_binary_portion_new(background, &addr, ELF_SHDR(format, shdr, sh_size));
+ new = g_binary_portion_new(background, get_mrange_addr(&range), get_mrange_length(&range));
if (has_strings)
name = extract_name_from_elf_string_section(format, &strings,
diff --git a/src/format/elf/section.c b/src/format/elf/section.c
index 9583927..556c0ed 100644
--- a/src/format/elf/section.c
+++ b/src/format/elf/section.c
@@ -207,6 +207,37 @@ void get_elf_section_content(const GElfFormat *format, const elf_shdr *section,
/******************************************************************************
* *
* Paramètres : format = description de l'exécutable à consulter. *
+* section = section à consulter. *
+* range = emplacement de la fonction à renseigner. [OUT] *
+* *
+* Description : Fournit la localisation d'une section. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void get_elf_section_range(const GElfFormat *format, const elf_shdr *section, mrange_t *range)
+{
+ virt_t virt; /* Emplacement virtuel */
+ vmpa2t tmp; /* Enregistrement intermédiaire*/
+
+ virt = ELF_SHDR(format, *section, sh_addr);
+
+ if (virt == 0)
+ virt = VMPA_NO_VIRTUAL;
+
+ init_vmpa(&tmp, ELF_SHDR(format, *section, sh_offset), virt);
+
+ init_mrange(range, &tmp, ELF_SHDR(format, *section, sh_size));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : format = description de l'exécutable à consulter. *
* name = nom de la section recherchée. *
* offset = position de la section trouvée. [OUT] *
* size = taille de la section trouvée. [OUT] *
@@ -237,6 +268,35 @@ bool find_elf_section_content_by_name(const GElfFormat *format, const char *name
/******************************************************************************
* *
+* Paramètres : format = description de l'exécutable à consulter. *
+* name = nom de la section recherchée. *
+* range = emplacement de la fonction à renseigner. [OUT] *
+* *
+* Description : Recherche une zone donnée au sein de binaire par nom. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool find_elf_section_range_by_name(const GElfFormat *format, const char *name, mrange_t *range)
+{
+ bool result; /* Bilan à retourner */
+ elf_shdr section; /* Section trouvée ou non */
+
+ result = find_elf_section_by_name(format, name, &section);
+
+ if (result)
+ get_elf_section_range(format, &section, range);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : format = description de l'exécutable à consulter. *
* section = section contenant des chaînes terminées par '\0'. *
* index = indice du premier caractères à cerner. *
diff --git a/src/format/elf/section.h b/src/format/elf/section.h
index aed6f9e..f3be0f4 100644
--- a/src/format/elf/section.h
+++ b/src/format/elf/section.h
@@ -45,9 +45,15 @@ bool find_elf_sections_by_type(const GElfFormat *, uint32_t, elf_shdr **, size_t
/* Fournit les adresses et taille contenues dans une section. */
void get_elf_section_content(const GElfFormat *, const elf_shdr *, phys_t *, phys_t *, virt_t *);
+/* Fournit la localisation d'une section. */
+void get_elf_section_range(const GElfFormat *, const elf_shdr *, mrange_t *);
+
/* Recherche une zone donnée au sein de binaire par nom. */
bool find_elf_section_content_by_name(const GElfFormat *, const char *, phys_t *, phys_t *, virt_t *);
+/* Recherche une zone donnée au sein de binaire par nom. */
+bool find_elf_section_range_by_name(const GElfFormat *, const char *, mrange_t *);
+
/* Identifie une chaîne de caractères dans une section adéquate. */
const char *extract_name_from_elf_string_section(const GElfFormat *, const elf_shdr *, off_t);
diff --git a/src/format/elf/strings.c b/src/format/elf/strings.c
index 9bcb87f..8901db9 100644
--- a/src/format/elf/strings.c
+++ b/src/format/elf/strings.c
@@ -155,8 +155,8 @@ bool parse_elf_string_data(GElfFormat *format, phys_t start, phys_t size, virt_t
const bin_t *data; /* Contenu complet et original */
vmpa2t pos; /* Tête de lecture */
bool cut; /* Séparation nette ? */
- off_t i; /* Boucle de parcours */
- off_t end; /* Position de fin de chaîne */
+ 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 */