It is not really a modding question in the first place but related: Not being able to restore a previously dumped BIOS drives me here.
[Sorry for the long details that follow later! And I had to slice my post due to new user limit ]
Typically, I do a BIOS backup/dump using the original tools provided by the manufacturer before I flash a new BIOS version (AFUWINx64.exe dump.rom /O). When trying to restore the old version after the update (for testing purposes), the original update package uses the command AFUWINx64.EXE imageM46.rom /p /b /n /r /sp /defans /capsule. I realized that it does not want to be flashed back, seeing the infamous Error 18: Secure flash verify fail - rendering the whole idea of a BIOS backup impossible.
My main questions are:
for some advice on how to flash the previously dumped BIOS
or what I have to change to let it flash ok (I am familiar with hex editing )
or some insights how this failing check is performed and the mechanisms behind:
Is it checked in the OEM flash tool (AFUWINx64 v5.09.02.1384.09)?
Is there a signature stored in the BIOS file which is missing or does not match?
How can this check be disabled? → Is it done on the board or in the flash tool?
Alternatively, if someone could provide me with the original Lenovo M46KT40A BIOS package (let’s call it v40 version for short) of a Thinkcentre M75t Gen2 (AMD Platform), it would work around my problem in an acceptable way as well. Since that is the version I can’t download or find online anymore. But it was the old version I updated in the first place and which I want to restore for testing.
However, I found the direct successor of that version still being online (M46KT41A, let’s call it the v41 version) and used that for some comparison of the original and the dumped BIOS files but I am not that familiar with the binary layout of the UEFI BIOSes and I’d be happy if someone with more experience could help with that. Of course, I dug through the forum and read the guides which seemed applicable here (AMI BIOS Aptio V platform), for example here (hxxps://winraid.level1techs.com/t/guide-how-to-flash-a-modded-ami-uefi-bios/30627) (bit old by now) and here (hxxps://winraid.level1techs.com/t/guide-manual-ami-uefi-bios-modding/22633/13) but the suggestions do not work as documented and I suppose, this stuff is developed further with fixes and better checks.
I’ll try to document my findings in the following.
For any insights into the mechanisms of the secure flash system, I’d be thankful - or just a copy of the original Lenovo M46KT40A BIOS package. (Btw, are there any systematic archives for BIOS files?)
Looking at the dumped BIOS files (for example dump b41.rom) and the original v41 update package (M46KT41A_IMAGEM46.ROM, right), they do not contain a capsule header or section which I often read about here.
<UEFITool screenshot of a68 and 0.28 left out>
Although, I notice the dump and the original file differ in the first half of the image. By looking at the hex it seems the dump contains all settings and machine data/serials which are mostly FFs in the original ROMs (dump left, original right):
In another guide here, it is recommended to run the BIOS file through the UBU tool (store/rename option on exit) which should remove a section which causes the check to fail (as far as I understood). I used UBU v1.79.17 with and without updates of Mar23 but it dit not change my BIOS dump of v40, the checksum of input and output files are identical. Here is my output on my v40 dump and findings of the UBU tool:
Scanning BIOS file bios_M46KT40A_orig.rom.
Please wait...
Manufacturer - LENOVO
Model - 32E1
BIOS release - 5.17 05/19/2023
BIOS platform - AMI Aptio 5
[EFI Drivers - Find and Extract]
AMD RAIDXpert2 GUID C74F06D2-ED92-489B-879C-C0E428A22167
AMD GOP SubGUID 12FA6BCD-E5C0-4E61-8BC6-3876EC6C2083
AMI NVMe GUID 634E8DB5-C432-43BE-A653-9CA2922CC458
Realtek Undi GUID E88DB748-A947-46CF-AB6F-5C99B6C6C4B8
[OROM - Find and Extract]
VBIOS in SubGUID 12BF5331-4DF7-4CA8-9C7F-155EF4A67A11
VBIOS in SubGUID 12BF5331-4DF7-4CA8-9C7F-155EF4A67985
OROM in GUID A0327FE0-1FDA-4E5B-905D-B510C45A61D1
OROM in GUID 365C62BA-05EF-4B2E-A7F7-92C1781AF4F9
Drücken Sie eine beliebige Taste . . .
Main Menu
[Current version in BIOS file]
1 - Disk Controller
EFI AMD RAIDXpert2-Fxx - 9.3.0-00221
EFI NVMe Driver present
2 - Video OnBoard
EFI AMD GOP Driver - 2.15.0.17.10
OROM VBIOS Cezanne - 017.010.000.028.000000
OROM VBIOS Renoir - 017.010.000.028.000000
3 - Network
EFI Realtek UNDI Driver - 2.055
OROM Realtek Boot Agent GE - 1.37
OROM Realtek Boot Agent GE - 2.66
4 - Other SATA Controller
5 - CPU MicroCode
View/Extract/Search/Replace
S - AMI Setup IFR Extractor
O - Option ROM in other GUIDs
0 - Exit
RS - Re-Scanning
A - About
Choice:
Side note: Regarding the UBU output, I noticed some changes depending which AFUWin version was used for dumping/reading the BIOS. When I read the BIOS with different versions of AFUWin there seem to be 3-byte changes scattered about the file which are FF with the old version (perhaps, some value separators or meta data). Here is a diff between v5.09.02.1384.09.B230523.LV (left, from the M46JY41 package) and v5.09.02.1384.09.B231030.LV (right from the M46JY4D package), please note the list of changes in the right pane (most are 3 bytes long):
Its the same changes applied by UBU (right below) when processing a BIOS file dumped with the older AFUWin (v5.09.02.1384.09.B230523.LV) on the left below:
Meaning, a BIOS file dumped by the newer AFUWin version (B231030) does not get modified by UBU, output is identical. I dumped the older target BIOS v40 by the newer AFUWin version (B231030) initially (because it was the newest BIOS version available) and therefore it does not get changed by UBU in any way.
In the thread above, @ket identified section GUID 5A88641B-BBB9-4AA6-80F7-498AE407C31F “and simply removed it, rebuilt the image and saved it”. Using UEFITool 0.28, that did not work for me, same error 18.
Playing around with v41 of the BIOS (because I have the dump AND the original image), I could swap out the first ~200 bytes in the original image with that of the dump and it still flashes ok. This area differs between them and seems binary data, after that some hardware specific text (or settings) follows which is all FF in the original ROM. (original left, mod right)
But however, if I just change the version numbers in the original image, flashing fails.
Therefore, the secure flash test seems to cover a specific area only: Haven’t had the time yet to figure out the boundaries by trail&error, is there a spec about it somewhere? (original left, mod right)
Comparing the dumped and the original v41 ROM files, they differ only in the first half (up to 5.672.188 bytes) where there are many areas in the dump which are just FF in the original ROM file:
Only the head, starting at 0x10 (58 bytes long) actually differs and is not FF in the original image (see screenshot above under A).
More interesting, starting at 5668872 bytes (0x568000) there is a 512 bytes area (left) which actually differs and is not FF in the original ROM (right, could this be a checksum/signature?) Starting at 0x568210 its all FF again in the original file:
For any insights into the mechanisms of the secure flash system, I’d be thankful - or just a copy of the original Lenovo M46KT40A BIOS package. (Btw, are there any systematic archives for BIOS files?)
Thanks for any help & sorry for the many replies of my own! (new-user limit for pictures)
Further looking at the differences of the v41 dump and the original bios file and testing what changes are necessary for the secure flash check to succeed, I figured out the following fixes to be done on the bios dump file of version m46kt41:
0x10…0x47 (can be kept)
0x48…0x241 (can be kept)
0x1000…0x1030 (can be kept)
0x1800…0x19c3 (can be kept)
0x8000…0x8005 (can be kept)
0x3708f…0x3708f (1 byte only! F0 → F8)
0x37a71…0x4bb5f, fill 0xff
0x56be0…0x56fef, fill 0xff
0x57000…0x65843, fill 0xff
0x76b90…0x76fff, fill 0xff
0x98000…0x9e06f, fill 0xff
0xb8000…0xb8a2f, fill 0xff
0x21b000…0x22955f, fill 0xff
0x568000…0x56820f (different pattern on both sides)
→ duplicate of original ROM pattern in dump at:
0x6e8000…0x6e820f (search for text ‘BCBATOKN’)
0x568210…0x568cfb, fill 0xff
Similar changes are then needed for the target version m46kt40 for which I do not have the original bios file, just the dump. The ranges are quite similar, sometimes larger until the next 0xff area:
0x3708f…0x3708f (1 byte only! value E0 → F8)
0x37a71…0x5695c, fill 0xff
0x56ba0…0x56fef, fill 0xff
0x57000…0x66c3b, fill 0xff
0x76ba0…0x76fff, fill 0xff
0x98000…0x9a99f, fill 0xff
0xb8000…0xb847f, fill 0xff
0x21b000…0x22955f, fill 0xff
0x568000…0x56820f, copy of 0x6e8000, len 0x210
0x568210…0x568cfb, fill 0xff
This passed the secure flash check and restored the v40 bios version successfully.
The check seems to be related to some repeatedly very similar (and aligned) areas in all three investigated bios versions. If someone is interested, the areas start with the APCB keyword and contain the keywords BCBATOKN, BCBAMEMG or BCBAPSPG:
0x1fa000: APCB…BCBAMEMG…TOKN, len 7976 (0x1f28)
0x3e4000: APCB…BCBAMEMG…TOKN, len 7976 (0x1f28), copy of 0x1fa000
0x3e8000: APCB…BCBATOKN, len 472 (0x1d8)
0x3e9000: APCB…BCBATOKN, len 480 (0x1e0), ‘RECV’ near end
0x564000: APCB…BCBAPSPG…MEMG…TOKN, len 9304 (0x2458)
0x568000: APCB…BCBATOKN, len 528 (0x210)
0x569000: APCB…BCBATOKN, len 536 (0x218), ‘RECV’ near end
0x6e4000: APCB…BCBAPSPG…MEMG…TOKN, len 9304 (0x2458), copy of 0x564000 and following
0x6e8000: APCB…BCBATOKN, len 528 (0x210)
0x6e9000: APCB…BCBATOKN, len 536 (0x218), ‘RECV’ near end
I am happy now with being able to restore the old v40 bios version and can’t spend any more time on further research.