2011-06-05 4 views
1

私はMinesweeper内でPlaySoundW機能を迂回することはありません。 PlaySoundW関数を呼び出すとすぐにゲームがクラッシュします。 コード内でビープ音のコメントを外すと、ビープ音が鳴り、クラッシュします。MS Detours 2.1 - スタックからの飛び出し

今、コードはhooked関数から元の関数を呼び出すので、何もしないでください。しかし、とにかくそれはクラッシュしています。

あなたは何が間違っているのか教えていただけますか?

Ollyでアプリをデバッグした後、私は、迂回がアクティブなときにすべてのごみがスタックから飛び出さないことを発見しました。 修正方法?

は、これは私のコードです:

#include <Windows.h> 
#include <tchar.h> 
#include <detours.h> 

namespace Hooks 
{ 
    BOOL(__stdcall *OrgPlaySoundW)(LPCTSTR pszSound, HMODULE hmod, DWORD fdwSound) = &PlaySoundW; 

    BOOL HookPlaySoundW(LPCTSTR pszSound, HMODULE hmod, DWORD fdwSound) 
    { 
     //Beep(1000, 250); 
     //return TRUE; 
     return OrgPlaySoundW(pszSound, hmod, fdwSound); 
    } 

    void DetourPlaySoundW(BOOL disable) 
    { 
     if(!disable) 
     { 
      DetourTransactionBegin(); 
      DetourUpdateThread(GetCurrentThread()); 
      DetourAttach(&(PVOID&)OrgPlaySoundW, &HookPlaySoundW); 
      DetourTransactionCommit(); 
     } else 
     { 
      DetourTransactionBegin(); 
      DetourUpdateThread(GetCurrentThread()); 
      DetourDetach(&(PVOID&)OrgPlaySoundW, &HookPlaySoundW); 
      DetourTransactionCommit(); 
     } 
    } 
} 

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 
{ 
    switch(fdwReason) 
    { 
    case DLL_PROCESS_ATTACH: 
     Hooks::DetourPlaySoundW(FALSE); 
     break; 
    case DLL_PROCESS_DETACH: 
     Hooks::DetourPlaySoundW(TRUE); 
     break; 
    } 
    return TRUE; 
} 
+0

Detoursは実際には(関数ポインタの)それほど恐ろしいキャストを必要としますか? –

+1

@Benはい、horridはLispのかっこのような視点です。 –

+0

@Seth:*未定義の動作*は視点ではありません。関数ポインタと 'void *'の間のキャストは未定義の動作です。そのコードはC++ではありません。彼らは少なくとも関数ポインタの正しいサイズであることが保証されている 'FARPROC'(' GetProcAddress'が返すようなもの)を使うべきです。 –

答えて

2

PlaySoundWのCCも__stdcallであるため)Windows.hから(:WINMMAPI BOOL WINAPI PlaySoundW(__in_opt LPCWSTR pszSound, __in_opt HMODULE hmod, __in DWORD fdwSound);__stdcallHookPlaySoundWの呼び出し規約を設定してみてください。

私は上記のことを除いて、カジュアルな視線の前後に迂回路で作業しました。これで問題が解決しない場合は、さらに調査をしてうれしいです。

のVisual C++のデフォルト設定は、コール* ER *がスタックをクリーンアップしますが、__stdcallに呼び出し* EE *がスタックをクリーンアップする__cdeclあります。おそらく(、すなわちの可能性があります)すべての「ごみがスタックからポップされた」理由です。

関連する問題