Как определить зависимости DLL исполняемых файлов windows программно?

Как определить, какая DLL двоичная зависит от использования программных методов?

чтобы быть ясным, я не пытаюсь определить зависимости DLL запущенного exec, но любого произвольного exec (который может отсутствовать требуемая DLL). Я ищу решение для реализации в C/C++ приложений. Это то, что должно быть сделано моим приложением во время выполнения и не может быть сделано сторонним приложением (например, зависит).

7 ответов


посмотри IMAGE_LOAD_FUNCTION API-интерфейс. Он вернет указатель на LOADED_IMAGE структура, которую можно использовать для доступа к различным разделам PE-файла.

вы можете найти некоторые статьи, которые описывают структуры размечаются здесь и здесь. Вы можете скачать исходный код для статей здесь.

Я думаю, это должно дать вам все, что вы необходимость.

обновление:

Я только что загрузил исходный код статьи. Если вы откроете EXEDUMP.CPP и посмотри DumpImportsSection он должен иметь код, который вам потребуется.


Это невозможно определить. По крайней мере, без большой работы. Любой двоичный файл может вызвать LoadLibrary для загрузки DLL. Даже если бы вы сканировали код для всех вызовов LoadLibrary, вам пришлось бы определить, какие строки используются для идентификации библиотеки. Отслеживание того, где в динамической памяти была помещена строка, будет сложнее, чем вы хотите справиться.


76 строк, чтобы сделать это на основе pedump код (не забудьте добавить Imagehlp.lib as dependancy):

#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;
}

в двух словах, вам нужно сканировать файл PE раздел импорта для каждой DLL, используемой исполняемым файлом. Затем рекурсивно найдите и сканируйте каждую dll, пока не найдете все зависимости.

конечно, приложения могут использовать семейство функций LoadLibrary для требуемых или дополнительных функций. Это не будет обнаружено с помощью этого метода.


Зависимость Walker можно сделать это с помощью меню профиля, если у вас есть целевой исполняемый файл. Просто загрузите исполняемый файл, скажите ему начать профилирование, и он перечислит все модули, загруженные во время выполнения программы.

зависимость Walker FAQ (первый вопрос ...)


Как насчет DLL, которую вы можете вызвать, чтобы вычислить всю эту информацию для вас и передать ответ в виде массива CStrings?

PE формат DLL можем сделать это для вас. Поставляется с исходным кодом, без ограничений GPL. PE File Explorer-это приложение GUI, которое использует DLL, также поставляемое с источником (без GPL).


конечно, это возможно и легко ! Это даже Win32 FAQ для возрастов на Win32 api Group

=> несколько строк кода с DBAPIs