C# UEFI固件文件解析 C#如何读取和分析UEFI应用程序或驱动文件

星降

星降

2026-03-31

622人浏览

原创

uefi pe32+ 文件头识别需依次验证:mz签名(0x4d5a)、pe签名(0x00004550)、可选头魔数0x20b、machine字段(x64为0x8664等);节表起始位置= dos头偏移+136,节数取自coff头numberofsections;eat目录位于数据目录第15项(索引14),签名须为"$eat"(0x54414524)。

c# uefi固件文件解析 c#如何读取和分析uefi应用程序或驱动文件

UEFI PE32+ 文件头怎么识别

不是所有以 .efi 结尾的文件都是合法 UEFI 映像;C# 里直接用 File.ReadAllBytes 读出来,第一件事是确认它是否真有 UEFI 兼容的 PE 结构。关键看 DOS 头后的 PE 签名和可选头魔数。

常见错误现象:System.BadImageFormatException 或解析出错后字段全为 0 —— 很可能跳过了 DOS stub、没校验 "PE\0\0" 签名,或误把 32 位 PE(0x10b)当 PE32+(0x20b)处理。

  • 先读前 64 字节,检查 bytes[0] == 0x4d && bytes[1] == 0x5a(即 "MZ"
  • 再从 bytes[60] 取 DWORD 偏移,读该位置的 4 字节是否等于 0x00004550(即 "PE\0\0"
  • 接着跳过 COFF 头(20 字节),读可选头前 2 字节:必须是 0x0b02(小端,对应 0x20b)才是 PE32+
  • UEFI 规范要求 Machine 字段为 0x8664(x64)或 0x014c(x86),ARM64 是 0xaa64;不匹配就不是目标平台固件

如何安全提取 EFI_IMAGE_NT_HEADERS64 和节表

C# 没有内置 UEFI PE 解析器,靠手动偏移计算容易越界或对齐错误。Windows SDK 的 IMAGE_NT_HEADERS64 结构在 .NET 中不能直接 Marshal.PtrToStructure,因为 UEFI 映像常含非标准节名、空节或重叠虚拟地址(VMA)。

使用场景:你想读取 `.text` 节原始字节做反汇编,或找 `.reloc` 节验证是否支持基址重定位 —— 这些都依赖正确解析节表起始位置和数量。

  • 可选头大小固定为 112 字节(PE32+),节表紧跟其后,起始偏移 = DOS 头偏移 + 4 + 20 + 112
  • 节表项大小是 40 字节,但实际节数要从 COFF 头的 NumberOfSections 字段(偏移 2 + 2 字节处)读,不能硬写循环 10 次
  • 每个节的 Name 是 8 字节 ANSI 字符串,需用 Encoding.ASCII.GetString(bytes, offset, 8).TrimEnd('\0'),别用 UTF8 否则乱码
  • 注意 VirtualAddressSizeOfRawData 可能为 0 —— 表示该节只存在于内存中(如 .bss),磁盘上无对应数据

为什么用 BinaryReaderSpan<byte></byte> 更稳妥

UEFI 映像里大量字段是 little-endian,且存在“按文件对齐(FileAlignment)”和“按内存对齐(SectionAlignment)”两套规则。用 Span<byte></byte> 手动 BitConverter.ToInt32(data.Slice(i, 4)) 容易忽略字节序翻转,或因未校验边界导致 IndexOutOfRangeException

C函数速查手册(CHM版)
C函数速查手册(CHM版)

C函数速查手册(CHM版)

下载

性能影响不大:单个 EFI 文件通常几 KB 到几百 KB,BinaryReader 的封装开销可忽略;但能避免 90% 的偏移计算失误。

  • 构造时用 new BinaryReader(new MemoryStream(bytes), Encoding.ASCII, leaveOpen: true)
  • 读 DWORD 用 reader.ReadUInt32()(自动 little-endian),别用 ToInt32
  • 读字符串前先 reader.BaseStream.Position 记录起点,读完 8 字节后手动 Seek 回去,避免破坏后续读取流位置
  • 遇到 SizeOfOptionalHeader == 0 或节表超出文件长度时,立即返回错误,不要尝试“尽力而为”解析

EFI 特有结构:如何定位和验证 IMAGE_DATA_DIRECTORY 中的 IMAGE_DIRECTORY_ENTRY_EAT

UEFI 驱动依赖导出表(Export Address Table)暴露入口点(如 UefiMain),但它不在标准 PE 的 IMAGE_DIRECTORY_ENTRY_EXPORT(索引 0),而是在 UEFI 扩展目录项 IMAGE_DIRECTORY_ENTRY_EAT(索引 14)。漏掉这点,就找不到驱动主函数地址。

容易踩的坑:直接查 Windows 文档里的目录索引表,会发现没有 14 这一项 —— 这是 EDK2 自定义扩展,仅在 UEFI 映像中有效。

  • PE32+ 可选头中,数据目录从偏移 120 开始,共 16 项,每项 8 字节(RVA + Size)
  • 第 15 项(索引 14)即 IMAGE_DIRECTORY_ENTRY_EAT,若 RVA != 0Size >= 24,才认为存在有效 EAT
  • EAT 结构头 4 字节是签名 0x54414524"$EAT"),紧接着是版本号(通常为 1)、导出函数数、名称 RVA 数组起始 RVA
  • 别假设 EAT 一定在某个节里 —— 它可能被打包进 .data 或自定义节(如 ".sdata"),需遍历节表匹配 RVA 范围

复杂点在于:不同 EDK2 版本生成的 EAT 格式略有差异,有些省略名称数组,有些把函数地址表放文件末尾。没看到 "$EAT" 签名,不等于没有导出 —— 也可能是精简版 UEFI 应用,靠硬编码入口偏移(AddressOfEntryPoint)启动。

相关文章

驱动精灵
驱动精灵

驱动精灵基于驱动之家十余年的专业数据积累,驱动支持度高,已经为数亿用户解决了各种电脑驱动问题、系统故障,是目前有效的驱动软件,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

c#

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c#是什么意思
c#是什么意思

C#是一种通用的面向对象编程语言,它在.NET框架上运行,可用于开发各种类型的应用程序。本专题为大家提供c#相关的各种文章、以及下载和课程。

2023.08.08

526

5

什么是c#
什么是c#

C#(读作C Sharp)是一种现代的、通用的、面向对象的编程语言。它由微软公司开发,于2000年首次发布,主要用于开发Windows桌面应用程序、Web应用程序、移动应用程序以及游戏开发等领域。C#是一种类型安全和托管的编程语言,它结合了C++的强大性能和C语言的简单易学特点,并引入了许多新的特性和概念,如委托、属性、泛型和异步编程等,以提高开发效率和代码可维护性。

2023.08.31

1132

3

C#中base关键字的用法
C#中base关键字的用法

在C#中,base关键字用于访问当前类的基类成员,这包括基类的字段、属性、方法、构造函数、索引器以及事件。想了解更多C#的相关内容,可以阅读本专题下面的文章。

2024.03.13

556

8

C#Task用法
C#Task用法

Task在C#中是用于表示异步操作的对象,它位于System.Threading.Tasks命名空间中。想了解更多C#中各种用法的相关内容,可以阅读本专题下面的文章。

2024.03.14

1028

11

C# 并发与异步编程
C# 并发与异步编程

本专题系统讲解 C# 异步编程与并发控制,重点介绍 async 和 await 关键字、Task 类、线程池管理、并发数据结构、死锁与线程安全问题。通过多个实战项目,帮助学习者掌握 如何在 C# 中编写高效的异步代码,提升应用的并发性能与响应速度。

2026.02.03

147

18

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

2026.02.06

202

20

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

2026.03.11

526

24

C# Unity游戏开发与ECS架构实践
C# Unity游戏开发与ECS架构实践

本专题聚焦 C# 在 Unity 游戏开发中的应用,系统讲解 ECS(Entity-Component-System)架构设计、游戏对象管理、性能优化与内存控制策略。通过实际游戏案例,帮助开发者构建高性能、结构清晰的游戏系统,提高游戏开发效率与运行性能。

2026.04.13

136

20

string转int
string转int

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

2023.08.02

2839

3

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
RabbitMQ 教程手册
RabbitMQ 教程手册

共0课时 | 0人学习

Linux man-pages 项目
Linux man-pages 项目

共0课时 | 0人学习

C# 教程
C# 教程

共94课时 | 20.1万人学习