我试图parsingPE文件,我将它加载到内存中,我将WinNT结构指针设置为适当的地址。 但是,我不能做愚蠢的检查PE \ 0 \ 0签名,因为我有错误的偏移量从DOS头(一个字节太多)。 所以当我检查IMAGE_NT_HEADERS.Signature时,我收到从'E'开始的4个字节。
#define SHOW_VAR(x) std::cout << #x << " = " << x << std::endl #define SHOW_HEX(x) std::cout << std::showbase << std::hex << #x << " = " << x << std::endl; std::cout << std::dec uintmax_t fileSize = boost::filesystem::file_size(m_filePath); m_image.reset(new char[fileSize]); boost::filesystem::ifstream file; file.open(m_filePath, std::ios::in); file.read(m_image.get(), fileSize); file.close(); m_DOSHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(m_image.get()); // --m_DOSHeader->e_lfanew; <---- THIS SOLVES THE PROBLEM BUT WHY? m_NTHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(m_image.get() + m_DOSHeader->e_lfanew); // DEBUG SHOW_HEX(m_DOSHeader->e_lfanew); for(int i = m_DOSHeader->e_lfanew - 5; i < m_DOSHeader->e_lfanew + 5; ++i) { if(i == m_DOSHeader->e_lfanew) std::cout << "---> "; SHOW_HEX(m_image[i]); } // check if MZ if(m_DOSHeader->e_magic != IMAGE_DOS_SIGNATURE) throw std::runtime_error("[PEFile] MZ signature not found"); // check if PE00 SHOW_VAR((char)m_NTHeaders->Signature); if(m_NTHeaders->Signature != IMAGE_NT_SIGNATURE) throw std::runtime_error("[PEFile] PE00 signature not found");
DEBUG代码片段的结果是:
m_DOSHeader->e_lfanew = 0xf0 m_image[i] = m_image[i] = m_image[i] = m_image[i] = m_image[i] = P ---> m_image[i] = E m_image[i] = m_image[i] = m_image[i] = L m_image[i] = (char)m_NTHeaders->Signature = E [ERROR] [PEFile] PE00 signature not found
我用pedump.me和m_DOSHeader-> e_lfanew = 0xf0检查了一下。 我做错了什么,我不得不减less这个抵消得到真正的签名?
我在64位Windows 8.1上使用VS2013 RC,但我检查了我已经设置_WIN32定义。 这个错误发生在32位和64位的exe文件中。
file.open(m_filepath, std::ios::in | std::ios::binary);
如果你没有以二进制模式打开,那么在处理输入时,可以通过std :: fstream添加或删除其他字符。