pefile写入PE文件报Errno 22错误 仅共享盘宿主机器可复现
问题根因
- 核心是Windows SMB共享的文件锁机制与
pefile库的文件句柄管理逻辑冲突导致的:pefile.PE(文件名)初始化时会以默认共享模式(仅允许其他读操作)打开目标文件,老版本pefile加载完成后不会主动释放该文件句柄- 本地磁盘允许同一进程内对同一个文件同时持有读+写句柄,所以本地运行正常;但SMB共享的文件锁由服务端(你提到的Windows Server 2016)管控,会直接拒绝同一进程持有的读句柄未释放时再开写句柄的请求,所以触发
Errno 22错误 - 你单独测试的写入代码仅打开一次文件,不存在句柄冲突,所以运行正常
可行解决方案
方案1:用内存字节流加载PE(最通用)
加载PE时先把文件内容读入内存再传给pefile,全程不持有原文件句柄,完全规避锁冲突:
import sys import pefile # 先读取文件内容到内存,读完立刻关闭文件句柄 with open(sys.argv[1], 'rb') as f: pe_bytes = f.read() pe = pefile.PE(data=pe_bytes) # 你的PE修改逻辑写在这里 pe.write(sys.argv[1]) # Python3请用print("Finished!") print "Finished!"
方案2:加载完成后主动释放PE对象的文件句柄
pefile的close()方法只会关闭内部持有的文件句柄,已经解析到内存的PE结构不会丢失,不影响后续修改和写入:
import sys import pefile pe = pefile.PE(sys.argv[1]) # 主动释放原文件句柄 pe.close() # 你的PE修改逻辑写在这里 pe.write(sys.argv[1]) print "Finished!"
方案3:先写临时文件再替换原文件(最稳妥)
避免写入过程中断损坏原文件,同时也能规避锁冲突:
import sys import os import pefile import tempfile pe = pefile.PE(sys.argv[1]) # 你的PE修改逻辑写在这里 # 在同目录下生成临时文件写入 temp_file = tempfile.mktemp(dir=os.path.dirname(sys.argv[1])) pe.write(temp_file) # 原子替换原文件 os.replace(temp_file, sys.argv[1]) print "Finished!"
内容的提问来源于stack exchange,提问作者craker
相关产品推荐
相关产品推荐

