上一篇博客讲了一个例子关于在一个C 程序里如何动态去load 一个可执行文件,并且让这个文件能够跑起来,代码里有几处是hard code 写的,没有去根据读取的可执行文件类型去分析它。上篇也说了,如果那个例子理解透了,那么对于efi 文件加载和执行理解起来就不成问题了。

这篇博客介绍一下,efi 文件内容。其实不用去看代码,也不用怎么翻spec, 看看下面的几个图片,应该就会很清晰,efi 文件的重定位,装载,执行了。

举个具体例子看一下吧。我这边有一个build 好的efi driver, 文件格式呢是pe32。

先来看看这个driver 是怎么个结构,我们可以用Windows 下的命令dumpbin /ALL xxx.efi > xx.txt

FILE HEADER VALUES
14C machine (x86)
3 number of sections
0 time date stamp
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL

OPTIONAL HEADER VALUES
10B magic # (PE32)
10.00 linker version
4DA0 size of code
4400 size of initialized data
0 size of uninitialized data
240 entry point (00000240)
240 base of code
4FE0 base of data
0 image base (00000000 to 000093DF)
20 section alignment
20 file alignment
0.00 operating system version
0.00 image version
0.00 subsystem version
0 Win32 version
93E0 size of image
240 size of headers
0 checksum
B subsystem (EFI Boot Service Driver)
0 DLL characteristics
0 size of stack reserve
0 size of stack commit
0 size of heap reserve
0 size of heap commit
0 loader flags
10 number of directories
0 [ 0] RVA [size] of Export Directory
0 [ 0] RVA [size] of Import Directory
0 [ 0] RVA [size] of Resource Directory
0 [ 0] RVA [size] of Exception Directory
0 [ 0] RVA [size] of Certificates Directory
8FA0 [ 428] RVA [size] of Base Relocation Directory
0 [ 0] RVA [size] of Debug Directory
0 [ 0] RVA [size] of Architecture Directory
0 [ 0] RVA [size] of Global Pointer Directory
0 [ 0] RVA [size] of Thread Storage Directory
0 [ 0] RVA [size] of Load Configuration Directory
0 [ 0] RVA [size] of Bound Import Directory
0 [ 0] RVA [size] of Import Address Table Directory
0 [ 0] RVA [size] of Delay Import Directory
0 [ 0] RVA [size] of COM Descriptor Directory
0 [ 0] RVA [size] of Reserved Directory

只是截取一部分,大概就这个样子,我们只关心加载和执行,所以其中

  1. entry point
  2. image base
  3. 重定向表

都在option header 里。所以无论我们的build tool 还是core 去分析这个driver 找到option header 就可以把需要的信息提取出来。提取出来,我们image 需要重定向,关于重定向之前也讲过,需要分析重定向表,好吧,看看重定向表的信息。

SECTION HEADER #3.reloc name428 virtual size8FA0 virtual address (00008FA0 to 000093C7)440 size of raw data8FA0 file pointer to raw data (00008FA0 to 000093DF)0 file pointer to relocation table0 file pointer to line numbers0 number of relocations0 number of line numbers
42000040 flagsInitialized DataDiscardableRead OnlyRAW DATA #300008FA0: 00 00 00 00 4C 00 00 00 54 32 6F 32 80 32 85 32  00008FB0: A1 32 B6 33 CC 33 E2 33 F8 33 04 36 2C 36 36 38  00008FC0: 47 38 4D 38 59 38 9C 38 97 39 10 3A 37 3A 52 3A  00008FD0: 57 3A 09 3B 35 3B 95 3B 2D 3C 4C 3C 6B 3C 8A 3C 00008FE0: A9 3C 2B 3E 32 3E E6 3E 4B 3F 5D 3F 00 10 00 00  00008FF0: 68 00 00 00 87 33 D2 33 95 35 9B 35 DE 35 E4 35  00009000: 3A 36 40 36 BA 36 BF 36 12 37 17 37 63 37 69 37  00009010: 8D 37 92 37 AB 37 B1 37 C7 37 CD 37 EA 37 F0 37  00009020: 06 38 0C 38 22 38 28 38 36 38 3B 38 5B 38 61 38  00009030: 77 38 7D 38 91 38 97 38 AB 38 B1 38 CD 38 D5 38  00009040: 33 39 3A 39 BD 39 C3 39 82 3B 4B 3D 25 3F 44 3F  // 重定向表的解析BASE RELOCATIONS #30 RVA,       4C SizeOfBlock254  HIGHLOW            000051B026F  HIGHLOW            000070B8280  HIGHLOW            00005020285  HIGHLOW            000070BC2A1  HIGHLOW            000070A03B6  HIGHLOW            000052A03CC  HIGHLOW            000052B03E2  HIGHLOW            000052C03F8  HIGHLOW            000052D0604  HIGHLOW            00005010

我们也稍微简单分析一下这个可重定向表,我们可以从表头可以看到这个表载入内存大小是0x428, 并且virtual address 0x8FA0(Image base 0x0000),所以0x8FA0 也可以看成载入内存时候,可重定向表距离image base 偏移是0x8FA0。 OK 找到表了,接下来就是对表的分析了

00008FA0: 00 00 00 00 4C 00 00 00 54 32 6F 32 80 32 85 32

重定向表还是按照block 去划分,每个block 会有一个header ,里面有两个内容 1 UINT32 RVP, 2 UINT32 blocksize。 从上面的数据,我们可以得出 RVP 是 0x00000000, blocksize =0x4c ,然后每个可重定位项是16bits 高4位是类型,低12bit 是偏移。我们可以看到上面的 54 32 就会解析成,偏移是0x254, 类型是0x03(HIGHLOW)。这个0x254 需要加上所在Block 的 RVP, 意思就是0x254 + 0x000000 = 0x254,这个偏移地方需要修改,修改多大,我们的类型是0x03,就是32bit。一起看个图片就知道了。两张图一个是重定向后的(左),一个没有重定向(右)。

可以看到偏移0xF4 的位置被修改了,那是Image Base ,被修改成实际image 载入内存的地址。剩下的就是需要重定向位置,我们用可以看到上面需要重定向的位置,有0x254, 0x26F, 等等,我们对着图片看看,不一样的地方正好和这些重定向偏移的地址吻合。好了,重定向之后,我们就可以根据表头的Entry point 偏移找到入口地址,然后跳入这个image 里。

关于PE 结构,它有它方便的一面,也有复杂的一面,对于学习uefi 的同学,PE 结构,我们了解这么多,也可以了。其他方面关于导入表,导出表,动态延时绑定等等,有兴趣自己去找另外的资料研究学习。

看着简单吧,其实自己写还不一定能写好,因为也有很多细节问题,比如内存对齐等等,细节的地方只能自己去摸索了,别人讲太多都是记不住,程序员还是应该务实一点,写几段代码调试几遍。比只看不写强太多。

UEFI 文件类型 .efi (二)相关推荐

  1. webstorm设置文件类型

    这里说一下webstorm如何配置文件类型,相信很多开发者都会有遇到过这个问题,新出来的,或者是以前的某些类型的文件,没有样式,看着特别奇怪. 这个就是没有使用对应的文件类型,并且配置. 例子一: M ...

  2. 如何判断任意文件类型

    这里写目录标题 如何判断任意文件类型 1问题 2可用的方案 2.1 使用HEX编辑工具 EmEditor Ultraedit WinHex DiskGenius 010Editor notepad++ ...

  3. BIOS、EFI与UEFI【系统启动专文二】转载自IT之家 (wkdubhe1987)

    BIOS.EFI与UEFI 1.BIOS.EFI.UEFI名词简介 前文已经说过BIOS是个程序,存储在BIOS芯片中,而现在的新式电脑用的基本都是UEFI启动,早期的过渡电脑用的都是EFI启动.其实 ...

  4. MDK的编译过程及文件类型全解——(二)

    前言: 为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长. 本文转载自:第48章 MDK的编译过程及文件类型全解-零死角玩转STM32 ...

  5. RHCSA (二) —— 常用简单命令Linux文件类型目录操作命令文件操作命令

    RHCSA 第二天 一.常用简单命令 1.timedatectl命令 timedatectl命令中的参数以及作用 2.reboot命令 3.poweroff命令 4.wget命令 wget命令的参数以 ...

  6. 嵌入式 Linux 入门(二、Linux 文件系统、文件类型及权限管理)

    嵌入式 Linux入 门第二课, linux 文件系统.文件类型及权限管理. ...... 矜辰所致 目录 前言 一.Linux 文件属性 1.1 Linux 文件类型 1.2 Linux 文件权限及 ...

  7. 脚本工具之下载M3U8文件类型的完整视频二-优酷

    上一篇文章<脚本工具之下载M3U8文件类型的完整视频>分享了鹅厂视频获取方法,今天分享一个优酷视频下载方法. 依赖说明 运行环境: Python3环境 内置播放命令: ffplay (需要 ...

  8. 第五课:系统目录及ls·文件类型及alias命令介绍

    1.上过一次我们学习了单用户和救援模式及服务器秘钥登录等操作,而我们最终的目的还是要操作和使用linux系统,所以我们今天先初步学习linux的基本命令如下: 一·目录介绍        ls命令介绍 ...

  9. 不限文件类型的ftp服务器,ftp服务器文件类型

    ftp服务器文件类型 内容精选 换一换 在SAP系统中,如果选择共享文件系统由SFS Turbo而非NFS Server提供时,例如SAP HANA中的Backup卷或者Shared卷,您需要创建SF ...

  10. 2.1/2.2 系统目录结构, 2.3 ls命令, 2.4 文件类型, 2.5 alias命令

    2019独角兽企业重金招聘Python工程师标准>>> 一.系统目录结构 ls / 查看根下面的文件 [root@linux-128 ~]# ls / bin dev home li ...

最新文章

  1. 京东2022届广告部算法岗内推
  2. pandas使用组合条件筛选、过滤数据行
  3. Facebook高管:我们是科技公司 不是媒体公司
  4. centos 日志切割_centos自带的日志切割工具 --- logrotate
  5. 七十九、TodoList示例 深入Redux的工作流
  6. php 文字超出画布,input实现文字超出省略号(代码示例)
  7. SQL Server链接服务器 Linked Server
  8. 【XLL 框架库函数】 Excel/Excel12f
  9. CSS3 制作魔方 - 相关立体样式
  10. 搭配和谐的色彩的秘密
  11. mysql数据库函数详解_MySQL数据库之字符函数详解
  12. 用 Open Live Writer 来写 cnblog.com 博客
  13. 【Struts2】〖登录功能〗Struts2框架实现登录功能
  14. linux下cmake安装配置
  15. 三分屏课件制作_如何利用剪辑软件制作分屏效果
  16. 朴素的模式匹配(布鲁特-福斯算法)
  17. 计算机网络图标不见了,电脑网络图标不见了怎么恢复
  18. 飞刀哥移植UC/OS-II到LPC1788(ARM Cortex-M3)的步骤
  19. 一个有点像舔狗的插件
  20. UDP都是全双工通信的吗

热门文章

  1. 淘宝客高手必备的14大WordPress插件
  2. 网络路径结点回溯分析工具
  3. pb利用pdf虚拟打印机将datawindow中的内容导出为pdf
  4. Jersey入门教程
  5. lcd1602c语言编程原理,简述lcd1602工作原理 lcd1602显示原理
  6. 使用Wineskin 重新打包《三国志 12 威力增强版 For Mac》
  7. 真正实现再wine上安装VC6.0,并编译调试程序
  8. elastic-Job配置参数详细解释
  9. 通过自学可以搭建量化交易模型吗?
  10. 一篇写给从未编程过的人的入门教程