
Here is the third part of my narration about the NVRAM formats used by UEFI-compatible firmware from various manufacturers.
In the first part, I talked about NVRAM in general and about the “standard” VSS format,
in the second - about interesting blocks that can be found next to NVRAM in this format, and this one will focus on a whole placer of various formats used in firmware on Phoenix platform
SCT : FlashMap, EVSA, Intel uCode, CMDB, SLIC pubkey and SLIC marker.
If you are wondering what the developers from Phoenix managed to make up for replacing VSS - welcome to the cat, but I’m warning you right away that the article was quite long.
Disclaimer # 3
I don’t even know what to write here after the first two “failures”, except that the author once again disclaims any and all responsibility for the loss of performance of your NVRAM, firmware, system, and everything else. Use the information at your own risk, behave well, and everything will be fine.
If you accidentally stumbled upon this article and it is not clear to you what is happening here, why the author dives into some formats with a head, without explaining anything, and how dare he at all - the
first and
second parts are waiting for you. The rest - for me!
Phoenix Flash Map
When I first opened the contents of the main NVRAM volume from the firmware of my old Dell Vostro 3360 on Ivy Bridge, I was very surprised. What is there to just find - first a whole set of Intel microcodes, after it some block with lines, half of which are copies of the
NoLongerUsed line, then vaguely familiar blocks with RSA signatures, about five EVSA repositories, and under the curtain - a structure with a speaker signature _FLASH_MAP. In short, the guys from Phoenix managed to dump NVRAM in such a heap of everything that it was impossible to figure out without a card. Let's start with it.
The card header is 16 bytes and looks like this:
struct PHOENIX_FLASH_MAP_HEADER { UINT8 Signature[10];
Immediately after the heading without additional alignment close to each other, the following entries follow:
struct PHOENIX_FLASH_MAP_ENTRY { EFI_GUID Guid;
The maximum size of the map is determined by its position, and since it is located at 0x1000 bytes from the end of the main volume of NVRAM, as much as possible there can be exactly 113 entries, which is enough with a huge margin.
In the screenshot, the map looks like this:

Immediately visible is the header with the
signature and the
number of records , immediately followed by a record with zero
GUID ,
data type 0 (that is, this is a volume),
record type 6,
physical address 0xFF980000,
data size 0x20000, and zero
offset ( , relative to itself, the first volume is not shifted anywhere, otherwise something is very wrong with either the file or the space metric).
')
You could still give all the values ​​of the GUIDs that I managed to find in different images and match the data type, but this can be done literally with one screenshot from
UEFITool NE , here it is:

In addition to GUIDs, there are also a couple of spoilers: vaguely familiar blocks with RSA turned out to be a public key and a marker for the
SLIC table, and for some reason, the block with lines was called CMDB. We will come back to all these things, but everything is clear with the card, it remains to learn how to parse the formats of all these blocks, and we can more or less understand the structure of NVRAM in the firmware based on Phoenix SCT. Go!
Intel microcode
First on the list we have a block with microcodes. I, unfortunately, do not have an image with AMD microcodes in NVRAM, so we will consider only Intel's ones. Despite the fact that there were as many as 12 free bytes in the header of the microcode, there was no space even for any seedy signature, and therefore searching for such a block of data among the contents of the NVRAM volume is still a task. You will develop your processor - think about the signature for its microcode, please! In any case, the main header of the Intel microcode is documented and has not changed, in my memory, never. Here he is:
struct INTEL_MICROCODE_HEADER { UINT32 Version;
In theory, there is still an extended header, but we have already received the most important information for further analysis, the total size. Let's look at the header of the first microcode in the volume:
Version is valid 1,
revision - 0x28,
release date - 04.24.2012,
processor type - 0x206A7,
checksum - 0xF3E9935D,
bootloader revision - 1,
processor flags - 0x12,
data size - 0x23D0,
total size - 0x2400.
The same microcode in UEFITool NE, it is clear that there were 5 such units with a microde:

CMDB
The next block to which the map refers is
CMDB . Its purpose is not very clear to me, most likely it was used to select the appropriate configuration in the firmware, suitable for several boards at once, or to populate SMBIOS tables, but at the moment it is no longer used. This block has a format that I cannot call anything other than “drug addict”, what its developers thought - this is a great mystery. See for yourself:
struct PHOENIX_CMDB_HEADER { UINT32 Signature;
The title does not look very strange, well, there’s no general size, well, okay, the end of the block can be found on parsing, the fun begins with chunks, which are easier to show in the screenshot right away:

After the header with a CMDB
signature , 0x0C and a
total size of 0x23, there is a zero chunk of three bytes: the
start byte is 0x42 (I still struggle with the desire to call it
TheAnswer ), the
offset of the first line after the header (which is always 0) and the
offset of the beginning of the block with strings (which is always TotalSize - HeaderSize). Total - three of the three fields are not used at all, why this chunk is needed is absolutely incomprehensible. The rest of the chunk follows, these already consist of five bytes: the
starting 0x42 that we are familiar with, the
offset of the key string , the incomprehensible
two-byte field , which is always 0x205 and the
offset of the string value . The lengths of both lines are not stored anywhere, and, apparently, are not even calculated. In the block with strings, the
BiosInfo header line is separately stored, referenced by the null chunk, and then all the remaining strings referenced by the remaining chunks. The total block size is always 0x100, so it is not stored anywhere. I would like to ask that the person who invented it smoked?
Since the structure has not been used for a long time, and at the same time, with my eyes, it is sorted out instantly; I did not add support for its analysis in UEFITool NE If suddenly you need it - write me in the comments or
here .
SLIC Pubkey and Marker
Right after CMDB, one after another, Pubkey and Marker blocks necessary for OEM activation of Windows Vista / 7/2008 follow, which are then transferred to the ACPI table SLIC by a special driver. I will not describe the format of these blocks in order to prevent the possible DMCA takedown of this article, but it was disassembled a long time ago, the description of all fields is shown by the
RW Everything utility, plus UEFITool NE supports them, so if you still need the formats of these blocks, look at them in
nvram.h .
EVSA
The latest format in our map, which (
finally! )
Is used to store NVRAM variables. Compared to VSS, the format uses space in NVRAM a bit more efficiently due to deduplication of variable names and their GUIDs, but it’s much easier to damage the EVSA storage, and almost all of my manual data recovery from NVRAM falls on it despite massive use. this checksum format. The data (including the header of the repository itself) is stored as records with a common header and different additional fields, like so:
struct EVSA_ENTRY_HEADER { UINT8 Type;
Screenshot:

Here we have a repository header with the
type 0xEC (“repository header”), single-byte
checksum 0x2C,
size 0x14 with the correct EVSA
signature ,
attributes 0x01 (“default values ​​here”) and
storage size 0x2B65. Immediately after the header, two entries of
type 0xED (“GUID”) go without any alignment, with
checksums 0x35 and 0xB3, respectively, of
size 0x16,
identifiers 0 and 1, and
GUIDs 4FEE3D67-18F4-4217-BA7B-BC538148382A and 1E1F1797-2CCE -49D6-A6CE-4012F338A76E respectively.
In UEFITool NE, the same storage looks like this:

In addition to the types 0xEC (“storage”) and 0xEC (sometimes 0xE1, “GUID”) discussed above, there are three more - 0xEE (sometimes 0xE2, “variable name”), 0xEF (sometimes 0xE3, “data”) and 0x83 ("Deleted data"). As I understand it, deleting records of the type “GUID” and “variable name” is possible only with a complete reassembly of the repository by the driver performing garbage collection in it.
An entry with the type “variable name” looks like this:
struct EVSA_NAME_ENTRY { EVSA_ENTRY_HEADER Header;
Picture:

An entry of
type 0xEE, with
a checksum of 0x39, a
length of 0x20, and an
identifier of 0, which contains the
string DellVariable in UCS2. It makes no sense to show in UEFITool NE - and so everything is clear.
It remains to consider the last record type - data. In fact, there are two formats, like this:
struct EVSA_DATA_ENTRY { EVSA_ENTRY_HEADER Header;
I will show only the first in the screenshot, because the second is quite rare, and there is just another additional field:

Here we have two entries of
type 0xEF, the first of which has a
checksum of 0x84,
size 0x5F,
GUID identifier 0,
identifier of the name 0 and
attributes 0x03 (
NV +
BS ), and the second - 0xEA, 0x11, 1, 1 and 0x03, respectively. In the first, it turns out that the data of the very aforementioned Dell variable is stored with the GUID 4FEE3D67-18F4-4217-BA7B-BC538148382A.
In UEFITool NE:

Conclusion
Well, now the format of the data, which can be stored on the Phoenix SCT code base in NVRAM volumes, has become a little clearer. It remains to talk about the format of NVAR, which is used in AMI Aptio, I will talk about it in the next, final part of this article.
Thank you very much for your attention, send the occluded spots to L / C, and let randomly save you from recovering NVRAM at least manually, even if you like.