Bypass BIOS Flash Protection Range Registers on Insyde BIOS (Xiaomi Air 12.5)

Hello, i’m currently trying to gain write access to the BIOS area on a Xiaomi Notebook Air 12.5

I could disable the generic BIOS lock by replacing the bit at offset 0x17 on “PchSetup” (4570B7F1-ADE8-4943-8DC3-406472842384)

1
2
3
 
(0x17, 1, 0x670EEB73D338776D) BIOS Lock
(0)[ ] Disabled
(1)[*] Enabled (Default)
 


But unfortunately they have included Protected Range Registers which can't be unlocked by the (placeholder?) setting:

1
 
Error 316: Protected Range Registers are currently set by BIOS, preventing flash access.
 

1
2
3
 
(0x612, 1, 0x670EEB73D338776D) Flash Protection Range Registers (FPRR)
(0)[ ] Disabled
(1)[*] Enabled (Default)
 

1
2
3
4
5
6
 
SPI Protected Ranges
------------------------------------------------------------
PRx (offset) | Value | Base | Limit | WP? | RP?
------------------------------------------------------------
PR0 (84) | 87FF06C0 | 006C0000 | 007FFFFF | 1 | 0
PR1 (88) | 853F0220 | 00220000 | 0053FFFF | 1 | 0
 


For now, i only have access to the range at 0x540000 - 0x6BFFFF, which includes EfiSystemNvDataFvGuid and a Padding range with the CPU Microcode..

Edit by Fernando: Thread title customized and shortened

I think i will just use an external programmer to overwrite the descriptor area, however the protected area still persists.

Edit:
The registers are different for Skylake/Kabylake:

1
2
3
4
5
 
Flash Protected Range 0 (BIOS_FPR0) = Offset 0x84
This register cannot be written when the FLOCKDN bit is set to 1.
 
Flash Protected Range 1 (BIOS_FPR1) = Offset 0x88
This register cannot be written when the FLOCKDN bit is set to 1.
 


1
2
3
4
5
6
 
Hardware Sequencing Flash Status and Control (BIOS_HSFSTS_CTL) = Offset 0x4
 
Flash Configuration Lock-Down (FLOCKDN): When set to 1,
those Flash Program Registers that are locked down by this
FLOCKDN bit cannot be written.
Once set to 1, this bit can only be cleared by a hardware reset.
 

Chipsec shows the value 0xE000 on offset 0x04 which enabled the FLOCKDN bit:

1
2
3
4
5
6
7
8
9
10
11
12
 
[*] HSFS = 0xE000 << Hardware Sequencing Flash Status Register (SPIBAR + 0x4)
[00] FDONE = 0 << Flash Cycle Done
[01] FCERR = 0 << Flash Cycle Error
[02] AEL = 0 << Access Error Log
[03] BERASE = 0 << Block/Sector Erase Size
[05] SCIP = 0 << SPI cycle in progress
[13] FDOPSS = 1 << Flash Descriptor Override Pin-Strap Status
[14] FDV = 1 << Flash Descriptor Valid
[15] FLOCKDN = 1 << Flash Configuration Lock-Down
 
[mmio] MMIO register range [0x00000000FE010000:0x00000000FE010000+00001000]:
+00000004: 0000E000
 


Based on this post by coderush to remove the FLOCKDN bit, i found something similar on SaInitDxe:
1
2
3
4
5
 
48d9:   8d 47 04                lea    eax,[edi+0x4]
48dc: ba 00 e0 00 00 mov edx,0xE000
48e1: 8b c8 mov ecx,eax
48e3: 8b d8 mov ebx,eax
48e5: e8 f6 dc ff ff call 0x25e0
 


It seems to write 0xE000 to the correct offset of 0x4, but it could be just an coincidence.

Edit:
Tested it without success, this is not the correct module.

Got it, the lock is inside BiosRegionLockDxe:

1
2
3
4
5
6
7
 
56c:    e8 d7 05 00 00          call   0xb48
571: 0f ba e0 0f bt eax,0xf
575: 72 0f jb 0x586
577: ba 00 80 00 00 mov edx,0x8000
57c: 48 dec eax
57d: 8b cb mov ecx,ebx
57f: e8 74 06 00 00 call 0xbf8
 


Replacing 0x80 with 0x00 avoids settings the FLOCKDN bit:
1
2
3
4
5
6
7
8
9
 
[*] HSFS = 0x6000 << Hardware Sequencing Flash Status Register (SPIBAR + 0x4)
[00] FDONE = 0 << Flash Cycle Done
[01] FCERR = 0 << Flash Cycle Error
[02] AEL = 0 << Access Error Log
[03] BERASE = 0 << Block/Sector Erase Size
[05] SCIP = 0 << SPI cycle in progress
[13] FDOPSS = 1 << Flash Descriptor Override Pin-Strap Status
[14] FDV = 1 << Flash Descriptor Valid
[15] FLOCKDN = 0 << Flash Configuration Lock-Down
 


Which allows me to remove the flash protected range:
1
2
3
4
5
6
7
8
 
[CHIPSEC] Read SPIBAR + 0x84: 0x87FF06C0
[CHIPSEC] Read SPIBAR + 0x88: 0x853F0220
 
[CHIPSEC] Write SPIBAR + 0x84: 0x00000000
[CHIPSEC] Write SPIBAR + 0x88: 0x00000000
 
[CHIPSEC] Read SPIBAR + 0x84: 0x00000000
[CHIPSEC] Read SPIBAR + 0x88: 0x00000000
 
1 Like

Hi,

Can you explain how correctly make changes and to flash them to bios?
It is clear to me how to change variables. But this is not a variable, meaning that after changes are made they must be flashed via fptw, but if bios is locked, how to flash it?
Also using UEFITool to extract BiosRegionLockDxe.efi , afterwards changing from 0x80 to 0x00 then inserting changed BiosRegionLockDxe.efi - UEFITool rebuilds bios backup completely. Is this is a good way to change?

Regards,

@Wootever - if you’re around chime in if you can, thanks!

@ziga34 - if you cannot write BIOS with FPT or other tools, due to lock you can try to unlock the variables in grub shell boot, did you try that already?
If yes, and no luck, you may need flash programmer to get the initial flash w/ unlock in there, then next BIOS flash do the edit in BIOS modules first then they should remain post flash.

Shortly what I have and what I did:
I own 2018 model mi notebook 13 air 8550u mx150 which has Insyde UEFI
there are totally 3 partitions: Descriptor, ME and BIOS
After inspecting descriptor there are r/w access to ME and BIOS
Using UEFITool I’ve extracted SetupUtility and then used IFR Extractor to convert it to readable txt file
Inside txt I found these variables which responsible for securing bios and some extra vars which I’m not sure if has any effect on bios:
RTC Lock
BIOS Lock
Flash Protection Range Registers
SPD Write Disable
BIOS Guard
Flash Wear Out Protection
CFG Lock
Me FW Image Re-Flash
MC Lock
Local FW Update

Then I’ve extracted list with all vars using H2OUVE tool (so this is probably the same thing as doing it through grub shell boot)

Looking at the SetupUtility I’ve found each variable in variable list and disabled every possible protection - basically changing 01’s to 00’s
Again using same H2OUVE I’ve pushed changes back to bios - successfully, no errors. Again extracted list to make sure that all vars was changed - yes it was.

Then removed secured boot and forced secure boot, removed all keys and etc.
Booted to system - success
launch CMD elevated
FPTW64.exe -d bios.bin -bios - success
FPTW64.exe -f bios.bin -bios - fail (Error 316: Protected Range Registers are currently set by BIOS, preventing flash access. Please contact the target system BIOS vendor for an option to disable Protected Range Registers. FPT Operation Failed.)

Then I’ve discovered this post by Wootever that there is FLOCKDN inside BiosRegionLockDxe, and I have the same structure inside - meaning that it is active.
And from this point I’m not sure how to proceed, because BiosRegionLockDxe doesn’t rely on any vars - there are just functions/routines and making changes inside this file and then inserting back to my bios backup via UEFITool it rebuilds bios completely - it’s not the same as changing vars.

Hope this explains :slight_smile:

So I’m curious how Wootever did that. If there is a method without SPI programmer…

https://forum.xda-developers.com/windows…air-13-t3659796

Is the issue of “BIOS Flash Protection” the same as this article? :slight_smile:

No. That is the article for unlocking 2016 model, which didn’t had FLOCKDN bit introduced.
For model 2018 it is not enough just to remove PRR.

I assume the PRR/FLOCKDN removal only applies to editing and then flashing the BIOS moving forward on next BIOS releases, once lock is removed in current onboard BIOS via flash programmer, but yes @Wootever will need to confirm if this is possible without a programmer

Hi,

Ok, so I bought SPI programmer and I removed FLOCKDN the same way Wootever did - it worked no more FLOCKDN after flashing modified BIOS. But now I’m not sure how to remove PRR0 and PRR1 protection.
Using RWEverything I’ve tried to search memory address SPIBAR + 0x84 (3800 + 84) and SPIBAR + 0x88 (3800 + 84), but everything was filled only with ‘AF’ values…
Anyone knows how to do it correctly?

/Ziga

Hi, I follow this tutorial but not works for me…
https://forum.xda-developers.com/showpos…79&postcount=20

I can’t flash .bin
https://github.com/daliansky/XiaoMi-Pro/issues/114

I would like delete whitelist from load wifi in m.2 port

@ziga34 - Looks like he used CHIPSEC, similar to RWEverytihng I think - https://github.com/chipsec/chipsec

@johnnync21 - You still need to do above too, aside from your whitelist mod if that is already done correctly.

I don’t know what you want to say… :frowning:

@Lost_N_BIOS @ziga34 I bought SPI programmer with clip. I have 12,5 6y30 and xiaomi mi air 2018 i7 8550. I would like know where is the chip to connect and if I can follow the tutorial

@johnnync21 - If you have programmer you do not need to unlock anything, only write in the BIOS you want already modified. I don’t know where the chip is, show me some images of your board and I can help you ID it

@Lost_N_BIOS
My Xiaomi mi air 2018

And IFR Extractor Variables

IMG-0030.JPG

setup IFR.txt (1.24 MB)

How can I search MC LOCK, CFG LOCK and more variables in ASP Programmer? It is in hexadecimal

I have a brick after flashing. My chip is a W25Q128JV. Can anyone help me? :frowning:

I was able to recover the laptop