当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何以编程方式确定Windows可执行文件DLL依赖项?》经验,为你挑选了3个好方法。

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

要清楚,我不是要确定正在运行的exec的DLL依赖项,而是任何任意exec(可能缺少必需的DLL).我正在寻找在C/C++应用程序中实现的解决方案.这是我的应用程序在运行时需要完成的事情,不能由第三方应用程序完成(如依赖).



1> Scott Wisnie..:

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

你可以找到一些文章描述的结构是怎样布局在这里,并在这里.您可以在此处下载文章的源代码.

我认为这应该可以满足您的一切需求.

更新:

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



2> Steve Rowe..:

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



3> 小智..:

根据脚踏代码执行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;
}

推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有