summaryrefslogtreecommitdiff
path: root/plugins/elf/dynamic.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/elf/dynamic.c')
-rw-r--r--plugins/elf/dynamic.c95
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;
+
+}