C++ 如何找到导出的函数';64位DLL中的地址?
我正在分析32位和64位DLL。我想知道导出函数的地址是什么。我已经处理了32位DLL,但同样的代码不适用于64位模块C++ 如何找到导出的函数';64位DLL中的地址?,c++,windows,dll,32bit-64bit,reverse-engineering,C++,Windows,Dll,32bit 64bit,Reverse Engineering,我正在分析32位和64位DLL。我想知道导出函数的地址是什么。我已经处理了32位DLL,但同样的代码不适用于64位模块 DWORD address = (*module)->getImageBaseAddress(); DWORD headerAddress = address + ((PIMAGE_DOS_HEADER)address)->e_lfanew; PIMAGE_NT_HEADERS header = (PIMAGE_NT_HEADERS)head
DWORD address = (*module)->getImageBaseAddress();
DWORD headerAddress = address + ((PIMAGE_DOS_HEADER)address)->e_lfanew;
PIMAGE_NT_HEADERS header = (PIMAGE_NT_HEADERS)headerAddress;
PIMAGE_EXPORT_DIRECTORY exports = (PIMAGE_EXPORT_DIRECTORY)(address + header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PVOID names = (BYTE *)address + exports->AddressOfNames;
PVOID moduleFunctions = (BYTE *)address + exports->AddressOfFunctions;
std::cout << "Characteristics: " << exports->Characteristics << endl;
std::cout << "TimeDateStamp: " << exports->TimeDateStamp << endl;
std::cout << "Major version: " << exports->MajorVersion << endl;
std::cout << "Minor version: " << exports->MinorVersion << endl;
std::cout << "Name: " << exports->Name << endl;
std::cout << "Base: " << exports->Base << endl;
std::cout << "Number of fun: " << exports->NumberOfFunctions << endl;
std::cout << "Number of names: " << exports->NumberOfNames << endl;
for (int i = 0; i < exports->NumberOfFunctions; i++) {
std::cout << std::string((char*)((BYTE *)address + ((DWORD *)names)[i])) << " @ " << ((DWORD *)moduleFunctions)[i] << endl;
}
DWORD地址=(*模块)->getImageBaseAddress();
DWORD headerAddress=地址+((PIMAGE\U DOS\U HEADER)地址)->e\U lfanew;
PIMAGE\U NT\U HEADERS header=(PIMAGE\U NT\U HEADERS)headerAddress;
PIMAGE\u EXPORT\u DIRECTORY exports=(PIMAGE\u EXPORT\u DIRECTORY)(地址+标题->可选标题.DataDirectory[IMAGE\u DIRECTORY\u ENTRY\u EXPORT].VirtualAddress);
PVOID名称=(字节*)地址+导出->地址名称;
PVOID moduleFunctions=(字节*)地址+导出->地址函数;
std::cout如果是64位二进制文件,则可选头
结构的大小不同。请参阅官方参考资料
您需要在可选标题(第一个字段)中键入“幻数”,以确定要使用的结构格式
编辑:添加显示选择正确标题格式的代码段:
char* address = (*module)->getImageBaseAddress();
char* headerAddress = address + ((PIMAGE_DOS_HEADER)address)->e_lfanew;
PIMAGE_NT_HEADERS32 header32 = (PIMAGE_NT_HEADERS32)headerAddress;
PIMAGE_NT_HEADERS64 header64 = (PIMAGE_NT_HEADERS64)headerAddress;
PIMAGE_EXPORT_DIRECTORY exports = NULL;
if (header32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) // PE32
exports = (PIMAGE_EXPORT_DIRECTORY)(address + header32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
else if (header32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) // PE32+
exports = (PIMAGE_EXPORT_DIRECTORY)(address + header64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
else
return 0;
还请注意,如果您试图从文件手动加载的图像(例如,文件的原始映射)执行此操作,则需要通过在部分列表中查找内存地址来识别文件指针位置,从而将RVA转换为文件偏移量。64位代码中的指针不是32位。我的意思是DWORD不应该工作。图像标题不再准确。今天还有图像头64。使用IMAGE\u FILE\u HEADER.Machine了解您得到的是哪一个。等等。你能给我看一下带有图像头64的代码应该是什么样子吗?如果我简单地用64位的结构替换32位的结构,我不会得到期望的结果。那么在你看来,64位DLL的代码与IMAGE\u NT\u HEADERS64的外观如何?我写了一些,但它仍然不能正常工作。PIMAGE_NT_HEADERS是PIMAGE_NT_HEADERS 32或PIMAGE_NT_HEADERS 64的类型定义,具体取决于是否定义了WIN64。那么这些有什么必要呢?@jhofman0x因为你不一定要获取关于你自己形象的信息。上面的代码允许您分析32位或64位头,无论您如何构建。@SilverbackNet谢谢,这很有意义。