有没有办法找到一个DLL暴露的所有功能

时间:2009-01-12 23:20:40

标签: c++ c winapi dll

我一直在寻找一种方法来获取映射到dll中函数名称的所有字符串。

我的意思是你可以调用GetProcAddress的所有字符串。如果你做一个dll的十六进制转储符号(字符串)在那里,但我认为必须有一个系统调用来获取这些名称。

13 个答案:

答案 0 :(得分:69)

如果您有MS Visual Studio,则有一个名为DUMPBIN的命令行工具。

dumpbin /exports <nameofdll>

答案 1 :(得分:32)

Windows下有三种不同类型的DLL:

  1. 公开DLL,它暴露DLL的exports表中的每个可用函数。您可以使用Visual Studio中的dumpbin.exe或depends.exe,或免费dependency walker来检查这些类型。 Matt Pietrek写了许多文章和实用程序,用于挖掘Win32 PE文件。看看他的经典MSDN Magazine articles。包含导出类的C ++ DLL将导出类中的每个方法。不幸的是,它导出了损坏的名称,因此dumpbin的输出实际上是不可读的。您需要使用类似vc ++ _ filt.exe的程序来解压缩输出。

  2. 公开COM对象的COM DLL。这些DLL公开了一些常规导出函数(DllRegisterServer等),使COM系统能够实例化对象。有许多实用程序可以查看这些DLL,但除非它们具有嵌入式类型库,否则它们很难检查。 4Developers有许多优秀的COM / ActiveX工具

  3. 包含.NET程序集的.NET DLL。通常,你会使用像.NET Reflector这样的工具来深入研究这些工具。

  4. 编辑:4Developers链接无效。

答案 2 :(得分:24)

还有http://www.dependencywalker.com/

的DEPENDs计划

答案 3 :(得分:16)

试试这个(Linux)C代码:

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

它遵循PE文件中的引用,最后为每个导出的符号调用回调函数。有关PE文件格式的概述,请参阅:http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf

答案 4 :(得分:10)

我不知道要使用WIn32 API:相反,您(或其他帖子中提到的工具之一)通过了解PE文件的二进制格式并读取文件来执行此操作:请参阅{{ 3}}(那篇文章提到了“PEDUMP”实用程序)。

答案 5 :(得分:7)

这需要一些工作,但您可以使用Microsoft的DbgHelp库以编程方式执行此操作。

Debugging Applications for Microsoft .Net and Microsoft Windows, by John Robbins是一本优秀(如果有点旧)的书,其中包含使用细节和完整来源。并且,您可以在亚马逊上以便宜的价格购买它!

答案 6 :(得分:6)

我使用dumpbinGUI,它在Windows资源管理器中右键单击,为您提供导出列表(以及更多)。 dumpbindepends也会为您提供列表。

答案 7 :(得分:5)

你需要检查.dll的PE头,因为这最终是Windows所做的。

假设你有一个指向.dll IMAGE_OPTIONAL_HEADER的指针(你可以使用dbghelp的ImageNtHeader函数,通过LoadLibrary加载.dll的句柄,或者尝试自己查找你知道你自己的.dll的布局),你会想看optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT],找到相对于可选标题的导出表,其中有偏移量,然后走导出表(它是{{1} }})。

对于funsies,向后兼容的PE图像以IMAGE_EXPORT_DIRECTORY开始; IMAGE_DOS_HEADER的偏移量为IMAGE_NT_HEADERIMAGE_DOS_HEADER::e_lfanew嵌入在NT标头中。

答案 8 :(得分:2)

有一个名为dll export viewer的程序,您可以使用:http://www.nirsoft.net/utils/dll_export_viewer.html

答案 9 :(得分:2)

我总是要这样做。我只是去其中一个网站。他们主持我们通常需要的信息。

Windows 7 DLL File Information

Windows XP DLL File Information

答案 10 :(得分:1)

你也可以使用&#34; objdump&#34; windows下的linux工具,但你可能要先安装cygwin。

我使用以下命令:

foreach (string key in HttpContext.Request.Form.Keys)
{      
}

答案 11 :(得分:0)

我想如果你想在运行时或极无用的系统(“dumpbin”)中找到未知dll的函数名,你最终会解析PE文件并自己进行解码;魔法。

你应该更清楚你想要什么。

BFD库可以做你想要的(和厨房水槽),这是几个GNU binutils工具的主要组成部分。我无法确定它是否适合你的问题。

答案 12 :(得分:0)

您不需要任何工具,也不需要解析PE。 只需使用标准的Win32 api(D)

代码(C中)已在Adv.Win32 api ng上多次发布( news://comp.os.ms-windows.programmer.win32)(自1992年起......)