UEFI BIOS Modification Part One: Introducing UEFITool

  • Tutorial
Hiding behind semi-mythical “security” and “protecting the simple user from bootkits”, UEFI manufacturers are tightening their screws with each new generation of their products. At the same time, the support of previous generations quickly disappears, and their users have no choice but to take this support into their own hands. Of course, in the absence of source code, making some changes is quite difficult, but you can do a lot without it.
In my previous articles about UEFI, I planned to describe various useful modifications that help to overcome some of the limitations laid down by manufacturers, but then they did not reach their hands, but now is the time.
In the first part of this article I will describe the work with the tool I wrote for modifying UEFI images, and the second will be devoted to the modifications themselves.


Entry, disclaimer


UEFI BIOS firmware on modern motherboards, despite the presence of various technologies like USB BIOS Flashback, Dual BIOS, Flash Recovery, etc. - still a lottery. Firmware for modified images is a double lottery.
That is why I ask that before any experiments with firmware can be started, using a hardware SPI programmer, a complete dump of the contents of the microcircuit is made, otherwise recovery from unsuccessful firmware (and it will happen sooner or later) will be long, expensive and painful.
An SPI programmer can currently be assembled at home from anything from a pair of resistors and capacitors ( SPIPGM ) to an Arduino or Raspberry Pi . My version of a cheap and fast SPI programmer is described here.. I advise fans of etching a couple of boards to pay attention to this project , and admirers of all-in-one devices - to this one .
Further in the text, I believe that you have a programmer, the ability to recover from a firmware failure, and a willingness to experiment. Of course, you can also sing songs to the madness of the brave, but don’t tell me later that I didn’t warn.
Traditionally, everything you read here is written for educational purposes, the author is not responsible for the possible damage to your equipment, lost profits, loss of time and faith in humanity, you use the provided software at your own risk and so on.

Uefitool


Tired of the limitations of existing utilities for working with UEFI images (well, struck by NIH syndrome at the very heart), I wrote an open-source cross-platform utility - UEFITool .
This is a UEFI image editor, written in C ++ \ Qt, distributed under the BSD license, ready-made assemblies are laid out here .
The project is under active development, so the code does not shine with beauty and there are no, no, but some bugs. If you stumble across - I will be glad to report.
For normal operation with the utility, it is worth reading the previous articles on the structure of the UEFI image, otherwise it will not be clear what is happening at all, but I will try to clarify some points. We assume that this is a blank for future documentation.
As examples in both parts of the article I will use full dumps with Zotac Z77-ITX WiFi (AMI Aptio4) and Dell Vostro 3360 (Phoenix SCT 2.3). Unfortunately, I do not have a test bench on the Insyde H2O platform, so I have nothing to tell about it. Perhaps Falseclock knows a little more about them.
From the point of view of UEFITool, there is practically no difference between the UEFI images of different manufacturers, so I will focus on it when describing patches.
So, run UEFITool, open the image (Ctrl + O) and see something like this:

The structure of the open image in the form of a tree is displayed on the left side of the window, information on the selected tree element on the right, messages indicating errors in the file format on the bottom, in this case, the use by Phoenix developers of sections with type 0xF0, the purpose of which is not described in the UEFI specification PI . Double-clicking on the message will open the tree so that it is visible either on the element itself that this message called, or its parent element. The search results can be displayed in the same window, which can be called up by pressing Ctrl + F (both options are in the same picture):

The terminology should be clarified here a bit. Almost all structural elements in the UEFI image have a header, which stores service data like GUIDs, attributes, checksums, etc., and the body - the data itself is stored in it. The text is not stored in the headers, so for him such a choice is not needed.
At the first level of the tree are Flash regions, in this case Descriptor, ME and BIOS:

When choosing a Descriptor region, you can find out the access settings for the regions, in this case full access, but such settings are very rare. Intel recommends that equipment manufacturers block access to the ME region for reading / writing and the Descriptor region for writing, which is why on most boards with built-in tools it is almost impossible to remove a full dump without dancing with a tambourine. When choosing the ME region, you can find out the version of ME firmware, but if it is not displayed, this is not good and it is better not to sew such an image.
Let's move one level down to the contents of the BIOS region:

At this level, there may be two types of elements: volumes and free space. Free in this case is not necessarily empty, for example, EC firmware is stored in this image at the very beginning of Padding .
Volumes are divided into ordinary volumes (the file system format is known), boot volumes (the FS format is known, contain the Security Core, it is worth changing with special care) and unknown (either the FS format is unknown or the analysis has not yet been implemented). In our case, the first volume after free space at the beginning is normal, then two unknowns (in fact, the first one stores NVRAM, and the second contains keys and databases for SecureBoot, but I haven’t explained this to the program yet), the last volume is bootable .
Now let's open a regular volume, in this case it stores files loaded in the DXE phase.

Such a structure (the main volume inside the compressed section) is used quite often, it allows you to save a decent amount of space in the chip. There is another option to compress not the whole volume, but each file individually - this is somewhat less economical in terms of space, but such a UEFI BIOS starts faster, because it makes no sense to unpack files that have not been accessed.
Now look inside the file:

All data in it is stored inside a GUID-defined section (an EDS or a checksum is usually stored in the header of such sections, in this case 4 bytes, similar to a CS, which, however, no one checks) and are divided into 4 sections: image PE32 - the actual executable file in the PE / COFF format, the DXE dependency section - determines the loading order of DXE drivers, the UI section - it stores the text "SystemCapsuleRt.efi" in Unicode format and an unknown section of type 0xF0 (most likely, its contents are somehow This is related to the aforementioned COP).
All this is good, of course, but editing is not yet visible. It doesn’t matter, we call the context menu for any element, which shows what can be done with this element.

And you can do the following:
  • save the element to a file either as a whole (Extract as is), or only data, without headers (Extract body)
  • rebuild the element (Rebuild), in this case, when you save the changed image for it (and all its parent elements), sizes, checksums will be recalculated, alignment will be fixed, i.e. image structure will be aligned with the UEFI PI specification
  • insert an element from the file, either before the selected one (Insert before), or after (Insert after), or inside it (Insert into, in this case, nothing can be inserted into the PE32 section)
  • replace an element with another element from the file, either in its entirety (Replace as is), or only its body (Replace body)

The last action is most useful because allows you to modify any part of the UEFI, without affecting the structure of the entire image.

Usage example


As an example, consider a modification useful for MacOS X users on a PC: bypassing the setting of the LOCK bit (0x0F) in the register MSR_PMG_CST_CONFIG_CONTROL (0xE2). This bit is set by the PowerManagement DXE driver so that the OS cannot control the CPU multiplier by writing to this register. For Windows and Linux, this is not a big problem, but MacOS X cannot stand such impudence from UEFI. You can, of course, patch the AICPM.kext driver (in 10.8) or the kernel (in 10.9), but it is better to patch the DXE driver and not be afraid that the next automatic update will break the download. This patch is needed only for systems based on Intel SandyBridge, IvyBridge and Haswell processors and their * -E options and is done like this:
  1. Open your dump in UEFITool, clear Messages by pressing Ctrl + Backspace, so as not to interfere
  2. Open the search, select Hex-pattern, Body only, look for the line "75080FBAE80F"
  3. We double-click on the message that the line is found, save the body of the specified element to a file
  4. We fix in the Hex editor "75080FBAE80F" to "EB080FBAE80F" (JE becomes JMP), save the changes
  5. We replace the contents of the selected element with the changed one, the old element will be marked for removal (Remove), the new one for replacement (Replace), all parent elements to the root will be rebuilt (Rebuild)

  6. Save the changed image (Ctrl + S), if the save was successful, a request will be issued to open the just saved image, if not, an error message

We flash the resulting image with the same SPI programmer with which it was made, and we get the absence of a kernel panic when loading MacOS X.

Details, other modifications, conclusion


If you are interested in where the 75080FBAE80F magic pattern came from and what other patches you should pay attention to, read the second part of this article, which will be published a little later. In it, I will try to prepare more examples in the format “what kind of modification, why is it needed, how to make it, by whom and how was found”, without delving into each time exactly how to remove the element to be modified and how to insert it back.
I hope that the article did not seem too boring and boring. If you have questions and suggestions - I will be glad to listen and answer as far as possible. Bug reports will be glad even more. Thanks in advance and successful firmware.

PS Dear administration and UFO personally, make a UEFI hub for such posts, please.

Also popular now: