前面介绍了如何使用汇编语言直接编写UEFI Application,这里我偶然发现一个问题:用汇编生成的EFI 文件中,DOS 头部看起来多了一些东西。比如十六进制查看之前的 NasmUEFI.EFI 文件:
对比 Hello.EFI:
可以看到有些内容被清空为0x00. 首先怀疑的是编译过程中有工具来完成这个动作。于是,重新编译 Hello.EFI 观察到在末期有下面的操作:
Generating code
Finished generating code
"GenFw" -e UEFI_APPLICATION -o c:\buildbs\201903\Build\AppPkg\DEBUG_VS2015x86\X64\AppPkg\Applications\Hello\Hello\DEBUG\Hello.efi c:\buildbs\201903\Build\AppPkg\DEBUG_VS2015x86\X64\AppPkg\Applications\Hello\Hello\DEBUG\Hello.dll
这个操作输入的是hello.dll 输出为 hello.efi,观察发现DLL 中还存在一些字符串,到了EFI 中会消失。接下来在窗口中直接运行 GenFw 来从 DLL生成EFI文件,最终确认是这个工具来完成移除多余的字符工作的,准确的说只是用0xFF覆盖,并没有引起文件长度的变化。
接下来查看 GenFW 的代码, \BaseTools\Source\C\GenFw\GenFw.c 其中下面就是我们需要找到的位置:
//
// Zero all unused fields of the DOS header
//
if (DosHdr != NULL) {
memcpy (&BackupDosHdr, DosHdr, sizeof (EFI_IMAGE_DOS_HEADER));
memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER));
DosHdr->e_magic = BackupDosHdr.e_magic;
DosHdr->e_lfanew = BackupDosHdr.e_lfanew;
for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (UINT32 ) DosHdr->e_lfanew; Index++) {
FileBuffer[Index] = (UINT8) DosHdr->e_cp;
}
}
特别提醒:目前提供的编译辅助工具都是 X86 版本的,因此需要在 x86 Native Tools Command Prompt 窗口下编译,如果使用X64会出现编译报错。
本文只是为了简单试验,并没有考虑一些特殊情况。针对上面的代码进行修改,插入一句话即可:
strcpy(&FileBuffer[sizeof (EFI_IMAGE_DOS_HEADER)],"www.lab-z.com");
这样,再次使用 GenFw 来进行DLL到EFI的转换,可以看到 EFI 文件中DOS Header后面被插入了我们期望的字符串。
通过上述的方法可以在 EFI 文件中自动加入自定义的字符串,通过这样的方法可以制作一些特殊的 EFI 文件,比如只能在特别BIOS上运行的 EFI文件。