You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++读取PE文件NT头时触发STATUS_ACCESS_VIOLATION异常怎么解决?

问题根因及修复方案

1. 文件大小计算逻辑错误(核心原因)

std::ifstream::seekg 传入参数错误,你当前的写法没有正确定位到文件末尾:

// 错误写法
fichier.seekg(std::ios::end);
auto length = fichier.tellg();
fichier.seekg(std::ios::beg);

seekg 带起始位置的重载需要传入两个参数:偏移量、参考位置,正确写法如下:

// 正确写法
fichier.seekg(0, std::ios::end);
auto length = fichier.tellg();
fichier.seekg(0, std::ios::beg);

你原来的写法只会把文件指针定位到偏移量为std::ios::end枚举值(通常为2)的位置,拿到的length不是真实的文件大小,后续分配的缓冲区大小、读取的文件内容全部错误,拿到的DOS头、e_lfanew都是垃圾值,最终计算出来的ntHeader指针越界触发访问异常。

2. 缺少错误分支的终止逻辑

你校验DOS头魔数失败后仅打印日志,没有终止后续逻辑:

// 错误写法:校验失败后继续执行
if (dosHeader->e_magic != 0x5A4D)std::cout << "[23] Getting the dosHeader failed" << std::endl;

如果读取到的文件内容不是合法PE,DOS头魔数不匹配,dosHeader->e_lfanew就是无效的随机值,后续计算的ntHeader必然是非法地址,需要在校验失败后直接终止流程:

// 正确写法:校验失败后直接返回
if (dosHeader->e_magic != 0x5A4D) {
    std::cout << "[23] Getting the dosHeader failed" << std::endl;
    delete[] pData;
    return -1;
}

3. 缺少偏移合法性校验

拿到e_lfanew后需要校验偏移是否在缓冲区范围内,避免越界访问:

if (dosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS) > static_cast<uintptr_t>(length)) {
    std::cout << "Invalid e_lfanew offset" << std::endl;
    delete[] pData;
    return -1;
}

4. 缺少文件操作结果校验

你没有校验文件打开、读取是否成功,如果文件路径错误、权限不足导致读取失败,后续的所有指针操作都是非法的,需要补充校验:

fichier.open(exeFile, std::ios::binary);
if (!fichier.is_open()) {
    std::cout << "Failed to open exe file" << std::endl;
    return -1;
}
// ... 读取文件后校验
if (!fichier) {
    std::cout << "Failed to read exe file" << std::endl;
    delete[] pData;
    fichier.close();
    return -1;
}

内容的提问来源于stack exchange,提问作者Meiziro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 17:48:03