diff options
Diffstat (limited to 'plugins/elf/loading.c')
-rw-r--r-- | plugins/elf/loading.c | 120 |
1 files changed, 83 insertions, 37 deletions
diff --git a/plugins/elf/loading.c b/plugins/elf/loading.c index 5bd7daa..bf79f13 100644 --- a/plugins/elf/loading.c +++ b/plugins/elf/loading.c @@ -75,6 +75,8 @@ struct _GElfLoading phys_t sym_start; /* Début de zone des symboles */ uint32_t sym_count; /* Nombre de symboles présents */ + GBinSymbol **imports_to_fill; /* Liste de symboles constitués*/ + }; struct @@ -107,9 +109,9 @@ struct _GElfLoading struct { - sym_iter_t *iter; /* Symboles à parcourir */ + vmpa2t start; /* Point de départ du parcours */ - elf_applying_cb callback_1; /* Routine de traitement #1 */ + elf_importing_cb callback_1; /* Routine de traitement #1 */ }; @@ -213,7 +215,13 @@ static void g_elf_loading_init(GElfLoading *loading) static void g_elf_loading_dispose(GElfLoading *loading) { - if (loading->kind == 2) + size_t i; /* Boucle de parcours */ + + if (loading->kind == 1) + for (i = 0; i < loading->rel_count; i++) + g_clear_object(&loading->imports_to_fill[i]); + + else if (loading->kind == 2) g_clear_object(&loading->content); G_OBJECT_CLASS(g_elf_loading_parent_class)->dispose(G_OBJECT(loading)); @@ -336,7 +344,7 @@ GElfLoading *g_elf_loading_new_for_relocations(GElfFormat *format, phys_t begin, /****************************************************************************** * * * Paramètres : format = ensemble d'instructions désassemblées. * -* iter = itérateur sur les symboles à parcourir. * +* start = point de départ du parcours de la PLT. * * str_start = début de la zone contenant les descriptions. * * relocs = table des relocalisations chargées. * * rel_count = nombre de ces éléments à interpréter. * @@ -353,7 +361,7 @@ GElfLoading *g_elf_loading_new_for_relocations(GElfFormat *format, phys_t begin, * * ******************************************************************************/ -GElfLoading *g_elf_loading_new_for_applying(GElfFormat *format, sym_iter_t *iter, phys_t str_start, elf_rel *relocs, size_t rel_count, phys_t sym_start, uint32_t sym_count, activity_id_t id, elf_applying_cb callback) +GElfLoading *g_elf_loading_new_for_imported(GElfFormat *format, const vmpa2t *start, phys_t str_start, elf_rel *relocs, size_t rel_count, phys_t sym_start, uint32_t sym_count, activity_id_t id, elf_importing_cb callback) { GElfLoading *result; /* Tâche à retourner */ @@ -368,7 +376,9 @@ GElfLoading *g_elf_loading_new_for_applying(GElfFormat *format, sym_iter_t *iter result->sym_start = sym_start; result->sym_count = sym_count; - result->iter = iter; + result->imports_to_fill = calloc(rel_count, sizeof(GBinSymbol *)); + + copy_vmpa(&result->start, start); result->callback_1 = callback; result->kind = 1; @@ -454,11 +464,10 @@ GElfLoading *g_elf_loading_new_for_strings(GElfFormat *format, phys_t begin, phy static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status) { GElfFormat *format; /* Format plus accessible */ - phys_t iter; /* Boucle de parcours */ + phys_t iter; /* Boucle de parcours #1 */ 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 */ + size_t i; /* Boucle de parcours #2 */ GBinSymbol *symbol; /* Symbole analysé */ format = loading->format; @@ -487,35 +496,23 @@ static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status) case 1: - ret = true; - - processed = 0; - valid = 0; - - for (symbol = get_symbol_iterator_next(loading->iter); - symbol != NULL && ret; - symbol = get_symbol_iterator_next(loading->iter)) + for (i = 0; i < loading->rel_count; i++) { - ret = loading->callback_1(loading, format, &valid, symbol); - - g_object_unref(G_OBJECT(symbol)); + symbol = loading->callback_1(loading, format, &loading->start); - if (!ret) + if (symbol == NULL) { - log_variadic_message(LMT_ERROR, _("Error while applying ELF relocation %zu!"), processed); + log_variadic_message(LMT_ERROR, _("Error while applying ELF relocation %zu!"), i); break; } - processed++; + loading->imports_to_fill[i] = symbol; gtk_status_stack_update_activity_value(status, loading->id, 1); - if (processed == loading->rel_count) - break; - } - loading->status = (processed == loading->rel_count); + loading->status = (i == loading->rel_count); break; case 2: @@ -702,25 +699,28 @@ bool g_elf_loading_search_for_relocation(const GElfLoading *loading, const uint6 * Paramètres : loading = chargement pour ELF à poursuivre. * * index = indice du symbole concerné. * * * -* Description : Construit la désignation adaptée à un symbole importé. * +* Description : Construit le symbole adapté à un symbole importé. * * * -* Retour : Nouvelle étiquette constituée ou NULL en cas d'échec. * +* Retour : Nouveau symbole constitué ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ -char *g_elf_loading_build_plt_name(const GElfLoading *loading, uint64_t index) +GBinSymbol *g_elf_loading_build_plt_symbol(const GElfLoading *loading, uint64_t index) { - char *result; /* Désignation à retourner */ + GBinSymbol *result; /* Symbole à retourner */ GElfFormat *format; /* Format plus accessible */ phys_t offset; /* Tête de lecture brute */ elf_sym sym; /* Symbole aux infos visées */ bool status; /* Bilan de récupération */ uint32_t name; /* Indice du nom du symbole */ vmpa2t pos; /* Position de lecture */ + GBinFormat *base; /* Autre version du format */ const GBinContent *content; /* Contenu binaire à lire */ - const char *prefix; /* Première partie de nom */ + const char *raw_label; /* Première partie de nom */ + GBinRoutine *routine; /* Routine à mettre en place */ + char *new_label; /* Nouvelle étiquette */ format = loading->format; @@ -739,17 +739,27 @@ char *g_elf_loading_build_plt_name(const GElfLoading *loading, uint64_t index) init_vmpa(&pos, offset, VMPA_NO_VIRTUAL); - content = G_BIN_FORMAT(format)->content; + base = G_BIN_FORMAT(format); + content = base->content; - prefix = (const char *)g_binary_content_get_raw_access(content, &pos, 1); + raw_label = (const char *)g_binary_content_get_raw_access(content, &pos, 1); - if (prefix != NULL && prefix[0] == '\0') + if (raw_label != NULL && raw_label[0] == '\0') result = NULL; else { - result = strdup(prefix); - result = stradd(result, "@plt"); + routine = g_binary_format_decode_routine(base, raw_label); + + raw_label = g_binary_routine_get_name(routine); + + new_label = strdup(raw_label); + new_label = stradd(new_label, "@plt"); + + g_binary_routine_set_name(routine, new_label); + + result = G_BIN_SYMBOL(routine); + } } @@ -761,6 +771,42 @@ char *g_elf_loading_build_plt_name(const GElfLoading *loading, uint64_t index) /****************************************************************************** * * +* Paramètres : loading = chargement pour ELF à poursuivre. * +* count = taille de la liste retournée. [OUT] * +* * +* Description : Fournit la liste de symboles importés constituée. * +* * +* Retour : Liste des symboles importés ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinSymbol **g_elf_loading_get_imported_symbols(const GElfLoading *loading, size_t *count) +{ + GBinSymbol **result; /* Liste à retourner */ + size_t i; /* Boucle de parcours */ + + *count = loading->rel_count; + + result = malloc(*count * sizeof(GBinSymbol *)); + + for (i = 0; i < *count; i++) + { + result[i] = loading->imports_to_fill[i]; + assert(result[i] != NULL); + + g_object_ref(G_OBJECT(result[i])); + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : loading = chargement pour ELF à mener. * * content = gestionnaire de contenu utilisé. [OUT] * * first = première position traitée par la tâche. [OUT] * |