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; + +} | 
