最初看见俄国一份DELPHI代码这样实现,他的优点在于
  1, 在代理函数的内部不用先UNHOOK,再调用,再重新HOOK,否则多线程下会出问题
  2, 没有硬编码,结构性比较好。


bool AfxHookCode(void* TargetProc, void* NewProc,void ** l_OldProc, int bytescopy = 5)
{

  DWORD dwOldProtect;

  ::VirtualProtect((LPVOID)TargetProc, bytescopy, PAGE_EXECUTE_READWRITE, &dwOldProtect);

  *l_OldProc = new unsigned char[bytescopy+5];          // 为拷贝执行被覆盖的指令申请空间 


  memcpy(*l_OldProc, TargetProc, bytescopy);           // 事先保存被破坏的指令

  *((unsigned char*)(*l_OldProc) + bytescopy) = 0xe9;    // 我的内存的代码执行完 跳到原来的 代码 + 破坏的代码的长度 上去

                            //被破坏指令的长度     //E9 opcode长度          //算出偏移的OPCODE    = 被HOOK函数地址的地址 + 破坏指令的长度 - 我分配内存的结束地址                            
    *(unsigned int *)((unsigned char*)(*l_OldProc) +bytescopy          +     1)          =   (unsigned int)(TargetProc) + bytescopy - ( (unsigned int)((*l_OldProc)) + 5 + bytescopy ) ;  // 我内存代码跳到原来代码上的偏移


  *(unsigned char*)TargetProc =(unsigned char)0xe9;             //被HOOK的函数头改为jmp


                                  //算出偏移的OPCODE  = 代理函数地址 - 被HOOK函数地址
  *(unsigned int*)((unsigned int)TargetProc +1) = (unsigned int)NewProc - ( (unsigned int)TargetProc + 5) ; //被HOOK的地方跳到我的新过程 接受过滤


  ::VirtualProtect((LPVOID)TargetProc, bytescopy, dwOldProtect, 0);
  return true;
}


bool AfxUnHookCode(void* TargetAddress, void * l_SavedCode, unsigned int len)
{
    DWORD dwOldProtect;

    ::VirtualProtect((LPVOID)TargetAddress, len, PAGE_EXECUTE_READWRITE, &dwOldProtect);   

    // 恢复被破坏处的指令 
    memcpy(TargetAddress, l_SavedCode, len);

    ::VirtualProtect((LPVOID)TargetAddress, len, dwOldProtect, 0);

    return true;
}



unsigned int *  OldProc;
typedef 
int 
(__stdcall * MYMESSAGEBOX)     //用于调用自己分配内存处的代码强制转换
   (
    IN HWND hWnd,
    IN LPCSTR lpText,
    IN LPCSTR lpCaption,
    IN UINT uType);


int 
__stdcall       // 这里不声明成stdcall的话 编译器认为是C声明方式 要自己平衡堆栈  
MyMessageBox(
    IN HWND hWnd,
    IN LPCSTR lpText,
    IN LPCSTR lpCaption,
    IN UINT uType)
{

  // 这里可以执行一些过滤行为 比如改变参数 或者 直接模拟返回正确的结果
  if ( strcmp(lpText, "sample") == 0)
  {
    printf("filter");
    return 1;
  }


      //强制转换成API函数类型 调用原来的函数
   return ( (MYMESSAGEBOX) OldProc)(hWnd, lpText, lpCaption, uType);

}




int main()
{
  MessageBox(0, "sample", "caption", MB_OK);   //正常调用MSG

                                                                // 这里一定要传地址变量的地址  直接传地址的话 地址变量是一份拷贝 根本不能保存分配的内存的地址(在我看来 指针就是地址变量)
                                  //当初写的时候调了3遍才知道这个原因- -
  AfxHookCode((void*)MessageBox, (void*)MyMessageBox, (void**)&OldProc, 5);


  MessageBox(0, "sample", "caption", MB_OK);  //被过滤掉了

  AfxUnHookCode((void*)MessageBox, OldProc, 5); // 恢复被hook的代码

  getchar();

  return 0;
}

上传的附件 AfxHookCode VC++6.0工程.rar