前面对于 RU.EFI 的研究告诉我们对于 X86 来说,访问硬件信息需要的基本操作有:

1. PCI 信息的访问

2. 访问IO Port 直接访问

3. IO Port Index/Data 方式的访问

4. Memory 的访问

5. Memory Index/Data 方式的访问

6. MSR 的访问

掌握了上述的访问方法就可以访问到 X86 上的全部空间和寄存器。下面逐项介绍在 WinDBG 中的访问方法。因为大多数情况下,WinDBG 是用于调试 Windows 软件本身而不是硬件,因此很多操作都是来自个人总结如果有错误或者遗漏,恳请及时指出。

1.PCI的访问

a. ... > Read More

Subst 命令是一个很老的 DOS命令,通过它可以将一个目录映射为一个盘符。

例如,我本机当前只有一个盘符c:

通过 subst d: 201903, 即可将 buildbs\201903 这个目录映射为 D:

再次查看会多出一个 d: 盘符

前一段时间参加创客嘉年华,惊奇的发现他们在这个活动上有一个摊位,更惊奇的是他们的摊位主打竟然是玩具。然后和他们聊了两句发现他们这些年转型向玩具市场进军。

转过天,我修理东西,拿出了他们家生产的螺丝刀,发现竟然生锈了。

基本上每一个刀头都没有幸免.......
这套工具用的很少
外包装还是完好的

除了这一套螺丝刀,我还有一个游标卡尺也是他们家的

> Read More

前面介绍了如何使用汇编语言直接编写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

使用汇编语言来编写UEFI Application 完全没有问题,理论上编写 DXE Driver 也没有问题。最近抽空研究了一下这个问题。

从网上的资料来说,可以使用 FASM来完成这个工作,在http://x86asm.net/articles/uefi-programming-first-steps/ 可以看到一篇名为 “UEFI Programming - First Steps”的文章。但是经过我的实验使用 FASM 最出来的EFI 在文件头部上(PE Header)就存在很大的问题,比如: Image Size 给出来的不正确,还有 BaseImage 给出的不正确。有可能是我没有使用正确的参数导致的,但是看起来研究会很麻烦,并且最终能否成功严重存疑于是放弃了。

接下来研究如何使用 Nasm 来实现编写一个 UEFI Application。在 https://hackerpulp.com/os/os-development-windows-1-building-uefi-applications-nasm/https://github.com/BrianOtto/nasm-uefi 找到了一个例子,经过修改可以正常工作。

1.原文是编写一个 BootLoader,所以最后完成显示之后Hang 住即可,这里我们需要正常返回,最终ASM 代码如下:

; Copyright 2018-2019 Brian Otto @ https://hackerpulp.com
; 
; Permission to use, copy,...								 > Read More
			

目标:对于一个已经存在,但是没有 Source Code 的 EFI Application ,通过一种方法来插入代码实现在运行时显示自定义字符串。

前面关于 EFI 文件的研究提到对于一个 EFI Application 来说,运行后会把全部内容加载到内存中。如果我们能在EFI中找到足够大的 “缝隙” ,可以将代码插其中然后通过修改EntryPoint 处加入跳转到缝隙处我们的代码执行之后再跳转会继续执行。

经过观察,我发现“MZ”标志后有一段可以使用的“缝隙”,这次试验就在这里加入代码完成。

首先遇到的问题是:我们需要插入什么样的代码来完成显示。众所周知,UEFI 下需要使用ConOut的OutputString来实现显示。当然无法手工直接编写汇编语句,于是在 \MdePkg\Library\UefiApplicationEntryPoint\ApplicationEntryPoint.c文件中,直接插入要显示的代码:

EFI_STATUS
EFIAPI
_ModuleEntryPoint (
  IN EFI_HANDLE        ImageHandle,
...								 > Read More
			

手上有一块 DFRobot 出品的 FireBeelte,它的主控芯片是 ESP32 自带 WIFI 和 蓝牙,因此可以直接模拟成蓝牙键盘。

首先需要安装ESP32 BLE for Arduino这个库,在https://github.com/nkolban/ESP32_BLE_Arduino

然后安装Bluetooth LE Keyboard 这个库,在 https://github.com/T-vK/ESP32-BLE-Keyboard

之后,还需要修改\ESP32-BLE-Keyboard-master\BleKeyboard.cpp 文件,在前面插入  HIDINPUT 和HIDOUTPUT 的定义,否则编译会报错:

#if defined(CONFIG_ARDUHAL_ESP_LOG)
  #include "esp32-hal-log.h"
  #define LOG_TAG ""
#else
  #include "esp_log.h"
  static const char* LOG_TAG =...								 > Read More
			

前面提到了使用 Image Size 作为CPU Debug Break的触发条件,相比使用Image 的Size作为触发条件,使用 Image Name 作为触发条件要方便很多,每次只需要重新编译Application 然后运行之即可,因此这里研究如何实现。

首先要解决的是哪里取得Image Name。通过观察可以得知当我们运行 NT32 模拟器时,每次调用 EFI Application时候会在 Debug 窗口显示加载的Image 名称:

这个显示的功能位于 \MdeModulePkg\Core\Dxe\Image\Image.c如下函数中:

EFI_STATUS
CoreLoadPeImage (
  IN BOOLEAN             ...								 > Read More
			

最近在研究 UEFI Application结构相关的内容。除了静态的分析,还需要找到一种观察和调试加载到内存后EFI文件的方法。经过比较和研究, NT32 模拟器是很好的选择。通过它能够方便的进行观察和反编译。

需要解决的第一个问题是:找到跳转到Application Entry Point 处的代码。经过研究入口位于  \MdeModulePkg\Core\Dxe\Image\Image.c  文件中下面这个函数:

EFI_STATUS
EFIAPI
CoreStartImage (
  IN EFI_HANDLE  ImageHandle,
  OUT UINTN      *ExitDataSize,
  OUT CHAR16     **ExitData  OPTIONAL
  )

前面准备妥当后,在下面的语句中跳转到Application Entry来开始执行:

最近需要进行memory stress 测试,于是到 MemTest86 网站上进行查看:

https://www.memtest86.com/index.html

目前他们提供了几个版本供下载,具体区别如下:

来自 https://www.memtest86.com/features.htm

可以看出对于普通测试,免费版已经足够。当然,如果有条件还是建议购买 Pro 版本。

运行测试的方法是:

1.从 https://www.memtest86.com/download.htm 下载免费版

2.解压之后的 Boot 目录内容就是可以在 UEFI Shell 下运行的Application