用了detour,还有一些可以优化的地方。测试了可行性,可以跑起来就懒得再继续弄了。
BOOL isSoundDisable()
{
return PathFileExists(_T("C:\\a.txt"));
}
DWORD CreateSoudBuffer_Real = NULL; //保存着真正的CreateSoundBuffer方法的地址
DWORD UnLock_Real = NULL; //保存着真正的UnLock方法的地址
HRESULT WINAPI Mine_Unlock(LPVOID pDirectSoundBuffer, LPVOID lp1, DWORD dw1, LPVOID lp2, DWORD dw2)
{
//静音的实现是靠清空第二和第四个参数来实现
HRESULT hr;
if (isSoundDisable())
{
memset(lp1,0,dw1);
memset(lp2,0,dw2);
}
__asm
{
push dw2
push lp2
push dw1
push lp1
push pDirectSoundBuffer
mov eax,UnLock_Real
call eax
mov hr,eax
}
return hr;
}
HRESULT WINAPI Mine_CreateSoundBuffer(LPVOID pDS, LPCDSBUFFERDESC lpDSBufferDesc, LPDIRECTSOUNDBUFFER* ppDirectSoundBuffer, LPUNKNOWN pUnkOuter)
{
HRESULT hr = S_OK;
IDirectSoundBuffer *pDirectSoundBuffer = NULL;
DWORD dwpDirectSoundBuffer = (DWORD)&pDirectSoundBuffer;
__asm
{
push pUnkOuter
push dwpDirectSoundBuffer
push lpDSBufferDesc
push pDS
mov eax,CreateSoudBuffer_Real
call eax
mov hr,eax
}
*ppDirectSoundBuffer = pDirectSoundBuffer; //把参数传回去
DWORD * pUnLock = (DWORD*)(*((DWORD*)(pDirectSoundBuffer)) + 0x4C); // 0x4c = 4 * 19; 让pUnLock指向虚表UnLock
DWORD dwRet = 0;
VirtualProtectEx((HANDLE)-1,pUnLock,4,64,&dwRet);
if (NULL == UnLock_Real) //还没保存时表示第一次经过这里,需要把虚表的指针保存起来
{
UnLock_Real = *pUnLock; //把真正的值保存起来
//替换HOOK
}
*pUnLock = (DWORD)Mine_Unlock;
return hr;
}
MMRESULT (WINAPI * Real_waveOutWrite)(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) = waveOutWrite;
MMRESULT WINAPI Mine_waveOutWrite(HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)
{
if (isSoundDisable()) memset(pwh->lpData,0,pwh->dwBufferLength);
return Real_waveOutWrite(hwo,pwh,cbwh) ;
}
MMRESULT (WINAPI * Real_midiStreamOut)(HMIDISTRM hMidiStream,LPMIDIHDR lpMidiHdr,UINT cbMidiHdr) = midiStreamOut;
MMRESULT WINAPI Mine_midiStreamOut(HMIDISTRM hMidiStream, LPMIDIHDR lpMidiHdr,UINT cbMidiHdr)
{
if(isSoundDisable())memset(lpMidiHdr->lpData,0,lpMidiHdr->dwBufferLength);
return Real_midiStreamOut(hMidiStream,lpMidiHdr,cbMidiHdr);
}
HRESULT (WINAPI * Real_DirectSoundCreate)(LPCGUID lpGuid, LPDIRECTSOUND* ppDS, LPUNKNOWN pUnkOuter) = DirectSoundCreate;
HRESULT WINAPI Mine_DirectSoundCreate(LPCGUID lpGuid, LPDIRECTSOUND* ppDS, LPUNKNOWN pUnkOuter)
{
HRESULT hr;
IDirectSound *pDS;
hr = Real_DirectSoundCreate(lpGuid, &pDS, pUnkOuter);
*ppDS = pDS;
DWORD* pCreateSoundBuffer = NULL;
pCreateSoundBuffer = (DWORD*)(*((DWORD*)pDS) + 3*4); //保存CreateSoundBuffer的指针
if (NULL == CreateSoudBuffer_Real) //还没有取得过 CreateSoudBuffer_Real ,说明是第一次运行到这里,需要保存
{
DWORD dwRet;
VirtualProtectEx((HANDLE)-1,pCreateSoundBuffer,4,64,&dwRet);
CreateSoudBuffer_Real = *pCreateSoundBuffer;//把虚表中原来的函数的值保存起来,以备调用。
}
*pCreateSoundBuffer = (DWORD)Mine_CreateSoundBuffer; //直接把虚表中的值替换(Hook)
return hr;
}
void HookSound()
{
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)Real_waveOutWrite, Mine_waveOutWrite);
DetourAttach(&(PVOID&)Real_midiStreamOut, Mine_midiStreamOut);
DetourAttach(&(PVOID&)Real_DirectSoundCreate, Mine_DirectSoundCreate);
DetourTransactionCommit();
}