回 帖 发 新 帖 刷新版面

主题:<windows核心编程>上ApiHook.cpp 问题

/*********************************************************************** 
Module:  APIHook.cpp 
Notices: Copyright (c) 2000 Jeffrey Richter 
***********************************************************************/ 

#include "..\CmnHdr.h" 
#include  <ImageHlp.h > 
#pragma comment(lib, "ImageHlp") 

#include "APIHook.h" 
#include "..\04-ProcessInfo\Toolhelp.h" 

/////////////////////////////////////////////////////////////////////// 

// When an application runs on Windows 98 under a debugger, the debugger 
// makes the module 's import section point to a stub that calls the   
   desired  看不太明白,98下到底怎么了? 
// function. To account for this, the code in this module must do some  
   crazy  
// stuff. These variables are needed to help with the crazy stuff. 

// The highest private memory address (used for Windows 98 only) 
   PVOID CAPIHook::sm_pvMaxAppAddr = NULL; 

  const BYTE cPushOpCode = 0x68;   // The PUSH opcode on x86 platforms 

//////////////////////////////////////////////////////////////////////// 
// The head of the linked-list of CAPIHook objects 
CAPIHook* CAPIHook::sm_pHead = NULL; 
//////////////////////////////////////////////////////////////////////// 


CAPIHook::CAPIHook(PSTR pszCalleeModName, PSTR pszFuncName, PROC pfnHook,  
   BOOL fExcludeAPIHookMod) { 

   if (sm_pvMaxAppAddr == NULL) { 
      // Functions with address above lpMaximumApplicationAddress require 
      // special processing (Windows 98 only) 
      SYSTEM_INFO si; 
      GetSystemInfo(&si); 
      sm_pvMaxAppAddr = si.lpMaximumApplicationAddress; 
   } 

   m_pNext  = sm_pHead;    // The next node was at the head 
   sm_pHead = this;        // This node is now at the head 

   // Save information about this hooked function 
   m_pszCalleeModName   = pszCalleeModName; 
   m_pszFuncName        = pszFuncName; 
   m_pfnHook            = pfnHook; 
   m_fExcludeAPIHookMod = fExcludeAPIHookMod; 
   m_pfnOrig            = GetProcAddressRaw( 
      GetModuleHandleA(pszCalleeModName), m_pszFuncName); 
   chASSERT(m_pfnOrig != NULL);  // Function doesn 't exist 

   if (m_pfnOrig  > sm_pvMaxAppAddr) { 
      // The address is in a shared DLL; the address needs fixing up  
       //我知道98下的DLL共享, fixing up 具体是怎么回事?      
      PBYTE pb = (PBYTE) m_pfnOrig; 
      if (pb[0] == cPushOpCode) { 
         // Skip over the PUSH op code and grab the real address 
     上面注释的操作原理是什么?  
        PVOID pv = * (PVOID*) &pb[1]; 
         m_pfnOrig = (PROC) pv; 
      } 
   } 

   // Hook this function in all currently loaded modules 
   ReplaceIATEntryInAllMods(m_pszCalleeModName, m_pfnOrig, m_pfnHook,  
      m_fExcludeAPIHookMod); 


注:GetProcAddressRaw其实就是GetProcAddress 

比如我们要HOOK的API是fApi,它的地址是AddApi. 我们的替换函数地址是AddHook . 
(98下)调试器首先修改了IAT , 将AddApi改为AddDebugger . 

看书上代码, 在IAT中并不是按函数名fApi来进行搜索, 而是用GetProcAddress(fApi) 
获取fApi的地址AddApi, 再从IAT中寻找这个地址值(AddApi) , 找到了将该值后将其修改为AddHook. 

现在, 由于AddApi已被调试器改成了AddDebugger ,而我们执行GetProcAddress(fApi) 
获得的仍然是AddApi . 怎么办呢 ? 只能是设法知道AddDebugger是多少. 

书上获取AddDebugger的方法我实在是想不明白其原理 : 
查看AddApi处的第一条指令是不是push, 如是, 则push内容即为AddDebugger ... 

欢迎大家讨论,指教!

回复列表 (共6个回复)

沙发

up

板凳

再UP

3 楼

难道没有人研究过类似问题吗?

4 楼

快绝望了...

5 楼


       //我知道98下的DLL共享, fixing up 具体是怎么回事?      
      PBYTE pb = (PBYTE) m_pfnOrig; 
      if (pb[0] == cPushOpCode) { 
         // Skip over the PUSH op code and grab the real address 
     上面注释的操作原理是什么?  
        PVOID pv = * (PVOID*) &pb[1]; 
         m_pfnOrig = (PROC) pv; 
      } 
这段代码的意思可能是98下的汇编代码的第一个字节是push指令,第二个字节才是真正的函数入口,这可以通过VC断点调试,查看其虚拟内存地址。[em2]

6 楼

哈,这么久了还有人关注我的贴子,太感动了!

我来回复

您尚未登录,请登录后再回复。点此登录或注册