我一直在尋找一種方法來獲取映射到dll中的函數名稱的所有字符串。有沒有辦法找到一個dll暴露的所有功能
我的意思是這一切,你可以調用GetProcAddress的字符串。如果你做了一個DLL的十六進制轉儲符號(字符串)在那裏,但我認爲必須有一個系統調用來獲取這些名稱。
我一直在尋找一種方法來獲取映射到dll中的函數名稱的所有字符串。有沒有辦法找到一個dll暴露的所有功能
我的意思是這一切,你可以調用GetProcAddress的字符串。如果你做了一個DLL的十六進制轉儲符號(字符串)在那裏,但我認爲必須有一個系統調用來獲取這些名稱。
需要一點工作,但是您可以使用Microsoft的DbgHelp庫以編程方式執行此操作。
Debugging Applications for Microsoft .Net and Microsoft Windows, by John Robbins是一本很好的(如果有點老)書,其中包含使用細節和完整的來源。而且,你可以在亞馬遜上以便宜的價格購買它!
如果你有MS Visual Studio中,有一個名爲DUMPBIN的命令行工具。
dumpbin /exports <nameofdll>
...也被稱爲:link.exe/dump/exports – reuben 2009-01-14 06:21:24
你不用甚至不需要VS.您可以下載MS Windows SDK,並在其中使用CMD Shell。很有用。 – MeanwhileInHell 2013-11-12 13:48:38
太棒了。這應該被標記爲已接受的答案 – 2015-11-25 09:19:22
的依賴程序我用dumpbinGUI,它給你的出口從Windows資源管理器右鍵單擊列表(和更多)。 dumpbin
和depends
都會給你列表。
我不知道有一個WIn32 API可以這樣做:相反,您(或其他文章中提到的其中一個工具)通過了解PE文件的二進制格式並讀取該文件來完成此操作:請參閱http://msdn.microsoft.com/en-us/magazine/cc301808.aspx (該文章提到了「PEDUMP」工具)。
我想你最終會解析PE文件,但demangling自己,如果你想找到在運行時或極其無用系統(「DUMPBIN」)未知DLL的函數名;魔法。
你應該更清楚你想要什麼。
BFD庫你想要做什麼(以及廚房水槽),這是一些GNU binutils的工具的主要成分。我無法確定它是否適合您的問題。
您需要檢查.dll文件的PE頭,因爲這是最終什麼Windows不反正。
假設你有一個指向該.dll的IMAGE_OPTIONAL_HEADER
(您可以使用DBGHELP的ImageNtHeader
函數的句柄加載一個.dll通過LoadLibrary
或試圖自行找到它,如果你知道該.dll自己的佈局)您需要查看optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]
,找到相對於帶有偏移量的可選標題的導出表,然後轉到導出表(這是一個IMAGE_EXPORT_DIRECTORY
)。
對於funsies,一個向後兼容PE圖像開始時用IMAGE_DOS_HEADER
;與IMAGE_NT_HEADER
的偏移量爲IMAGE_DOS_HEADER::e_lfanew
,並且IMAGE_OPTIONAL_HEADER
被嵌入在NT標頭中。
有一個名爲DLL導出瀏覽器可以使用程序:http://www.nirsoft.net/utils/dll_export_viewer.html
你不需要任何工具,你不需要解析PE。 只需使用標準的Win32 API(d)
的代碼(C)已經在Adv.Win32發表了許多次的API NG( 消息://comp.os.ms-windows.programmer.win32)(自1992年...)
有三種不同類型的DLL Windows下:在DLL的導出表暴露每個可用的功能
經典的DLL。您可以使用dumpbin.exe或依賴。EXE從Visual Studio,或免費dependency walker來檢查這些類型。 Matt Pietrek寫了很多文章和實用程序來挖掘Win32 PE文件。看看他的經典MSDN Magazine articles。包含導出類的C++ DLL將導出類中的每個方法。不幸的是,它輸出了重名的名字,所以dumpbin的輸出實際上是不可讀的。您將需要使用像vC++ _ filt.exe這樣的程序來對輸出進行分解。
公開COM對象的COM DLL。這些DLL公開了一些常規的導出函數(DllRegisterServer等),使COM系統能夠實例化對象。有很多實用程序可以查看這些DLL,但除非它們具有嵌入式類型庫,否則它們可能很難檢查。 4Developers有許多優秀的COM/ActiveX工具
包含.NET程序集的.NET DLL。通常你會使用像.NET Reflector這樣的工具來挖掘這些。
試試這個(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
您也可以在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
只是雞蛋裏挑骨頭,但我認爲你的意思 >但我想必須有一個系統調用 – 2009-01-13 20:19:22
如果你正在尋找一種方式來做到這一點programmaticly,看我的回答進一步下降。 – Aaron 2009-01-16 04:32:57
還要記住,DLL可以導出沒有字符串名稱的函數,並且必須通過它們的序號進行訪問。 – 2013-10-02 17:33:31