Winflash/AwdFlash是Windows下和dos下的BIOS刷新工具。
在windows下,刷新BIOS需要读写物理内存或IO端口。
在NT平台下,读写物理内存或IO端口需要驱动来支持(也可以使用/dev/PhysicalMemory来完成,但是2003sp1...)winflash使用驱动来实现物理内存/IO端口的读写,这一点很明显。
winflash/awdflash都是使用SMI Flash来进行BIOS刷新的。
对winflash/awdflash反汇编,都可以发现mov dx, ds:SMI_PORTmov al, 28hout dx, al ; manufacture's diagnostic checkpoint之类的字样.(开始还以为这是调试用的端口.../感谢网友 的文章。
) 废话就不说了,先看一下WinFlash的FlowChart吧: 直接将winflash拖到IDA中也可以,如果你能看得下去... winflash是经过加壳的,用PE Scan检测一下,aspack 2.12可直接脱壳,没有什么特殊的障碍... 在NT下,Winflash需要动态加载驱动,直接在代码中查找CreateService(),然后在逐级找到calller,hehe,最后来到如下位置 snyped:004029A0 084 mov ecx, esisnyped:004029A2 084 call check_OS_Versionsnyped:004029A2snyped:004029A7 084 mov ecx, esisnyped:004029A9 084 call Start_SYS_Driversnyped:004029A9snyped:004029AE 084 test al, alsnyped:004029B0 084 jnz short Check_Award_BIOSsnyped:004029B0snyped:004029B2 084 lea ecx, [ebp+var_74]snyped:004029B5 084 mov [ebp+var_4], 0FFFFFFFFhsnyped:004029BC 084 call CCommandLineInfo::~CCommandLineInfo(void) 有关MFC的东西不用管了,接着看下面主要是调用驱动的功能来读取物理内存的F000:0000段的内容,即SystemBIOS模块的内容(初始化后),从中获取BIOS/FlashROM的相关信息。
snyped:004029D4 Check_Award_BIOS: ; CODE XREF: CMainFrame_InitInstance+120jsnyped:004029D4 084 mov ecx, offset flash_info_structsnyped:004029D9 084 call PhysicalMemoryRead ;这里使用DeviceIoCtrl的222000h功能;读取0xF0000-0xFFFFF的内存到用户态缓冲区snyped:004029D9snyped:004029DE 084 mov ecx, offset flash_info_structsnyped:004029E3 084 call Get_Award_Modular_Sig ;此函数从读取的0xF000段数据中获取BIOS信息;snyped:004029E3snyped:004029E8 084 test al, alsnyped:004029EA 084 jnz short BIOS_is_Awardsnyped:004029EAsnyped:004029EC 084 push offset s_XBiosAwardGb ; " 本机主板 BIOS 不是 Award 的!
"snyped:004029F1 088 push 1 ; intsnyped:004029F3 08C push 0 ; intsnyped:004029F5 090 mov ecx, esisnyped:004029F7 090 call ErrorDialog__1snyped:004029F7snyped:004029FC 084 lea ecx, [ebp+var_74]snyped:004029FF 084 mov [ebp+var_4], 0FFFFFFFFhsnyped:00402A06 084 call CCommandLineInfo::~CCommandLineInfo(void) 在上面的代码中,最重要的函数就是0x004029E3 位置调用的函数snyped:004011D0 Get_Award_Modular_Sig proc near ; CODE XREF: CMainFrame_InitInstance+153psnyped:004011D0 ; sub_4033A0+8psnyped:004011D0 000 push esisnyped:004011D1 004 mov esi, ecxsnyped:004011D3 004 mov ds:byte_44FB08, 0snyped:004011DA 004 mov eax, [esi+4]snyped:004011DD 004 push eaxsnyped:004011DE 008 call check_Award_Modular_BIOS_Sig ;当找到"Award Modular BIOS"字符串时,此函数返回1snyped:004011DEsnyped:004011E3 004 test al, alsnyped:004011E5 004 jnz short loc_4011E9 ;AwdBIOS,在这里跳转snyped:004011E5snyped:004011E7 004 pop esisnyped:004011E8 000 retnsnyped:004011E8snyped:004011E9 ; ---------------------------------------------------------------------------snyped:004011E9snyped:004011E9 loc_4011E9: ; CODE XREF: Get_Award_Modular_Sig+15jsnyped:004011E9 004 mov ecx, esisnyped:004011EB 004 call GetSMI_Port ;在Offset_" $@AWDFLASH"+0x2A 位置获取SMI_PORTsnyped:004011EBsnyped:004011F0 004 mov ecx, esi等snyped:004011F2 004 call GetFlashInfo ;由"KAFLASH" 获取BIOS FlashROM信息,包括FlashROM 大小,Base Addrsnyped:004011F2snyped:004011F7 004 mov ecx, esisnyped:004011F9 004 call GetDecompressInfo ;暂时这样认为,获取DecompressBlock的起始位置...(?
?
?
?
)snyped:004011F9snyped:004011FE 004 mov al, 1snyped:00401200 004 pop esisnyped:00401201 000 retnsnyped:00401201snyped:00401201 Get_Award_Modular_Sig endp
获取了BIOS和FlashROM的相关信息后,下面是设置驱动的全局变量,SMI_PORT其中IoCtlCode:222004h-->设置驱动的全局变量,(in/out Buffer见下面)222008h-->调用SMI_0x2E功能
snyped:00402A1E BIOS_is_Award: ; CODE XREF: CMainFrame_InitInstance+15Ajsnyped:00402A1E 084 cmp ds:Window_Version, 2000hsnyped:00402A28 084 jnz short SMI_0x2E_Func_0snyped:00402A28snyped:00402A2A 084 mov ax, ds:SMI_PORTsnyped:00402A30 084 lea ecx, [ebp+BytesReturned]snyped:00402A33 084 mov edi, ds:DeviceIoControlsnyped:00402A39 084 push 0 ; lpOverlappedsnyped:00402A3B 088 push ecx ; lpBytesReturnedsnyped:00402A3C 08C push 0 ; nOutBufferSizesnyped:00402A3E 090 push 0 ; lpOutBuffersnyped:00402A40 094 lea edx, [ebp+SMI_Port]snyped:00402A43 094 mov word ptr [ebp+SMI_Port], axsnyped:00402A47 094 mov eax, ds:hDevicesnyped:00402A4C 094 push 2 ; nInBufferSizesnyped:00402A4E 098 push edx ; lpInBuffersnyped:00402A4F 09C push 222004h ;
winflash.exe是请求winflash.sys来完成Flash的,直接静态反汇编winflash.sys即可(文件很简单,是个普通的driver/文件很小...) 至于各个寄存器的设置,反汇编的代码里看得很清楚了。
如果有疑问,可以使用softice调试一下:做法是在winflash刷新的时候,ctrl+d,然后addr winflashmod winflash.sys找到winflash的加载基址然后根据IDA反汇编的代码偏移计算出需要中断的代码位置,然后bpx即可.(也可以直接单步跟踪,如果你很有耐心的话...) 这样,winfash的FlowChart基本上出来了你也可以自己写一个Flash BIOS的程序(前提是awd/SMI Flash...) 不想说废话了这里加一个自己部分注释的winflash.* 的IDB(适用于IDA5)地址.link: winflash_unpack.idb http://xxx link: winflash_sys.idb http://xxx //后面提供一个集中下载的位置...
