DEP と mofooter その2

        SPDEP=GetProcAddress(hDll,"SetProcessDEPPolicy");
00401A6A 8B F4            mov         esi,esp
00401A6C 68 F0 59 4A 00   push        offset "SetProcessDEPPolicy"
00401A71 8B 45 C8         mov         eax,dword ptr [hDll]
00401A74 50               push        eax 
00401A75 FF 15 40 EC 4B 00 call        dword ptr [GetProcAddress]
00401A7B 3B F4            cmp         esi,esp
00401A7D E8 4E 07 05 00   call        _RTC_CheckEsp
00401A82 89 45 EC         mov         dword ptr [SPDEP],eax
        if(SPDEP){
00401A85 83 7D EC 00      cmp         dword ptr [SPDEP],0
00401A89 74 05            je          initialize_findacx+0A0h
            _asm{
                push 0
00401A8B 6A 00            push        0   
                call SPDEP
00401A8D FF 55 EC         call        dword ptr [SPDEP]
            }

以前 書いた記事で DEP回避用に、 SetProcessDEPPolicy を使うという話がありました

DEP と mofooter

ところが、Windows 7 でこの関数呼ぶと、落とされるという事が判明!

正しくは、
・SetProcessDEPPolicyを呼ぶのは問題ない。
・GetSystemDEPPolicyで呼び出して得た値を、SetProcessDEPPolicy に書き戻したらダメってことでした。

bex
bex2

素直にDEPリストに追加した方がよさそうですね。

Windows 7のデータ実行防止リストのGUIいじってたら、定義が消せなくなって、正常に動作しなくなってしまった(汗)これはひどいバグ。

HKEY_LOCAL_MACHINE の SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers に定義が保存されているので、おかしくなったら 手動で削除してみましょう。

今から備えるWindows Server 2003 SP1(第4回=最終回) - Windows2003:ITpro

おすすめ

4件のフィードバック

  1. えむけい より:

    VirtualProtect使いましょうよ。Win95でも実装されていないだけでエントリポイントは存在するので、関数の存在チェックは不要です。

  2. blackwingcat より:

    いあ、そのVirtualProtect を使うとDEPが有効になってる場合例外で落っこちるんですよ。
    i=(FARPROC)&_imp__IsDebuggerPresent;
    VirtualProtect(i, sizeof(FARPROC), PAGE_READWRITE, &dw);
    *(FARPROC*)i=(FARPROC)&IsDebuggerPresent_stub;
    VirtualProtect(i, sizeof(FARPROC), dw, NULL);
    ↑DEP有効時はこのコードでBEX例外

  3. えむけい より:

    2つ目のVirtualProtectが失敗して、__imp__IsDebuggerPresentに実行属性が戻されないまま呼び出されてDEPに落とされているのではないでしょうか。
    http://msdn.microsoft.com/ja-jp/library/cc430214.aspx
    > lpflOldProtect
    > 指定されたページ領域の最初のページの以前のアクセス保護値が書き込まれる変数へのポインタを指定します。このパラメータが NULL の場合や、有効な変数を指していない場合、関数は失敗します。
    VirtualProtectは周囲4KB(1ページ全体)の保護属性を書き換えるので、__imp__VirtualProtectの実行属性が巻き添えで落とされている可能性が高いです。その場合、当然二度目のVirtualProtect呼び出しでDEPに引っかかります。
    一度目のVirtualProtect呼び出しでは保護属性の指定をPAGE_READWRITE_EXECUTEにする必要がありそうです。
    あと書き込みはポインタアクセスではなくWriteProcessMemory(GetCurrentProcess(),…)で行う必要があるかと。

  4. blackwingcat より:

    ありがとうございます。
    検証を新しい記事にまとめました。

コメントを残す

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