web-dev-qa-db-fra.com

Est-il possible de trouver toutes les fonctions exposées par une dll

J'ai été à la recherche d'un moyen d'obtenir toutes les chaînes qui mappent aux noms de fonctions dans une DLL. 

J'entends par là toutes les chaînes pour lesquelles vous pouvez appeler GetProcAddress. Si vous effectuez un dump hexadécimal d'une dll, les symboles (chaînes) sont présents, mais je suppose qu'il faut un appel système pour acquérir ces noms.

55
minty

Cela prend un peu de travail, mais vous pouvez le faire par programme en utilisant la bibliothèque DbgHelp de Microsoft. 

Débogage d’applications pour Microsoft .Net et Microsoft Windows, par John Robbins est un excellent livre (même s’il est un peu plus ancien) qui contient les détails de l’utilisation et le source complet. Et, vous pouvez le chercher sur Amazon pour pas cher!

7
Aaron

Si vous avez MS Visual Studio, il existe un outil de ligne de commande appelé DUMPBIN.

dumpbin/exports <nameofdll>
69
Die in Sente

Il existe trois types distincts de DLL sous Windows:

  1. DLL classiques qui exposent toutes les fonctions disponibles dans la table des exportations de la DLL. Vous pouvez utiliser dumpbin.exe ou depend.exe de Visual Studio, ou le programme free dependency walker pour examiner ces types. Matt Pietrek a écrit de nombreux articles et utilitaires permettant de creuser des fichiers Win32 PE. Découvrez ses classiques Articles de MSDN Magazine . Les DLL C++ contenant des classes exportées exporteront toutes les méthodes de la classe. Malheureusement, il exporte les noms mutilés, de sorte que la sortie de dumpbin est pratiquement illisible. Vous devrez utiliser un programme tel que vc ++ _filet.exe pour démêler la sortie.

  2. DLL COM qui exposent des objets COM. Ces DLL exposent une poignée de fonctions exportées régulières (DllRegisterServer, etc.) permettant au système COM d'instancier des objets. De nombreux utilitaires peuvent examiner ces DLL, mais ils peuvent être assez difficiles à examiner s'ils ne possèdent pas de bibliothèques de types incorporées. 4Developers possède un certain nombre de bons outils COM/ActiveX

  3. DLL .NET contenant des assemblys .NET. Typiquement, vous utiliseriez un outil tel que .NET Reflector pour creuser dans ces répertoires.

Edit: le lien 4Developers ne fonctionne pas.

31
Mike Thompson

Il existe également le programme DEPENDs à http://www.dependencywalker.com/

24
Die in Sente

Essayez ceci (code Linux):

#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

unsigned int vpe2offset(void * base, unsigned int vpe) {
    unsigned int * ptr = base;
    unsigned int pe_offset;
    unsigned short num_sections;

    pe_offset = ptr[0x3c/4];                             //PE header offset
    ptr = base + pe_offset;                              //PE header address
    num_sections = ((unsigned short*)ptr)[6/2];          //Section count
    ptr = ((void*)base) + 0x18 + 0x60 + 16*8 + pe_offset;//Address of first section

    while (num_sections--) {
        if (vpe >= ptr[0x0c/4] && vpe < ptr[0x0c/4] + ptr[0x10/4]) {
            return vpe - ptr[0x0c/4] + ptr[0x14/4];
        }
        ptr += 0x28/4;
    }

    return 0;
}

void iterate_exports(void * base, int(*iterator)(char*)) {
    unsigned int * ptr = base;
    unsigned int pe_offset,
                 exports_offset,
                 number_of_names,
                 address_of_names;

    pe_offset = ptr[0x3c/4];
    ptr = base + pe_offset;
    exports_offset = ptr[0x78/4];
    ptr = base + vpe2offset(base, exports_offset);
    number_of_names = ptr[0x18/4];
    address_of_names = ptr[0x20/4];
    ptr = base + vpe2offset(base, address_of_names);
    while (number_of_names-- && iterator((char*)(base + vpe2offset(base, ptr++[0])))) {
        /* Do nothing */
    }
}

int print_symbol_name(char * name) {
    printf("%s\n", name);
    return 1;
}

int main(int argc, char const *argv[]) {
    int fd;
    struct stat st;
    void * base;

    if (argc == 1) {
        printf("Usage: %s <dll>\n", argv[0]);
    } else if (stat(argv[1], &st) == 0 && (fd = open(argv[1], O_RDONLY)) >= 0) {
        base = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        if (base != MAP_FAILED) {
            iterate_exports(base, print_symbol_name);
            munmap(base, st.st_size);
        } else {
            fprintf(stderr, "Could not map \"%s\".\n", argv[1]);
        }
        close(fd);
    } else {
        fprintf(stderr, "Could not open \"%s\" for reading.\n", argv[1]);
    }
    return 0;
}

Il suit les références à l'intérieur du fichier PE et appelle finalement une fonction de rappel pour chaque symbole exporté. Pour un aperçu du format du fichier PE, voir: http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf

15
Robert Larsen

Je ne connais pas d'API Win32 pour le faire: vous (ou l'un des outils mentionnés dans d'autres articles) le faites en connaissant le format binaire d'un fichier PE et en lisant le fichier: voir http://msdn.Microsoft.com/en-us/magazine/cc301808.aspx (et cet article mentionnait un utilitaire "PEDUMP").

10
ChrisW

J'utilise dumpbinGUI , qui vous donne la liste des exportations (et beaucoup plus) à partir d'un clic droit dans l'Explorateur Windows dumpbin et depends vous donneront également les listes.

6
ctacke

Vous devez inspecter l'en-tête PE du fichier .dll, car c'est ce que Windows fait de toute façon.

En supposant que vous ayez un pointeur sur le IMAGE_OPTIONAL_HEADER du .dll (vous pouvez utiliser la fonction ImageNtHeader de dbghelp avec un handle vers un .dll chargé via LoadLibrary ou tenter de le trouver vous-même si vous connaissez vous-même la disposition du .dll), vous voudrez Pour regarder optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT], recherchez la table d'exportation par rapport à l'en-tête facultatif avec le décalage dedans, puis parcourez la table d'exportation (il s'agit d'un IMAGE_EXPORT_DIRECTORY).

Pour les funsies, une image PE compatible avec les versions antérieures commence par un IMAGE_DOS_HEADER; le décalage par rapport à IMAGE_NT_HEADER est IMAGE_DOS_HEADER::e_lfanew et le IMAGE_OPTIONAL_HEADER est incorporé dans l'en-tête NT.

5
MSN

vous pouvez utiliser un programme appelé visualiseur d'exportation dll: http://www.nirsoft.net/utils/dll_export_viewer.html

2
nick

Je dois toujours faire ça. Je viens d'aller sur l'un de ces sites. Ils hébergent les informations dont nous avons généralement besoin.

Informations sur les fichiers Windows 7 DLL

Informations sur les fichiers Windows XP DLL

2
claws

Vous pouvez également utiliser l'outil linux "objdump" sous Windows, mais vous devrez peut-être installer cygwin au préalable.

J'utilise les commandes suivantes:

# feed the output to less
objdump -x nameOfThe.Dll| less
# or use egrep to filter
objdump -x /cygdrive/c/Windows/system32/user32.dll | \ 
    egrep "^\s*\[[ [:digit:]]{4}\] \w{1,}" | less
1
SchLx

Je suppose que vous allez finir par analyser le fichier PE et vous démêler vous-même si vous voulez trouver les noms de fonction d'une DLL inconnue dans le système d'exécution ou d'un système extrêmement inutile ("dumpbin"); la magie.

Vous devriez être plus clair sur ce que vous voulez.

BFD library fait ce que vous voulez (et l’évier de la cuisine), qui est le composant principal de plusieurs outils GNU binutils. Je ne peux pas être sûr que cela conviendra à votre problème.

0
artificialidiot

Vous n'avez besoin d'aucun outil et vous n'avez pas besoin d'analyser PE. Il suffit d’utiliser l’API Win32 standard (D)

Le code (en C) a été publié à plusieurs reprises sur Adv.Win32 api ng ( News: //comp.os.ms-windows.programmer.win32) (depuis 1992)

0
ferod