win32k.sys のハック方法

User32.dll や gdi32.dll は win32k.sys を介して、カーネルモードに入って、Kernel API 関数をコールします。

実際にどんなふうに関数が呼ばれているか、普通の Visual Studio のデバッガでは見ることが難しいので解説してみることにします。


例えば、 User32.dll の DisableProcessWindowsGhosting を例にとってみましょう。

 DisableProcessWindowsGhosting:
          push    00000002h
          call    SUB_L77CF84C2
          retn

 SUB_L77CF84C2:
          mov    eax,00001142h
          mov    edx,7FFE0300h
          call    [edx]
          retn    0004h

パラメータ 2を渡して、システムコール  1142h が呼び出されています

Windows WIN32K.SYS System Call Table (NT/2000/XP/2003/Vista/2008/7)
上記のソースは XP なので、 1142hをチェックすると、NtUserCallNoParam であることがわかります。

Win32k/syscalls の Windows 2000 に関する情報

1142h (0x2)は _DisableProcessWindowsGhosting に間違いないですね。

1142h は win32k.sys の関数テーブルとしてコールされます。
KeAddSystemServiceTable を探してみると、

          push    edi
          push    LBF99E490
          push    [LBF99E48C] // テーブルの数=29bh
          mov    [LBF9A8AB8],esi
          push    esi
          push    LBF99D780 //テーブルのオフセット
          call    [ntoskrnl.exe!KeAddSystemServiceTable]

テーブルのオフセットがありました。

関数 1142hは 0x142+1番目の関数なので、323番目のテーブルアドレスを見てみましょう。

 LBF8010B7:
          push    ebp
          mov    ebp,esp
          push    esi
          push    edi
          call    SUB_LBF800ACA
          mov    edi,[ebp+08h]
          cmp    edi,0000001Eh
          jnc    LBF8010EE
          call    [LBF993978+edi*4]
          cmp    edi,00000002h
          mov    esi,eax
          jc     LBF8010E6
 LBF8010D9:
          call    SUB_LBF800AF6
          pop    edi
          mov    eax,esi
          pop    esi
          pop    ebp
          retn    0004h

こんな感じのコードになっています。XPの場合、NtUserCallNoParam の関数番号は最大 0x1d までなので、第1引数が 0x1e 以上の場合は何もせずに終了しています。

 LBF993978:
         dd    SUB_LBF832AAF
         dd    LBF8918CA
         dd    LBF9343E1
         dd    LBF80A748
         dd    LBF917229
         dd    SUB_LBF8A2CAB
         dd    LBF9336E3
         dd    SUB_LBF92B694
         dd    LBF91AE56
         dd    SUB_LBF81C2D8
         dd    LBF8D737E
         dd    LBF8D051E
         dd    LBF884FAC
         dd    SUB_LBF89D359
         dd    LBF91D14D
         dd    LBF8767C4
         dd    LBF918CB5
         dd    LBF919972
         dd    LBF91905E
         dd    LBF919293
         dd    LBF9192D0
         dd    LBF919379
         dd    LBF91941C
         dd    LBF9194F4
         dd    LBF859473
         dd    LBF87BEA1
         dd    SUB_LBF893AF7
         dd    LBF87684E
         dd    LBF873D62
         dd    SUB_LBF80D1B8

関数 0x2h は 3番目の関数なので、LBF993978 の 3番目のテーブルを見てみると何をやってるかわかります。

 LBF9343E1:
          call    [ntoskrnl.exe!PsGetCurrentProcess]
          push    eax
          call    [ntoskrnl.exe!PsGetProcessWin32Process]
          add    eax,00000190h
          or    dword ptr [eax],00000001h
          retn

これが関数の中身ということになります。

仮にユーザーモード関数で置き換えるとしたら、

          mov    eax,fs:[00000124h]
          mov    eax,[eax+000001ECh]
          mov    eax,[eax+0
0000130h]
          or    dword ptr [eax+00000190h],1
          retn

こうですかね|。・ω・) (ユーザーモードだと最初が0になるので実際はおっこちますが)

おすすめ

コメントを残す

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