Is there a way to find all the functions exposed by a dll

86,089

Solution 1

It takes a bit of work, but you can do this programmaticly using the DbgHelp library from Microsoft.

Debugging Applications for Microsoft .Net and Microsoft Windows, by John Robbins is an excellent (if a little older) book which contains use details and full source. And, you can pick it up on Amazon for the cheap!

Solution 2

If you have MS Visual Studio, there is a command line tool called DUMPBIN.

dumpbin /exports <nameofdll>

Solution 3

There are three distinct types of DLLs under Windows:

  1. Classic DLLs that expose every available function in the exports table of the DLL. You can use dumpbin.exe or depends.exe from Visual Studio, or the free dependency walker to examine these types. Matt Pietrek wrote many articles and utilities for digging into Win32 PE files. Have a look at his classic MSDN Magazine articles. C++ DLLs that contain exported classes will export every method in the class. Unfortunately it exports the mangled names, so the output of dumpbin is virtually unreadable. You will need to use a program like vc++_filt.exe to demangle the output.

  2. COM DLLs that expose COM objects. These DLLs expose a handful of regular exported functions (DllRegisterServer etc) that enable the COM system to instantiate objects. There are many utilities that can look at these DLLs, but unless they have embedded type libraries they can be quite difficult to examine. 4Developers have a number of good COM/ActiveX tools

  3. .NET DLLs that contain .NET assemblies. Typiically you would use a tool like .NET Reflector to dig into these.

Edit: 4Developers link is not working.

Solution 4

Also there is the DEPENDs program at http://www.dependencywalker.com/

Solution 5

Try this (Linux) C code:

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

It follows references inside the PE file and finally calls a callback function for each exported symbol. For an overview of the PE file format see this: http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf

Share:
86,089
minty
Author by

minty

Updated on June 28, 2020

Comments

  • minty
    minty almost 4 years

    I've been searching for a way to get all the strings that map to function names in a dll.

    I mean by this all the strings for which you can call GetProcAddress. If you do a hex dump of a dll the symbols (strings) are there but I figure there must me a system call to acquire those names.

  • Die in Sente
    Die in Sente over 15 years
    An excellent answer, which I'm voting up, but I'll add the link to the definitive reference document on the PE file format: microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
  • Greg Domjan
    Greg Domjan over 15 years
    Alternativly, Depends is also available in the platform sdk installation.
  • reuben
    reuben over 15 years
    ...also known as: link.exe /dump /exports
  • user2895001
    user2895001 over 15 years
    @Greg The version in the SDK is a few versions older than what's on the website. Probably fine with it, but might as well recomend the source..
  • MeanwhileInHell
    MeanwhileInHell over 10 years
    You don't even need VS. You can just download the MS Windows SDK, and use the CMD Shell in it. Very useful.
  • Evgen
    Evgen about 6 years
    The names it reports are still mangled, but you can quickly de-mangle them with demangler.com