最近在操作一台Dell Vostro 2420笔记本电脑时,遇到了BIOS降级的棘手难题。因特定需要将BIOS升级至A07版本后,试图降回更低版本却发现无法实现——最初使用的备份软件生成的恢复文件完全失效(升级时未仔细核对,很可能程序与主板型号不兼容)。尝试了网上常见的刷BIOS工具与方法(包括DOS环境下的AFUDOS.exe),均告失败,着实令人困扰。
首先检查了另一台同型号电脑的BIOS版本为A03,随后从戴尔官网下载了A03版本的更新程序(2420A03.EXE)。但运行时,程序直接弹出提示:“You are about to flash your BIOS to an older BIOS version. Dell does not recommend flashing your BIOS to an older version. Press OK button to exit.” 点击确定后程序立即退出——这种“自作主张”的设计实在令人恼火,凭什么禁止用户降级?
所有网上可用的工具在这台较新的笔记本上集体失灵,不得不考虑最稳妥的办法:直接使用戴尔官网的BIOS更新程序刷回(官网能下载到与机器严格匹配的版本)。但程序运行到最后总会弹出那个令人沮丧的提示并退出——唯一的出路就是:修改这个程序!定位弹出MessageBox的代码,反转其逻辑。这可谓是最后一根救命稻草,若失败只能接受现实,但终究值得一试。
启动IDA,加载2420A03.exe,分析完成。好消息是程序没有任何加密或自我保护机制,显然是直接编写而成,未考虑被修改的可能。查看资源发现包含多个对话框,似乎“封装”了ALUWINGUI程序(观察到ALUWINGUI的痕迹,例如对话框等)。但直接运行网上下载的ALUWINGUI总会死机,因此只能将注意力转回到反汇编分析2420A03.exe上。
弹出MessageBox的代码定位很容易——对话框文本明文存放在.rdata段,顺藤摸瓜找到.text地址0x00466E21处的关键跳转:
.text:00466E00 .text:00466E00 loc_466E00: ; CODE XREF: sub_466D40+9Fj .text:00466E00 ; sub_466D40+B7j .text:00466E00 push offset aWarning_4 ; "WARNING" .text:00466E05 lea eax, [ebp+Caption] .text:00466E0B push eax ; LPSTR .text:00466E0C call ds:wsprintfA .text:00466E12 add esp, 8 .text:00466E15 mov ecx, [ebp+var_10C] .text:00466E1B cmp ecx, [ebp+var_214] .text:00466E21 jnb loc_466EF0 ; 【重要】要修改的指令! .text:00466E27 movzx edx, word_5072F8 .text:00466E2E and edx, 80h .text:00466E34 jz short loc_466E93 .text:00466E36 push offset aWarning_5 ; "WARNING!!" .text:00466E3B lea eax, [ebp+Caption] .text:00466E41 push eax ; LPSTR .text:00466E42 call ds:wsprintfA .text:00466E48 add esp, 8 .text:00466E4B push offset aYouAreAboutToF ; "You are about to flash your BIOS to an "... .text:00466E50 lea ecx, [ebp+Text] .text:00466E56 push ecx ; LPSTR .text:00466E57 call ds:wsprintfA .text:00466E5D add esp, 8 .text:00466E60 push 31h ; uType .text:00466E62 lea edx, [ebp+Caption] .text:00466E68 push edx ; lpCaption .text:00466E69 lea eax, [ebp+Text] .text:00466E6F push eax ; lpText .text:00466E70 push 0 ; hWnd .text:00466E72 call ds:MessageBoxA .text:00466E78 cmp eax, 1 .text:00466E7B jnz short loc_466E87
浏览整个函数即可发现,第11行的jnb loc_466EF0正是关键分支点。若var_10C < var_204(即当前版本高于待刷版本),程序便会进入弹出MessageBox的路径;否则跳转至0x466EF0执行正常刷写。因此只需将jnb改为jb,逻辑即被反转——将刷低版本视为刷高版本,从而绕过限制。
修改汇编指令需参考Intel官方文档《64 IA-32 Architectures Software Developer Manual 325462》。IDA中显示jnb loc_466EF0对应的字节序列为:0F 83 C9 00 00 00。前两个字节0F 83为JNB的操作码,后四个字节C9 00 00 00表示偏移量0xC9(201字节)。
有多种修改方案可供选择:
(1)将JNB改为JB(操作码0F 82)——仅在待刷版本低于当前版本时执行刷写。
(2)改为JNZ(0F 85)——只要版本不同即执行刷写。
(3)改为JMP(E9)——无条件刷写,但需补充一个NOP,且可能需要处理版本相等的情况。
这里采用方案(1)。使用UltraEdit打开exe文件,IDA显示的地址为进程空间逻辑地址,减去ImageBase(0x00400000)得到文件偏移0x00066E21。跳转到文件地址0x00066E20处,将第二个字节开始的6个字节0F 83 C9 00 00 00改为0F 82 C9 00 00 00(仅修改文件地址0x00066E22处的字节,从0x83变为0x82),JNB即变为JB。
修改后运行程序,那个烦人的MessageBox不再弹出,而是显示系统正在关机的提示——有希望了!系统自动重启后,进入BIOS刷新界面(如下图),大约一两分钟便完成。重启进入BIOS查看版本信息,已顺利回到A03,一切正常。

至此,刷回低版本BIOS的操作完成。其他版本的BIOS降级遇到类似限制时,原理相同——只要这些更新程序未对修改设置障碍,具备一定汇编知识,借助工具即可轻松修改这一逻辑。此处忍不住吐槽一下戴尔的设计:自由选择权应交给用户。当然,刷BIOS确实存在风险,除非有特殊需求(例如激活Windows 7及以上系统),并且有成功把握,否则不建议轻易尝试。关于激活Windows 7,目前几乎所有软破解和网上流传的Key均已失效,剩下的唯一途径是从BIOS入手(软刷或硬刷添加SLIC 2.1),模拟大厂OEM产品。虽然采用这种方式激活的用户数量庞大,但混杂在更多正版OEM产品中,Windows的认证技术尚不足以区分,因此这种“盗版”几乎可以认为是安全的。
【补充资料】BiosFix工具下载链接
该程序是一个命令行辅助工具。由于BIOS程序仅需调整一两条指令的机器码(1~2个字节),借助该工具,只需提供Fix信息,用户即可自行完成修改,无需上传较大的文件。附件中包含程序、配置文件、源代码及使用说明。
使用方式:
命令行格式:BiosFix.EXE "XXXX.EXE"
例如:BiosFix.EXE "D:\M8888A03.EXE"
输出文件为:"D:\M8888A03_Fixed.EXE"
若直接双击程序,会提示手动输入路径(不需要双引号)。例如在cmd中输出:
>BiosFix Input the source bios file[XXX.exe] to fix: >E:\Bios_Fix\5437A00.EXE ImageBase: 00400000H NumberOfSections: 4 ----------------[FixNo: 01]----------------- VA: 004693B1H FA: 00068DB1H Overwrite 2 Bytes (JNB->JNZ); ----------------[Fix Completed!]----------------- The Fixed File is: E:\Bios_Fix\5437A00_Fixed.EXE
以上便是戴尔笔记本刷回低版本BIOS的详细教程。
