最初看见俄国一份DELPHI代码这样实现,他的优点在于
1, 在代理函数的内部不用先UNHOOK,再调用,再重新HOOK,否则多线程下会出问题
2, 没有硬编码,结构性比较好。
#include <iostream>
#include <stdio.h>
#include <windows.h>
using namespace std;
#define bt 5
unsigned int* Oldpro;
typedef int (_stdcall * MYMESSAGE)(IN HWND hWnd,
IN LPCSTR lpText,
IN LPCSTR lpCaption,
IN UINT uType);
int _stdcall Mymessage(HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType)
{
if(strcmp(lpText,"ooooo")==0)
{
cout<<"xxxx"<<endl;
return 1;
}
return int(((MYMESSAGE)Oldpro)(hWnd,lpText,lpCaption,uType));
}
bool ApiHook(LPVOID TargetPro,LPVOID NewPro,LPVOID* Oldpro)
{
DWORD dwOldpro;
BOOL nVirtual;
nVirtual=VirtualProtect(TargetPro,5,PAGE_EXECUTE_READWRITE,&dwOldpro);
if(nVirtual==0)
{
cout<<"virtualprotect error"<<endl;
return false;
}
*Oldpro=new unsigned char[bt+5];
memcpy(*Oldpro,TargetPro,bt);
*((unsigned char*)(*Oldpro)+5)=0xe9;
*((unsigned int*)(*Oldpro)+bt+1)=(unsigned int)(TargetPro)-(unsigned int)(*Oldpro)-5;
*(unsigned char*)TargetPro=0xe9;
*(unsigned int*)((unsigned int)TargetPro+1)=(unsigned int)(NewPro)-(unsigned int)(TargetPro)-5;
if(VirtualProtect(TargetPro,bt,dwOldpro,0))
{
cout<<"virtualprotect error"<<endl;
return false;
}
return true;
}
bool UnApiHook(LPVOID TargetPro,LPVOID Oldpro)
{
DWORD dwOldpro;
if(VirtualProtect(TargetPro,bt,PAGE_EXECUTE_READWRITE,&dwOldpro))
{
memcpy(TargetPro,Oldpro,bt);
if(VirtualProtect(TargetPro,bt,dwOldpro,0))
{
return true;
}
}
return false;
}
void main()
{
MessageBox(NULL,"xxxxx","before hook",MB_OK);
if(ApiHook(MessageBox,(void*)Mymessage,(LPVOID*)&Oldpro))
{
cout<<"sucess"<<endl;
}
MessageBox(NULL,"ooooo","after hook",MB_OK);
UnApiHook(MessageBox,Oldpro);
}