如何确定哪个DLL是二进制文件依赖于使用编程方法?
要清楚,我不是要确定正在运行的exec的DLL依赖项,而是任何任意exec(可能缺少必需的DLL).我正在寻找在C/C++应用程序中实现的解决方案.这是我的应用程序在运行时需要完成的事情,不能由第三方应用程序完成(如依赖).
看看IMAGE_LOAD_FUNCTION
API.它将返回一个指向LOADED_IMAGE
结构的指针,您可以使用该指针访问PE文件的各个部分.
你可以找到一些文章描述的结构是怎样布局在这里,并在这里.您可以在此处下载文章的源代码.
我认为这应该可以满足您的一切需求.
更新:
我刚刚下载了文章的源代码.如果你打开EXEDUMP.CPP
并看看DumpImportsSection
它应该有你需要的代码.
这是不可能确定的.至少不是没有大量的工作.任何二进制文件都可以调用LoadLibrary来加载DLL.即使您要扫描代码以获取对LoadLibrary的所有调用,您也必须确定使用哪些字符串来识别库ID.追踪字符串放置在动态内存中的位置将比您想要解决的更难.
根据脚踏代码执行76行(不要忘记添加Imagehlp.lib作为依赖):
#include#include "windows.h" //DONT REMOVE IT #include "ImageHlp.h" #include "stdafx.h" template 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 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; }