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モードになってしまいました。

というわけでこのドライバのバグです。詰めが甘いですね|。・ω・) ふふふ

おすすめ

1件の返信

  1. nikonikopan より:

    この記事を読まずにvmware player で飼っていたwindows 2kに2012年7月のupdateでKB829884をあてBODを喰らってしまいました.uninstallフォルダーにあったvideoprt.sysを元に戻してどうやら回復したようです.このdriverのerrorは直りそうですか?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です