0

0

C#解析Windows PE文件头 C#如何读取EXE或DLL的结构信息

幻夢星雲

幻夢星雲

发布时间:2026-03-15 09:46:31

|

821人浏览过

|

来源于php中文网

原创

必须先读取DOS头获取e_lfanew值定位PE签名,再根据Magic字段区分32/64位解析可选头,节表数量由NumberOfSections决定,结构体需[StructLayout(Sequential, Pack=1)]且字段类型严格匹配,RVA需转文件偏移。

c#解析windows pe文件头 c#如何读取exe或dll的结构信息

System.IO.FileStream 读取 PE 头前必须跳过 DOS 头

PE 文件开头是 DOS 头(IMAGE_DOS_HEADER),它占 64 字节,但真正关键的 PE 签名("PE\0\0")在偏移 0x3C 处的 e_lfanew 字段指向的位置。直接从文件头开始解析会失败。

  • 先读取前 64 字节,解析出 e_lfanew 字段(4 字节小端整数)
  • 用该值作为偏移,定位到 PE 签名位置;若此处不是 0x00004550(即 "PE\0\0"),说明不是合法 PE 文件
  • DOS stub(DOS 占位程序)可能很长,但 PE 头永远从 e_lfanew 指向的位置开始,不是固定偏移 0x40

解析 IMAGE_FILE_HEADERIMAGE_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.Machine0x014C(I386)或 0x8664(AMD64)等,但不决定可选头大小
  • 真正决定用哪个可选头的是紧接在 IMAGE_FILE_HEADER 后的 Magic 值:0x010B 表示 32 位,0x020B 表示 64 位
  • 忽略这个判断,硬按 32 位读 64 位文件,会导致后续所有字段错位(比如 AddressOfEntryPoint 解析成错误地址)

节表(Section Headers)数量由 NumberOfSections 决定,不能硬写死

节表紧跟在可选头之后,每个节头固定 40 字节(IMAGE_SECTION_HEADER),但节数量由 IMAGE_FILE_HEADER.NumberOfSections 给出——这个值通常为 3~6,但某些加壳或手工构造的 PE 可能只有 1 节或多达 10+ 节。

小微助手
小微助手

微信推出的一款专注于提升桌面效率的助手型AI工具

下载
  • NumberOfSections * 40 计算节表总长度,再用 FileStream.Seek() 跳转到对应位置
  • 常见错误:假设只有 .text/.rdata/.data 三节,漏读 .reloc 或 .rsrc,导致资源或重定位信息丢失
  • 节名是 8 字节 ASCII(如 ".text\0\0\0"),需用 Encoding.ASCII.GetString() 并截断 \0,不能直接 ToString()

Marshal.PtrToStructure 解析结构体时注意字节对齐和字段顺序

C# 默认结构体布局是 Auto,会重排字段顺序并插入填充,而 PE 结构体是 C 风格的 Sequential 布局、1 字节对齐。不显式声明,解析结果全是错的。

  • 每个结构体必须加 [StructLayout(LayoutKind.Sequential, Pack = 1)]
  • 字段类型要严格匹配:比如 WORDUInt16DWORDUInt32PVOID 在 64 位 PE 中是 UInt64,不是 IntPtr
  • 避免用 string 直接映射字符数组;对 IMAGE_DOS_HEADER.e_lfanew 这种 4 字节字段,必须用 UInt32,不能用 Int32(符号扩展会污染高位)

最易被忽略的是:PE 头里大量字段是相对虚拟地址(RVA),不是文件偏移。比如 OptionalHeader.AddressOfEntryPoint 是 RVA,要查节表才能换算成实际文件位置——这个转换逻辑一旦写错,整个反汇编或资源提取就全偏了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1051

2023.08.02

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

202

2025.07.04

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

202

2025.07.04

常见的编码方式
常见的编码方式

常见的编码方式有ASCII编码、Unicode编码、UTF-8编码、UTF-16编码、GBK编码等。想了解更多编码方式相关内容,可以阅读本专题下面的文章。

649

2023.10.24

a和A对应的ASCII码数值
a和A对应的ASCII码数值

a的ascii码是65,a的ascii码是97;ascii码表中,一个字母的大小写数值相差32,一般知道大写字母的ascii码数值,其对应的小写字母的ascii码数值就算出来了,是大写字母的ascii码数值“+32”。想了解更多相关的内容,可阅读本专题下面的相关文章。

2262

2024.10.24

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1518

2023.07.26

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.4万人学习

C 教程
C 教程

共75课时 | 5.5万人学习

C++教程
C++教程

共115课时 | 22万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号