希望能够帮帮小弟
程序源代码:
void CTestAPIDlg::OnHook() 

// TODO: Add your control notification handler code here 
HMODULE m_hdl = GetModuleHandle(NULL); 
HMODULE m_hdldll=LoadLibrary("User32.dll"); 
FARPROC m_ProAdd = GetProcAddress(m_hdldll,"MessageBoxA"); //pf*m_pf=MessageBoxQ; 
//fp=MessageBox; 
ReplaceIATEntryInOneMod("User32.dll" , m_ProAdd , (PROC)MessageBoxQ , m_hdl); 
} void CTestAPIDlg::ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller) 

    ULONG ulSize;   PIMAGE_IMPORT_DESCRIPTOR pImportDesc = NULL; 
  __try { 
      pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData( 
        hmodCaller, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize); 
  } 
  __except (InvalidReadExceptionFilter(GetExceptionInformation())) { 
  
  } 
  
  if (pImportDesc == NULL) 
      return;  // This module has no import section or is no longer loaded   for (; pImportDesc->Name; pImportDesc++) 
  { 
      PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name); 
      if (lstrcmpiA(pszModName, pszCalleeModName) == 0) 
  {         PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) 
            ((PBYTE) hmodCaller + pImportDesc->FirstThunk);         // Replace current function address with new function address 
        for (; pThunk->u1.Function; pThunk++) 
{             // Get the address of the function address 
            PROC* ppfn = (PROC*) &pThunk->u1.Function;             // Is this the function we're looking for? 
            BOOL bFound = (*ppfn == pfnCurrent); 
            if (bFound) 

              if (!WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, sizeof(pfnNew), NULL) && (ERROR_NOACCESS == GetLastError())) 
  { 
                  DWORD dwOldProtect; 
                  if (VirtualProtect(ppfn, sizeof(pfnNew), PAGE_WRITECOPY, &dwOldProtect)) 
  { 
                    WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, sizeof(pfnNew), NULL); 
                    VirtualProtect(ppfn, sizeof(pfnNew), dwOldProtect, &dwOldProtect); 
                  } 
              } 
              return;  // We did it, get out 
            } 
        } 
      }  // Each import section is parsed until the right entry is found and patched 
  } 
}void CTestAPIDlg::OnMsgbox() 
{
// TODO: Add your control notification handler code here
MessageBoxA("没有被截取到!");
}

解决方案 »

  1.   

    听我说,你写一个基于WIN32的程序A,程序A里调用MessageBox,用这个程序做测试,因为MFC里调用的MessageBox不能捕获,理论上调用的都是那个全局的MessageBox,但却不捕获。不知道为啥。
      

  2.   


    MFC对MessageBox做了封装了的吧.
      

  3.   

    是做了封装,不过归根到底还是用的那个全局的MessageBox,因为动态链接时根据IAT里调用的还是USER32.DLL里面的MessagBoxA,W而已。
      

  4.   

    找到一个解释我来解释一下,这种现象是正常的你的hook是导入表hook说白了只能hook到程序静态引入的函数如果你在程序中使用::MessageBox则最终程序中确实引入了user32.dll中的MessageBoxA函数,这样可以hook到如果你用CWnd::MessageBox来调用就不行了或许你也知道CWnd::MessageBox最终也是调用了::MessageBox但是你的程序没有直接导入::MessageBox因为CWnd::MessageBox也是一个导出函数,具体名字大约是msvc60.dll之类的是一个MFC的支持库因此你hook导入表的时候根本找不到::MessageBox的引入而只能找到CWnd::MessageBox的引入(这个引入的名字很复杂,是变形过的)所以你的hook无法成功///////////////////////////////////////////////////////////////
    你所提到的问题恰恰是导入表式hook的局限性只有改变hook的形式才能根本上解决这个问题新的hook方式就是inline hook
      

  5.   

    对了,楼主想研究HOOK的话windows核心编程对API重定位有详细的解说,可以看一下
      

  6.   

    void CTestAPIDlg::OnMsgbox1() 

    // TODO: Add your control notification handler code here 
    MessageBox("谢谢!"); 
    } 这个MessageBox调用的是CWnd::MessageBoxA,可不是User32里面的MessageBoxA。IAT里面自然没有这个函数。MFC32.dll中的导出函数没有名字,所以只能用数字,这里MessageBox对应的是4224(我是VC6, Win2k3 SP1)。 强制hack的方法如下: OnHook: 
    HMODULE m_hdl = GetModuleHandle(NULL); 
    //去MFC42.dll中找(我调试的是Release版本,所以不是MFC42D.dll)CWnd::MessageBoxA 
    FARPROC m_ProAdd = GetProcAddress(LoadLibrary("MFC42.dll"),(LPCSTR)4224); 
    //然后以MessageBoxQ函数hook之 
    ReplaceIATEntryInOneMod("MFC42.dll" , m_ProAdd , (PROC)MessageBoxQ , m_hdl); MessageBoxQ函数要注意,没有四个参数了,因为hook的是CWnd类成员函数,所以有个this指针在ECX寄存器。我是这么写的: 
    int  WINAPI  MessageBoxQ(LPCTSTR lpText,LPCTSTR lpCaption,UINT uType) 
    {  
        //break in debugger 
        __asm int 3; 
        return  0;  
      

  7.   

    怎么会是这样的,一样是可以的吧?在MFC中的MessageBoxA不就是经过封装了而已,但是在里面还是调用win32 MessageBoxA这个API吧,我刚刚测试过就没问题,你可以去下载个<windows 核心编程>的源码看下他是怎么拦截API的
      

  8.   

    我经过测试,成功HOOK到了MFC里的CWnd::MessageBox(),CWnd的实际是调用了SDK里面的MessageBox,你可以查看MFC提供的源码,它的实现在WINCORE.CPP,可以清楚的看到它调用了sdk的,由于一般写MFC程序时,appwizard最后一步是都用动态链接,如果改成静态链接就可以HOOK到!
    为什么动态链接就HOOK不到,还不清楚!或许可以只是方法不对,还待研究