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