最近需=编写检查某个PE文件(exe或者dll)依赖的dll有哪些, 于是查找资料尝试编写了这段代码, 经测试, 在x64或者x86环境下均可获取x64和x86的PE文件的dll列表.
#include <windows.h>
#include <dbghelp.h>
#include <tchar.h>
#include <vector>
#include <string>
#pragma comment(lib, "dbghelp.lib")
//获取指定模块导入的dll列表
std::vector<std::string> GetDependsDlls(LPCTSTR filePath)
{
std::vector<std::string> dllList;
HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE hFileMap = NULL;
LPVOID lpbaseAddress = NULL;
PIMAGE_NT_HEADERS pNtHeaders = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = NULL;
DWORD dwSize = 0;
hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
goto L_Cleanup;
}
hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (NULL == hFileMap)
{
goto L_Cleanup;
}
lpbaseAddress = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
if (NULL == lpbaseAddress)
{
goto L_Cleanup;
}
pNtHeaders = ImageNtHeader(lpbaseAddress);
if (NULL == pNtHeaders)
{
goto L_Cleanup;
}
pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToDataEx(lpbaseAddress, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &dwSize, NULL);
if (NULL == pImportDesc)
{
goto L_Cleanup;
}
for (int i = 0; 0 != pImportDesc[i].Name; ++i)
{
LPCSTR szDllName = (LPCSTR)ImageRvaToVa(pNtHeaders, lpbaseAddress, pImportDesc[i].Name, NULL);
dllList.push_back(szDllName);
}
L_Cleanup:
if (NULL != lpbaseAddress)
{
UnmapViewOfFile(lpbaseAddress);
}
if (NULL != hFileMap)
{
CloseHandle(hFileMap);
}
if (INVALID_HANDLE_VALUE != hFile)
{
CloseHandle(hFile);
}
return dllList;
}
main.cpp
#include <iostream>
int main()
{
std::vector<std::string> dllList;
printf("szDllName: %s\n", R"(D:\games\7 Billion Humans.exe)");
dllList = GetDependsDlls(_T(R"(D:\games\7 Billion Humans.exe)"));
for (auto item : dllList)
{
std::cout << item << std::endl;
}
std::cout << std::endl;
printf("szDllName: %s\n", R"(D:\games\megaman11.exe)");
dllList = GetDependsDlls(_T(R"(D:\games\megaman11.exe)"));
for (auto item : dllList)
{
std::cout << item << std::endl;
}
std::cout << std::endl;
return 0;
}