我有一个包含一些导出函数的 DLL,我想以编程方式将它们表示为包含它们在当前进程中的名称和函数地址的对象向量。我目前使用的是导出函数名称的硬编码列表,但每次修改 DLL 时都必须对其进行修改。我希望它可以简单地遍历导出的函数,而不必首先被告知函数名称是什么。 Visual Studio 的
dumpbin /exports
列举了导出的 dll 函数,我如何在 C++ 中完成相同的功能?
我目前的功能是这样的:
std::vector<DllFunc> DllFunc::vector = std::vector<DllFunc>();
HRESULT DllFunc::initialize(DWORD procId, const std::wstring& dllPath) {
const std::vector<std::string> moduleNames = { "initProcInfo", "querySuccess", "eject" };
HMODULE dllHandle = LoadLibraryW(dllPath.c_str());
for (std::string moduleName : moduleNames) {
LPVOID modulePtr = GetProcAddress(dllHandle, moduleName.c_str());
vector.push_back(DllFunc(moduleName, processModulePtr));
}
FreeLibrary(injectorDllHandle);
return S_OK;
}
一些评论提到了 PE 格式和 Imagehlp 库,所以我在研究了这些之后将这个函数放在一起
HRESULT DllFunc::initialize(DWORD procId, const std::wstring& dllPath) {
HMODULE dllHandle = LoadLibraryW(dllPath.c_str());
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)(dllHandle);
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((LPBYTE)(dllHandle)+dosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER optionalHeader = (PIMAGE_OPTIONAL_HEADER) &(ntHeaders->OptionalHeader);
PIMAGE_DATA_DIRECTORY dataDirectory = &(optionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((LPBYTE)(dllHandle )+dataDirectory->VirtualAddress);
LPDWORD addressOfNames = (LPDWORD)((LPBYTE)(dllHandle)+exportDirectory->AddressOfNames);
LPWORD addressOfNameOrdinals = (LPWORD)((LPBYTE)(dllHandle)+exportDirectory->AddressOfNameOrdinals);
LPDWORD addressOfFunctions = (LPDWORD)((LPBYTE)(dllHandle)+exportDirectory->AddressOfFunctions);
vector.reserve(exportDirectory->NumberOfNames);
for (unsigned int i = 0; i < exportDirectory->NumberOfNames; i++) {
std::string name = (char*)((LPBYTE)(dllHandle)+addressOfNames[i]);
WORD ordinal = addressOfNameOrdinals[i];
PDWORD address = (PDWORD)((LPBYTE)(dllHandle)+addressOfFunctions[ordinal]);
vector.push_back(DllFunc(name, absoluteAddress));
}
FreeLibrary(dllHandle);
return S_OK;
}