如何从 DOS headers 访问 PE NT headers?
How to access PE NT headers from DOS headers?
我正在尝试将 .exe PE 文件读入内存并访问 NT headers。我已经可以访问 DOS headers 但无法从中解析 NT headers。
这是我目前的情况:
static constexpr uint16_t DOS_HDR_MAGIC = 0x5A4D; // "MZ"
static constexpr uint32_t NT_HDR_MAGIC = 0x00004550; // "PE\x0\x0"
struct nt_headers_t
{
uint32_t signature;
file_header_t file_header;
optional_header_x64_t optional_header;
};
struct dos_header_t
{
uint16_t e_magic;
uint16_t e_cblp;
uint16_t e_cp;
uint16_t e_crlc;
uint16_t e_cparhdr;
uint16_t e_minalloc;
uint16_t e_maxalloc;
uint16_t e_ss;
uint16_t e_sp;
uint16_t e_csum;
uint16_t e_ip;
uint16_t e_cs;
uint16_t e_lfarlc;
uint16_t e_ovno;
uint16_t e_res[ 4 ];
uint16_t e_oemid;
uint16_t e_oeminfo;
uint16_t e_res2[ 10 ];
uint32_t e_lfanew;
};
int main(void) {
std::ifstream input("./stuff.exe", std::ios::in | std::ios::binary );
input.seekg(0, std::ios::end);
int file_size = input.tellg();
input.seekg(0, std::ios::beg);
std::byte *file = new std::byte[file_size];
input.read((char *)file, file_size);
struct dos_header_t *dos_header = (struct dos_header_t *)file;
assert(dos_header->e_magic == DOS_HDR_MAGIC);
struct nt_headers_t *nt_headers = (struct nt_headers_t *)file + dos_header->e_lfanew;
assert(nt_headers->signature == NT_HDR_MAGIC);
}
e_lfanew
应包含 NT headers 开头的地址。我只是将此值添加到文件开头:(struct nt_headers_t *)file + dos_header->e_lfanew;
我做错了吗?所附图片表示 e_lfanew
包含倒序的 NT headers 偏移量。我应该如何反转它?
I simply add this value to file start: (struct nt_headers_t *)file + dos_header->e_lfanew;
Am I doing that wrong?
是的,但是出于与 PE 无关的“无聊原因”headers:因为您已经完成了转换 在 添加之前,偏移量按 nt_headers_t
的大小缩放。偏移量需要按比例添加,所以先添加,然后再转换。
Attached picture says that e_lfanew contains the NT headers offset in reverse order. How should I reverse it?
它是 little-endian 字节顺序,你可能 运行 little-endian 机器上的代码(现在大多数机器都是这样)所以你不需要做任何事情, 只需读取该值即可正确解释它。
我正在尝试将 .exe PE 文件读入内存并访问 NT headers。我已经可以访问 DOS headers 但无法从中解析 NT headers。
这是我目前的情况:
static constexpr uint16_t DOS_HDR_MAGIC = 0x5A4D; // "MZ"
static constexpr uint32_t NT_HDR_MAGIC = 0x00004550; // "PE\x0\x0"
struct nt_headers_t
{
uint32_t signature;
file_header_t file_header;
optional_header_x64_t optional_header;
};
struct dos_header_t
{
uint16_t e_magic;
uint16_t e_cblp;
uint16_t e_cp;
uint16_t e_crlc;
uint16_t e_cparhdr;
uint16_t e_minalloc;
uint16_t e_maxalloc;
uint16_t e_ss;
uint16_t e_sp;
uint16_t e_csum;
uint16_t e_ip;
uint16_t e_cs;
uint16_t e_lfarlc;
uint16_t e_ovno;
uint16_t e_res[ 4 ];
uint16_t e_oemid;
uint16_t e_oeminfo;
uint16_t e_res2[ 10 ];
uint32_t e_lfanew;
};
int main(void) {
std::ifstream input("./stuff.exe", std::ios::in | std::ios::binary );
input.seekg(0, std::ios::end);
int file_size = input.tellg();
input.seekg(0, std::ios::beg);
std::byte *file = new std::byte[file_size];
input.read((char *)file, file_size);
struct dos_header_t *dos_header = (struct dos_header_t *)file;
assert(dos_header->e_magic == DOS_HDR_MAGIC);
struct nt_headers_t *nt_headers = (struct nt_headers_t *)file + dos_header->e_lfanew;
assert(nt_headers->signature == NT_HDR_MAGIC);
}
e_lfanew
应包含 NT headers 开头的地址。我只是将此值添加到文件开头:(struct nt_headers_t *)file + dos_header->e_lfanew;
我做错了吗?所附图片表示 e_lfanew
包含倒序的 NT headers 偏移量。我应该如何反转它?
I simply add this value to file start:
(struct nt_headers_t *)file + dos_header->e_lfanew;
Am I doing that wrong?
是的,但是出于与 PE 无关的“无聊原因”headers:因为您已经完成了转换 在 添加之前,偏移量按 nt_headers_t
的大小缩放。偏移量需要按比例添加,所以先添加,然后再转换。
Attached picture says that e_lfanew contains the NT headers offset in reverse order. How should I reverse it?
它是 little-endian 字节顺序,你可能 运行 little-endian 机器上的代码(现在大多数机器都是这样)所以你不需要做任何事情, 只需读取该值即可正确解释它。