2011-06-05 84 views
1

我不想绕过扫雷里面的PlaySoundW功能。 一旦它调用PlaySoundW函数,游戏就会崩溃。 如果我在我的代码中取消注释嘟嘟声,游戏会发出嘟嘟声而不是崩溃。MS Detours 2.1 - 弹出堆栈

现在代码正在从挂钩函数调用原始函数,所以它不应该做任何事情。但无论如何它正在崩溃。

你能告诉我什么是错的吗?

在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是否真的需要所有可怕的强制转换(函数指针)? – 2011-06-05 21:43:52

+1

@是的,和horrid是一个观点,就像Lisp的括号一样。 – 2011-06-05 21:44:27

+0

@Seth:*未定义的行为*不是一个观点。在函数指针和'void *'之间进行转换是未定义的行为。该代码是无效的C++。他们至少应该使用'FARPROC'(例如'GetProcAddress'返回),它保证了函数指针的大小。 – 2011-06-05 21:45:22

回答

2

尝试的HookPlaySoundW调用约定设置为__stdcall(因为PlaySoundW的CC也__stdcall(从Windows.h):WINMMAPI BOOL WINAPI PlaySoundW(__in_opt LPCWSTR pszSound, __in_opt HMODULE hmod, __in DWORD fdwSound);)。

我一直在走弯路之前和之后一起工作,除了上面提到的东西外,一切都看起来正确。如果这不能解决您的问题,我很乐意做一些进一步的调查。

为Visual C++的默认设置是__cdecl在通话* *清理堆栈,但在__stdcall通话* EE *清理堆栈。这可能是(,即可能是)所有“垃圾从堆栈中弹出”的原因。