diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2020-02-09 22:02:42 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2020-02-09 22:02:42 (GMT) | 
| commit | 3674529a39efe30672fd386ae25367fea1502a69 (patch) | |
| tree | dfcbc96b56e596cc78975c9de6e5bc8fd8db2f42 /plugins | |
| parent | ea19719b17ff319c6c728271907f8f2ac7d8c9df (diff) | |
Hardened the renaming of Elf external entries.
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/elf/format.c | 20 | ||||
| -rw-r--r-- | plugins/elf/loading.c | 4 | ||||
| -rw-r--r-- | plugins/elf/loading.h | 2 | ||||
| -rw-r--r-- | 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; | 
