您的位置:首页 >C#读取EXE/DLL文件头结构解析
发布于2026-02-09 阅读(0)
扫一扫,手机访问
必须先读取DOS头获取e_lfanew值定位PE签名,再根据Magic字段区分32/64位解析可选头,节表数量由NumberOfSections决定,结构体需[StructLayout(Sequential, Pack=1)]且字段类型严格匹配,RVA需转文件偏移。

System.IO.FileStream 读取 PE 头前必须跳过 DOS 头PE 文件开头是 DOS 头(IMAGE_DOS_HEADER),它占 64 字节,但真正关键的 PE 签名("PE\0\0")在偏移 0x3C 处的 e_lfanew 字段指向的位置。直接从文件头开始解析会失败。
e_lfanew 字段(4 字节小端整数)0x00004550(即 "PE\0\0"),说明不是合法 PE 文件e_lfanew 指向的位置开始,不是固定偏移 0x40IMAGE_FILE_HEADER 和 IMAGE_OPTIONAL_HEADER 要区分 32/64 位PE 文件可选头有两种:32 位用 IMAGE_OPTIONAL_HEADER32(共 224 字节),64 位用 IMAGE_OPTIONAL_HEADER64(共 240 字节)。仅靠文件扩展名(.exe/.dll)无法判断,必须读 IMAGE_FILE_HEADER.Machine 和可选头中的 Magic 字段。
IMAGE_FILE_HEADER.Machine 是 0x014C(I386)或 0x8664(AMD64)等,但不决定可选头大小IMAGE_FILE_HEADER 后的 Magic 值:0x010B 表示 32 位,0x020B 表示 64 位AddressOfEntryPoint 解析成错误地址)NumberOfSections 决定,不能硬写死节表紧跟在可选头之后,每个节头固定 40 字节(IMAGE_SECTION_HEADER),但节数量由 IMAGE_FILE_HEADER.NumberOfSections 给出——这个值通常为 3~6,但某些加壳或手工构造的 PE 可能只有 1 节或多达 10+ 节。
NumberOfSections * 40 计算节表总长度,再用 FileStream.Seek() 跳转到对应位置".text\0\0\0"),需用 Encoding.ASCII.GetString() 并截断 \0,不能直接 ToString()Marshal.PtrToStructure 解析结构体时注意字节对齐和字段顺序C# 默认结构体布局是 Auto,会重排字段顺序并插入填充,而 PE 结构体是 C 风格的 Sequential 布局、1 字节对齐。不显式声明,解析结果全是错的。
[StructLayout(LayoutKind.Sequential, Pack = 1)]WORD → UInt16,DWORD → UInt32,PVOID 在 64 位 PE 中是 UInt64,不是 IntPtrstring 直接映射字符数组;对 IMAGE_DOS_HEADER.e_lfanew 这种 4 字节字段,必须用 UInt32,不能用 Int32(符号扩展会污染高位)最易被忽略的是:PE 头里大量字段是相对虚拟地址(RVA),不是文件偏移。比如 OptionalHeader.AddressOfEntryPoint 是 RVA,要查节表才能换算成实际文件位置——这个转换逻辑一旦写错,整个反汇编或资源提取就全偏了。
下一篇:腾讯会议预定方法及步骤详解
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9