有没有办法find所有由dll暴露的function

我一直在寻找一种方法来获取映射到一个DLL中的函数名称的所有string。

我的意思是所有可以调用GetProcAddress的string。 如果你做一个DLL的hex转储的符号(string)在那里,但我想那里必须我一个系统调用来获取这些名称。

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

由John Robbins撰写的针对Microsoft .Net和Microsoft Windows的debugging应用程序是一本很好的(如果稍微老一点的)书,其中包含使用细节和完整源代码。 而且,你可以在亚马逊上买便宜的!

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

  dumpbin / exports <nameofdll> 

在Windows下有三种不同types的DLL:

  1. 经典DLL公开DLL的导出表中每个可用函数的经典DLL。 您可以使用Visual Studio中的dumpbin.exe或depend.exe或免费的依赖关系人员来检查这些types。 Matt Pietrek写了很多文章和实用程序来挖掘Win32 PE文件。 看看他的经典MSDN杂志文章 。 包含导出类的C ++ DLL将导出类中的每个方法。 不幸的是,它输出了重名的名字,所以dumpbin的输出实际上是不可读的。 您需要使用像vc ++ _ filt.exe这样的程序来对输出进行分解。

  2. 公开COM对象的COM DLL。 这些DLL暴露了一些常规的导出函数(DllRegisterServer等),使COM系统能够实例化对象。 有很多实用程序可以查看这些DLL,但除非它们具有embedded式types库,否则它们可能相当难以检查。 4开发人员有一些很好的COM / ActiveX工具

  3. 包含.NET程序集的.NET DLL。 通常你会使用像.NET Reflector这样的工具来挖掘它们。

我不知道WIn32 API是这样做的:相反,你(或其他职位中提到的其中一个工具)通过了解PE文件的二进制格式并读取该文件来完成此操作:请参阅http:// msdn .microsoft.com / en-us / magazine / cc301808.aspx (该文章提到了“PEDUMP”实用程序)。

试试这个(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文件中的引用,最后为每个导出的符号调用一个callback函数。 有关PE文件格式的概述,请参阅: http : //www.openrce.org/reference_library/files/reference/PE%20Format.pdf

我使用dumpbinGUI ,它给你的Windows资源pipe理器中的右键单击导出列表(以及更多)。 dumpbindepends都会给你列表。

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

假设你有一个指向.dll的IMAGE_OPTIONAL_HEADER的指针(你可以使用dbghelp的ImageNtHeader函数来处理通过LoadLibrary加载的.dll的句柄,或者如果你自己知道.dll的布局,试图自己find它),你会想要查看optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] ,find导出表相对于在那里的偏移量的可选标题,然后走出导出表(这是一个IMAGE_EXPORT_DIRECTORY )。

对于funsies,一个向后兼容的PE图像开始与IMAGE_DOS_HEADER ; IMAGE_NT_HEADER的偏移量是IMAGE_DOS_HEADER::e_lfanew ,并且IMAGE_OPTIONAL_HEADER被embedded到NT头中。

有一个程序称为DLL导出查看器,您可以使用: http : //www.nirsoft.net/utils/dll_export_viewer.html

我总是必须这样做。 我只是去这些网站之一。 他们主持我们通常需要的信息。

Windows 7 DLL文件信息

Windows XP DLL文件信息

我想你最终会parsingPE文件,如果你想在运行时或者无用的系统(“dumpbin”)中find一个未知的dll的函数名, 魔法。

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

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

你不需要任何工具,也不需要parsingPE。 只要使用标准的Win32 API(D)

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

你也可以在windows下使用“objdump”linux工具,但是你可能需要先安装cygwin。

我使用以下命令:

 # 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