Die*_*nte 72
如果您有MS Visual Studio,则有一个名为DUMPBIN的命令行工具.
dumpbin /exports <nameofdll>
Mik*_*son 33
Windows下有三种不同类型的DLL:
经典DLL,它暴露DLL的exports表中的每个可用函数.您可以使用Visual Studio中的dumpbin.exe或depends.exe,或者使用自由依赖性walker来检查这些类型.Matt Pietrek写了许多文章和实用程序,用于挖掘Win32 PE文件.看看他的经典MSDN杂志文章.包含导出类的C++ DLL将导出类中的每个方法.不幸的是,它导出了损坏的名称,因此dumpbin的输出实际上是不可读的.您需要使用类似vc ++ _ filt.exe的程序来解压缩输出.
暴露COM对象的COM DLL.这些DLL公开了一些常规导出函数(DllRegisterServer等),使COM系统能够实例化对象.有许多实用程序可以查看这些DLL,但除非它们具有嵌入式类型库,否则它们很难检查.4开发人员拥有许多优秀的COM/ActiveX工具
包含.NET程序集的.NET DLL.通常,你会使用像.NET Reflector这样的工具来深入研究这些工具.
编辑:4Developers链接无法正常工作.
Rob*_*sen 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;
}
Run Code Online (Sandbox Code Playgroud)
它遵循PE文件中的引用,最后为每个导出的符号调用回调函数.有关PE文件格式的概述,请参阅:http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf
Chr*_*isW 10
我不知道WIn32 API可以做到这一点:相反,您(或其他帖子中提到的工具之一)通过了解PE文件的二进制格式并读取文件来完成它:请参阅http:// msdn .microsoft.com/en-us/magazine/cc301808.aspx(该文章提到了"PEDUMP"实用程序).
这需要一些工作,但您可以使用Microsoft 的DbgHelp库以编程方式执行此操作.
John Robbins调试Microsoft .Net和Microsoft Windows的应用程序是一本优秀的(如果有点旧)书,其中包含使用细节和完整源代码.并且,您可以在亚马逊上以便宜的价格购买它!
您需要检查.dll的PE头,因为这最终是Windows所做的.
假设你有一个指向.dll的指针IMAGE_OPTIONAL_HEADER(如果你自己知道.dll的布局,你可以使用ImageNtHeader带有.dll句柄的dbghelp 函数LoadLibrary或者自己尝试找到它),你会想看看optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT],找到相对于带有偏移量的可选标题的导出表,然后遍历导出表(它是a IMAGE_EXPORT_DIRECTORY).
对于funsies,向后兼容的PE图像以a开头IMAGE_DOS_HEADER; 偏移到IMAGE_NT_HEADERis IMAGE_DOS_HEADER::e_lfanew,并IMAGE_OPTIONAL_HEADER嵌入在NT标头中.