pe头部修改必须先解除文件映射保护,正确方式是用createfile以generic_read|generic_write打开,再通过createfilemapping和mapviewoffile获得可写视图,否则writefile易报error_access_denied;修改需同步更新校验和、重定位表、节对齐及数字签名,否则导致加载失败或安全拦截。

PE头部修改必须先解除文件映射保护
直接用fstream打开EXE并写入PE头部大概率失败——Windows会锁住正在运行或已加载的模块,且大多数PE文件默认以只读方式映射。真正可行的方式是:先用CreateFile以GENERIC_READ | GENERIC_WRITE和FILE_SHARE_READ打开,再用CreateFileMapping + MapViewOfFile获得可写视图,否则WriteFile可能报错ERROR_ACCESS_DENIED或写入无效。
- 务必检查
GetLastError()返回值,常见错误包括ERROR_SHARING_VIOLATION(其他进程正使用该文件)和ERROR_INVALID_HANDLE(映射失败但没检查返回值) - 不要用
std::ofstream直接覆盖原文件——这会破坏重定位表、校验和、签名等依赖原始布局的结构 - 修改前建议先调用
CheckSumMappedFile验证原始校验和是否有效,避免误改导致文件无法加载
修改IMAGE_OPTIONAL_HEADER::AddressOfEntryPoint要同步更新重定位
单纯改AddressOfEntryPoint字段(比如跳转到自定义初始化代码)会导致程序启动后崩溃——因为新入口地址若不在原始基址范围内,且DLL未启用ASLR,系统加载器不会自动重定位该地址。你得手动计算RVA偏移,并确保目标代码位于合法节区内。
- 先用
IMAGE_NT_HEADERS定位OptionalHeader,再通过NumberOfRvaAndSizes确认IMAGE_DIRECTORY_ENTRY_BASERELOC是否存在 - 若存在重定位表,修改入口点后需调用
ApplyBaseRelocation逻辑(或至少清空ImageBase并设为0),否则加载器可能忽略你的改动 - 入口点地址必须是节内对齐后的RVA(不是RAW offset),可用
VirtualAddress字段查节头确认范围
添加新节时SizeOfImage和SizeOfHeaders必须重新对齐
新增一个节区(如.injected)后,SizeOfImage不能简单加节大小——它必须按OptionalHeader::SectionAlignment向上取整;同理,SizeOfHeaders要按FileAlignment对齐,否则加载器拒绝加载,报错STATUS_INVALID_IMAGE_FORMAT。
- 计算新
SizeOfImage:取最后一个节的VirtualAddress + VirtualSize,再向上对齐到SectionAlignment -
SizeOfHeaders=sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS) + NumberOfSections × sizeof(IMAGE_SECTION_HEADER),结果按FileAlignment对齐 - 新增节的
PointerToRawData必须大于原SizeOfHeaders,且与FileAlignment对齐,否则磁盘文件结构损坏
签名和校验和被破坏后程序可能无法运行或触发SmartScreen拦截
任何对PE头部或节数据的修改都会使嵌入式数字签名失效,Windows会拒绝加载带有效签名但内容不匹配的二进制文件;同时CheckSum字段若不更新,某些安全软件或企业策略会直接拦截。
- 调用
CheckSumMappedFile更新校验和(注意它返回的是DWORD校验值,需写回OptionalHeader::CheckSum) - 签名无法“修复”,只能重新签名——用
signtool sign /fd SHA256 /tr http://timestamp.digicert.com ...,否则UAC弹窗可能显示“未知发布者” - 修改后务必用
dumpbin /headers核对optional header values中checksum和image base是否符合预期
PE头部操作本质是绕过加载器约束的底层动作,稍有对齐偏差或字段误算就会让文件变成不可执行的垃圾数据——最稳妥的做法永远是:改完立刻用LoadLibrary尝试加载测试,而不是等部署时才发现ERROR_BAD_EXE_FORMAT。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











