Как программно определить зависимости DLL от исполняемых файлов Windows?
Как определить, какая DLL-библиотека зависит от использования программных методов?
Чтобы быть ясным, я не пытаюсь определить зависимости DLL от исполняемого exec, но от любого произвольного exec (для которого может отсутствовать требуемая DLL). Я ищу решение для реализации в приложении C/С++. Это то, что должно выполняться моим приложением во время выполнения и не может быть выполнено сторонним приложением (например, зависит).
Ответы
Ответ 1
Взгляните на IMAGE_LOAD_FUNCTION
API. Он вернет указатель на структуру LOADED_IMAGE
, которую вы можете использовать для доступа к различным разделам PE файла.
Вы можете найти некоторые статьи, описывающие, как структуры размещаются здесь, и . Вы можете загрузить исходный код для статей здесь.
Я думаю, что это должно дать вам все, что вам нужно.
Update:
Я только что загрузил исходный код для статьи. Если вы откроете EXEDUMP.CPP
и взгляните на DumpImportsSection
, он должен иметь код, который вам нужен.
Ответ 2
Это невозможно определить. По крайней мере, не без большой работы. Любой двоичный файл может вызвать LoadLibrary для загрузки DLL. Даже если вы должны были сканировать код для всех вызовов в LoadLibrary, вам нужно будет определить, какие строки использовались для идентификации библиотеки. Отслеживание там, где в динамической памяти помещена строка, будет сложнее, чем вы хотите решить.
Ответ 3
76 строк для этого на основе pedump code (не забудьте добавить 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 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;
}
Ответ 4
В двух словах вам нужно отсканировать файл импорта файла PE для каждой DLL, используемой исполняемым файлом. Затем рекурсивно найдите и сканируйте каждую dll, пока не найдете все зависимости.
Конечно, приложения могут использовать семейство функций LoadLibrary для требуемых или дополнительных функций. Это не будет обнаружено с помощью этого метода.
Ответ 5
Dependency Walker может сделать это, используя меню профиля, если у вас есть целевой исполняемый файл. Просто загрузите исполняемый файл, скажите ему, чтобы начать профилирование, и он перечислит все модули, загруженные во время выполнения программы.
Часто задаваемые вопросы по Walker (первый вопрос...)
Ответ 6
Как насчет DLL, которую вы можете вызвать, чтобы рассчитать всю эту информацию для вас и передать ответ в виде массива CStrings?
PE Format DLL может сделать это за вас. Поставляется с исходным кодом, без ограничений GPL. PE File Explorer - это графическое приложение, использующее DLL, также поставляемое с источником (без GPL).
Ответ 7
Конечно, это возможно и легко!
Это даже часто задаваемые вопросы по Win32 на Win32 api Group
= > несколько строк кода с помощью DBAPI