我试图解析PE文件,将其加载到内存中,并将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可以。我必须减小此偏移量才能获得真正正确的签名,这是我做错了什么?
我在64位Windows 8.1上使用VS2013 RC,但检查了是否已设置_WIN32定义。对于32位和64位exe文件,都会发生此错误。
最佳答案
file.open(m_filepath, std::ios::in | std::ios::binary);
如果您未以二进制模式打开,则在处理输入时可以通过std::fstream添加或删除其他字符。
关于c++ - 如何获得PE文件签名偏移量?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19503448/