From 3674529a39efe30672fd386ae25367fea1502a69 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 9 Feb 2020 23:02:42 +0100 Subject: Hardened the renaming of Elf external entries. --- plugins/elf/format.c | 20 ++++++++++++++------ plugins/elf/loading.c | 4 +++- plugins/elf/loading.h | 2 +- plugins/elf/symbols.c | 31 +++++++++++++++++++++++++------ 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; -- cgit v0.11.2-87-g4458