如何以编程方式确定Windows可执行文件的DLL依赖关系?

如何确定哪些DLL是一个二进制文件依赖于使用编程方法?

要清楚,我不是要确定正在运行的exec的DLL依赖关系,而是确定任意exec(可能缺less必需的DLL)的DLL依赖关系。 我在找一个在C / C ++应用程序中实现的解决scheme。 这是我的应用程序需要在运行时完成的事情,不能由第三方应用程序(如依赖)来完成。

看看IMAGE_LOAD_FUNCTION API。 它将返回一个指向LOADED_IMAGE结构的指针,您可以使用该指针访问PE文件的各个部分。

你可以找到一些文章来描述这里的结构是如何布置的。 你可以在这里下载文章的源代码。

我认为这应该给你你需要的一切。

更新:

我刚刚下载了文章的源代码。 如果你打开EXEDUMP.CPP并看看DumpImportsSection它应该有你需要的代码。

这是不可能确定的。 至少不是没有很多的工作。 任何二进制文件都可以调用LoadLibrary来加载一个DLL。 即使您要扫描所有对LoadLibrary的调用的代码,也必须确定使用哪些字符串来标识库。 追踪动态内存中字符串的放置位置将比您要解决的难度更大。

基于pedump代码的76行(不要忘记添加Imagehlp.lib作为依赖):

 #include <stdio.h> #include "windows.h" //DONT REMOVE IT #include "ImageHlp.h" #include "stdafx.h" template <class T> PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva, T* pNTHeader) // 'T' == PIMAGE_NT_HEADERS { PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(pNTHeader); unsigned i; for ( i=0; i < pNTHeader->FileHeader.NumberOfSections; i++, section++ ) { // This 3 line idiocy is because Watcom's linker actually sets the // Misc.VirtualSize field to 0. (!!! - Retards....!!!) DWORD size = section->Misc.VirtualSize; if ( 0 == size ) size = section->SizeOfRawData; // Is the RVA within this section? if ( (rva >= section->VirtualAddress) && (rva < (section->VirtualAddress + size))) return section; } return 0; } template <class T> LPVOID GetPtrFromRVA( DWORD rva, T* pNTHeader, PBYTE imageBase ) // 'T' = PIMAGE_NT_HEADERS { PIMAGE_SECTION_HEADER pSectionHdr; INT delta; pSectionHdr = GetEnclosingSectionHeader( rva, pNTHeader ); if ( !pSectionHdr ) return 0; delta = (INT)(pSectionHdr->VirtualAddress-pSectionHdr->PointerToRawData); return (PVOID) ( imageBase + rva - delta ); } void DumpDllFromPath(wchar_t* path) { char name[300]; wcstombs(name,path,300); PLOADED_IMAGE image=ImageLoad(name,0); if (image->FileHeader->OptionalHeader.NumberOfRvaAndSizes>=2) { PIMAGE_IMPORT_DESCRIPTOR importDesc= (PIMAGE_IMPORT_DESCRIPTOR)GetPtrFromRVA( image->FileHeader->OptionalHeader.DataDirectory[1].VirtualAddress, image->FileHeader,image->MappedAddress); while ( 1 ) { // See if we've reached an empty IMAGE_IMPORT_DESCRIPTOR if ( (importDesc->TimeDateStamp==0 ) && (importDesc->Name==0) ) break; printf(" %s\n", GetPtrFromRVA(importDesc->Name, image->FileHeader, image->MappedAddress) ); importDesc++; } } ImageUnload(image); } //Pass exe or dll as argument int _tmain(int argc, _TCHAR* argv[]) { DumpDllFromPath(argv[1]); return 0; } 

简而言之,您需要为可执行文件使用的每个DLL扫描PE文件的导入部分 然后递归地定位并扫描每个dll,直到找到所有的依赖关系。

当然,应用程序可以使用LoadLibrary系列函数来实现所需或可选的功能。 这将不会被检测到这种方法。

如果您有一个目标可执行文件,则依赖Walker可以通过使用配置文件菜单来完成此操作。 简单地加载可执行文件,告诉它开始分析,它将列出执行程序时加载的所有模块。

依赖沃克常见问题(第一个问题…)

你可以调用一个DLL来为你计算所有这些信息,并把答案作为一个CString数组传递回来?

PE格式DLL可以为你做这个。 提供源代码,没有GPL限制。 PE文件浏览器是一个使用DLL的GUI应用程序,也提供了源代码(没有GPL)。

当然,这是可能的,容易的! 它甚至是一个Win32 api组的年龄常见问题

=>用DBAPI编写几行代码