summaryrefslogtreecommitdiff
path: root/plugins/elf
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-02-09 22:02:42 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-02-09 22:02:42 (GMT)
commit3674529a39efe30672fd386ae25367fea1502a69 (patch)
treedfcbc96b56e596cc78975c9de6e5bc8fd8db2f42 /plugins/elf
parentea19719b17ff319c6c728271907f8f2ac7d8c9df (diff)
Hardened the renaming of Elf external entries.
Diffstat (limited to 'plugins/elf')
-rw-r--r--plugins/elf/format.c20
-rw-r--r--plugins/elf/loading.c4
-rw-r--r--plugins/elf/loading.h2
-rw-r--r--plugins/elf/symbols.c31
4 files changed, 43 insertions, 14 deletions
diff --git a/plugins/elf/format.c b/plugins/elf/format.c
index f2f7609..c5f5530 100644
--- a/plugins/elf/format.c
+++ b/plugins/elf/format.c
@@ -333,7 +333,7 @@ static bool g_elf_format_analyze(GElfFormat *format, wgroup_id_t gid, GtkStatusS
exe = G_EXE_FORMAT(format);
if (!read_elf_header(format, &format->header, &format->is_32b, &format->endian))
- goto gefa_error;
+ goto error;
/* Vérification des tailles d'entrée de table */
@@ -377,7 +377,7 @@ static bool g_elf_format_analyze(GElfFormat *format, wgroup_id_t gid, GtkStatusS
default:
log_variadic_message(LMT_ERROR, "Architecture not supported for ELF binaries");
- goto gefa_error;
+ goto error;
break;
}
@@ -398,17 +398,17 @@ static bool g_elf_format_analyze(GElfFormat *format, wgroup_id_t gid, GtkStatusS
preload_binary_format(PGA_FORMAT_PRELOAD, base, base->info, status);
if (!load_elf_symbols(format, gid, status))
- goto gefa_error;
+ goto error;
if (!find_all_elf_strings(format, gid, status))
- goto gefa_error;
+ goto error;
if (!g_executable_format_complete_loading(exe, gid, status))
- goto gefa_error;
+ goto error;
result = true;
- gefa_error:
+ error:
return result;
@@ -450,6 +450,14 @@ static SourceEndian g_elf_format_get_endianness(const GElfFormat *format)
static void g_elf_format_complete_analysis(GElfFormat *format, wgroup_id_t gid, GtkStatusStack *status)
{
+ /**
+ * C'est la phase de désassemblage qui produit les symboles externes appelés
+ * au sein du code.
+ *
+ * Le renommage de ces symboles doit donc intervenir une fois les symboles
+ * en place, donc après les opérations de désassemblage terminées.
+ */
+
refresh_elf_relocations(format, gid, status);
}
diff --git a/plugins/elf/loading.c b/plugins/elf/loading.c
index 7b257f0..5bd7daa 100644
--- a/plugins/elf/loading.c
+++ b/plugins/elf/loading.c
@@ -458,6 +458,7 @@ static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status)
phys_t old; /* Sauvegarde du point d'avant */
bool ret; /* Bilan d'un appel */
size_t processed; /* Nombre de symboles traités */
+ virt_t valid; /* Adresse virtuelle valide */
GBinSymbol *symbol; /* Symbole analysé */
format = loading->format;
@@ -489,12 +490,13 @@ static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status)
ret = true;
processed = 0;
+ valid = 0;
for (symbol = get_symbol_iterator_next(loading->iter);
symbol != NULL && ret;
symbol = get_symbol_iterator_next(loading->iter))
{
- ret = loading->callback_1(loading, format, symbol);
+ ret = loading->callback_1(loading, format, &valid, symbol);
g_object_unref(G_OBJECT(symbol));
diff --git a/plugins/elf/loading.h b/plugins/elf/loading.h
index 62d8efe..8fb4ce9 100644
--- a/plugins/elf/loading.h
+++ b/plugins/elf/loading.h
@@ -52,7 +52,7 @@ typedef struct _GElfLoadingClass GElfLoadingClass;
typedef bool (* elf_loading_cb) (GElfLoading *, GElfFormat *, phys_t *);
/* Assure l'intégration d'un symbole issu des relocalisations. */
-typedef bool (* elf_applying_cb) (GElfLoading *, GElfFormat *, GBinSymbol *);
+typedef bool (* elf_applying_cb) (GElfLoading *, GElfFormat *, virt_t *, GBinSymbol *);
/* Indique le type défini pour les tâches de chargements pour format ELF. */
diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c
index 26876bd..854d724 100644
--- a/plugins/elf/symbols.c
+++ b/plugins/elf/symbols.c
@@ -101,7 +101,7 @@ static bool do_elf_relocation_loading(GElfLoading *, GElfFormat *, phys_t *);
static bool load_elf_relocations(GElfFormat *, const elf_phdr *, elf_rel **, size_t *, wgroup_id_t, GtkStatusStack *);
/* Assure l'intégration d'un symbole issu des relocalisations. */
-static bool do_elf_relocation_renaming(GElfLoading *, GElfFormat *, GBinSymbol *);
+static bool do_elf_relocation_renaming(GElfLoading *, GElfFormat *, virt_t *, GBinSymbol *);
/* Applique les étiquettes issues des relocalisations. */
static bool apply_elf_relocations(GElfFormat *, elf_rel *, size_t, sym_iter_t *, wgroup_id_t, GtkStatusStack *);
@@ -1263,6 +1263,7 @@ bool refresh_elf_relocations(GElfFormat *format, wgroup_id_t gid, GtkStatusStack
* *
* Paramètres : loading = chargement de relocalisations en cours. *
* format = format ELF à compléter. *
+* valid = dernière adresse virtuelle non couverte. [OUT] *
* symbol = symbole courant issu de la liste à analyser. *
* *
* Description : Assure l'intégration d'un symbole issu des relocalisations. *
@@ -1273,7 +1274,7 @@ bool refresh_elf_relocations(GElfFormat *format, wgroup_id_t gid, GtkStatusStack
* *
******************************************************************************/
-static bool do_elf_relocation_renaming(GElfLoading *loading, GElfFormat *format, GBinSymbol *symbol)
+static bool do_elf_relocation_renaming(GElfLoading *loading, GElfFormat *format, virt_t *valid, GBinSymbol *symbol)
{
bool result; /* Bilan à retourner */
const mrange_t *range; /* Espace occupé par le symbole*/
@@ -1290,6 +1291,22 @@ static bool do_elf_relocation_renaming(GElfLoading *loading, GElfFormat *format,
range = g_binary_symbol_get_range(symbol);
+ /**
+ * Il peut arriver qu'un symbole figure par erreur dans la liste des symboles
+ * importés. Cela fait par exemple suite au désassemblage d'une zone considèrée
+ * de façon erronée comme du code, opération qui conduit à la création fortuite
+ * d'un symbole non désiré.
+ *
+ * On se prémunit ici d'une erreur de traitement en vérifiant simplement la
+ * couverture des symboles externes, qui englobe un éventuel symbole superflu.
+ */
+
+ if (range->addr.virtual < *valid)
+ {
+ result = true;
+ goto exit;
+ }
+
stype = g_binary_symbol_get_stype(symbol);
if (stype != STP_ROUTINE && stype != STP_CODE_LABEL && stype != STP_ENTRY_POINT)
@@ -1297,7 +1314,7 @@ static bool do_elf_relocation_renaming(GElfLoading *loading, GElfFormat *format,
g_binary_format_add_error(G_BIN_FORMAT(format), BFE_SPECIFICATION, get_mrange_addr(range),
_("The PLT seems to contains more than routines"));
- goto derr_exit;
+ goto exit;
}
@@ -1308,10 +1325,10 @@ static bool do_elf_relocation_renaming(GElfLoading *loading, GElfFormat *format,
/* Détermination de la relocalisation associée */
result = format->ops.get_linkage_offset(format, range, &offset);
- if (!result) goto derr_exit;
+ if (!result) goto exit;
result = g_elf_loading_search_for_relocation(loading, &offset, &reloc);
- if (!result) goto derr_exit;
+ if (!result) goto exit;
/* Récupération des données du symbole visé */
@@ -1342,7 +1359,9 @@ static bool do_elf_relocation_renaming(GElfLoading *loading, GElfFormat *format,
free(name);
- derr_exit:
+ *valid = range->addr.virtual + range->length;
+
+ exit:
return result;