diff options
Diffstat (limited to 'plugins/elf/dynamic.c')
-rw-r--r-- | plugins/elf/dynamic.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/plugins/elf/dynamic.c b/plugins/elf/dynamic.c index 782167c..ed681d1 100644 --- a/plugins/elf/dynamic.c +++ b/plugins/elf/dynamic.c @@ -107,3 +107,98 @@ bool find_elf_dynamic_item_from_pheader(const GElfFormat *format, const elf_phdr return result; } + + +/****************************************************************************** +* * +* Paramètres : format = description de l'exécutable à consulter. * +* count = nombre d'éléments dans la liste constituée. * +* * +* Description : Fournit la liste des objets partagés requis. * +* * +* Retour : Liste de noms d'objets ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char **list_elf_needed_objects(const GElfFormat *format, size_t *count) +{ + const char **result; /* Liste à retourner */ + elf_phdr dynamic; /* Programme à analyser */ + virt_t strtab_virt; /* Adresse mémoire des chaînes */ + uint64_t max; /* Nombre d'entités présentes */ + uint64_t i; /* Boucle de parcours */ + phys_t pos; /* Position de lecture */ + elf_dyn item; /* Informations extraites */ + vmpa2t strtab_pos; /* Emplacement des chaînes */ + GBinContent *content; /* Contenu global analysé */ + vmpa2t end; /* Limite finale de contenu */ + vmpa2t str_pos; /* Emplacement d'une chaîne */ + phys_t diff; /* Données encore disponibles */ + const bin_t *string; /* Nouvelle chaîne trouvée */ + + result = NULL; + *count = 0; + + if (!find_elf_program_by_type(format, PT_DYNAMIC, &dynamic)) + goto leno_exit; + + max = ELF_PHDR(format, dynamic, p_filesz) / ELF_SIZEOF_DYN(format); + + /* Première passe : recherche des chaînes */ + + strtab_virt = VMPA_NO_VIRTUAL; + + for (i = 0; i < max; i++) + { + pos = ELF_PHDR(format, dynamic, p_offset) + i * ELF_SIZEOF_DYN(format); + + if (!read_elf_dynamic_entry(format, pos, &item)) + break; + + if (ELF_DYN(format, item, d_tag) == DT_STRTAB) + strtab_virt = ELF_DYN(format, item, d_un.d_val); + + } + + if (strtab_virt == VMPA_NO_VIRTUAL) + goto leno_exit; + + if (!g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), strtab_virt, &strtab_pos)) + goto leno_exit; + + /* Seconde passe : recherche des objets requis */ + + content = G_BIN_FORMAT(format)->content; + + g_binary_content_compute_end_pos(content, &end); + + for (i = 0; i < max; i++) + { + pos = ELF_PHDR(format, dynamic, p_offset) + i * ELF_SIZEOF_DYN(format); + + if (!read_elf_dynamic_entry(format, pos, &item)) + break; + + if (ELF_DYN(format, item, d_tag) == DT_NEEDED) + { + copy_vmpa(&str_pos, &strtab_pos); + advance_vmpa(&str_pos, ELF_DYN(format, item, d_un.d_val)); + + diff = compute_vmpa_diff(&str_pos, &end); + + string = g_binary_content_get_raw_access(content, &str_pos, diff); + + result = (const char **)realloc(result, ++(*count) * sizeof(const char *)); + result[*count - 1] = (const char *)string; + + } + + } + + leno_exit: + + return result; + +} |