VideoPortInitialize にまつわるvmware ドライバの謎
VideoPortInitialize の 第一引数に 構造体サイズを設定するのですが
Windows 2000の videoprt.sys で 0x54 でも、エラーにならないように改造したら、VMWare のグラフィックドライバでBSoDになるようになってしまった。
というわけで、解析してみたよ。
mov esi,[VIDEOPRT.SYS!VideoPortInitialize] push 00000000h lea eax,[ebp-54h] push eax push [ebp+0Ch] mov dword ptr [ebp-4Ch],L000258C6 push [ebp+08h] mov dword ptr [ebp-48h],SUB_L00023972 mov dword ptr [ebp-44h],L00010EE2 mov dword ptr [ebp-40h],L00024580 mov dword ptr [ebp-34h],SUB_L00011250 mov dword ptr [ebp-28h],L00024262 mov dword ptr [ebp-24h],L00022FCE mov dword ptr [ebp-20h],L00022FE4 mov dword ptr [ebp-50h],00000005h mov dword ptr [ebp-54h],00000054h mov dword ptr [ebp-3Ch],0000AAC0h mov word ptr [L0001CB68],01FEh call esi test eax,eax jz L00026760 push 00000000h lea eax,[ebp-54h] push eax push [ebp+0Ch] mov dword ptr [ebp-54h],00000050h push [ebp+08h] mov word ptr [L0001CB68],01F4h call esi test eax,eax jz L00026760 push 00000000h lea eax,[ebp-54h] push eax push [ebp+0Ch] mov dword ptr [ebp-54h],00000028h push [ebp+08h] mov word ptr [L0001CB68],0190h |
赤が構造体サイズ。水色が成功したときの設定値
どういうことかというと、構造体サイズが 0x28/0x50/0x54 のときにそれぞれOSバージョンの判定として、それぞれ 510,500,400 を返しているんだな。
cmp word ptr [L0001CB68],01FEh jnz L00025AF5 push esi call SUB_L00023016 test al,al jz L00025AF5 push 0000001Fh push esi call SUB_L00010E82 push offset VideoPortCreateSecondaryDisplay push esi mov [L00013280],eax call [edi+60h] test eax,eax mov [ebp+14h],eax jz L00025AEA xor ebx,ebx inc ebx cmp [L00013280],ebx jle L00025A8A mov dword ptr [ebp+08h],L0001CD74 L00025A51: push 00000001h push [ebp+08h] push esi call [ebp+14h] test eax,eax mov [ebp+18h],eax jnz L00025A70 add dword ptr [ebp+08h],00000004h inc ebx cmp ebx,[L00013280] jl L00025A51 jmp L00025A8A L00025A70: push ebx push 0000001Fh push esi call SUB_L00010EB0 push [ebp+18h] push ebx push offset VideoPortCreateSecondaryDisplay_Fail call SUB_L00010A24 add esp,0000000Ch |
call [edi+60h] で エントリーポイントを取得してるのですが、
関数がないのを確認する前に水色の処理が走って、緑色のところに関数の実行結果が入るのですが、初期値は失敗の「1」が入ってるのですが、その後の処理で関数が成功したものとして「0」が入りそのまま処理されてしまうので、不具合が起こります
色々なパターンで実験してみました
1.最初の分岐で強制ジャンプ
2.緑の処理の直前に eax = 1 を代入
3.最初の分岐で強制ジャンプ させつつ L00013280 を 0 に設定する
4.call SUB_L00023016の直後にエラー処理に飛ばす
1と2と3は正常に動作
3は VGAモードになってしまいました。
というわけでこのドライバのバグです。詰めが甘いですね|。・ω・) ふふふ
この記事を読まずにvmware player で飼っていたwindows 2kに2012年7月のupdateでKB829884をあてBODを喰らってしまいました.uninstallフォルダーにあったvideoprt.sysを元に戻してどうやら回復したようです.このdriverのerrorは直りそうですか?