源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

C++封装IATHOOK类实例

  • 时间:2021-02-21 08:04 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:C++封装IATHOOK类实例
本文实例讲述了C++封装IATHOOK类的实现方法。分享给大家供大家参考。具体方法如下: 1. 定义成类的静态成员,从而实现自动调用
[u]复制代码[/u] 代码如下:
static CAPIHOOK sm_LoadLibraryA;  static CAPIHOOK sm_LoadLibraryW;  static CAPIHOOK sm_LoadLibraryExA;  static CAPIHOOK sm_LoadLibraryExW;  static CAPIHOOK sm_GetProcAddress;
2. ReplaceIATEntryInAllMods中遍历模块的框架
[u]复制代码[/u] 代码如下:
void CAPIHOOK::ReplaceIATEntryInAllMods(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, BOOL bExcludeAPIHookMod)  {      //取得当前模块句柄      HMODULE hModThis = NULL;      if (bExcludeAPIHookMod)      {          MEMORY_BASIC_INFORMATION mbi;          if (0 != ::VirtualQuery(ReplaceIATEntryInAllMods, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) //ReplaceIATEntryInAllMods必须为类的static函数          {              hModThis = (HMODULE)mbi.AllocationBase;          }      }      //取得本进程的模块列表      HANDLE hModuleSnap = INVALID_HANDLE_VALUE;       MODULEENTRY32 me32;      hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());      if (INVALID_HANDLE_VALUE == hModuleSnap)      {          return;      }      me32.dwSize = sizeof( MODULEENTRY32 );       if( !Module32First( hModuleSnap, &me32 ) )       {           return;      }      do       { //对每一个模块          if (me32.hModule != hModThis)          {              ReplaceIATEntryInOneMod(pszExportMod, pfnCurrent, pfnNewFunc, me32.hModule);          }      } while( Module32Next( hModuleSnap, &me32 ) );           ::CloseHandle(hModuleSnap); //配对写    }
3. 遍历链表摘除自己的框架
[u]复制代码[/u] 代码如下:
CAPIHOOK::~CAPIHOOK(void)  {      //取消对函数的HOOK      ReplaceIATEntryInAllMods(m_pszModName, m_pfnHook, m_pfnOrig, TRUE);        //把自己从链表中删除      CAPIHOOK* p = sm_pHeader;      if (p == this)      {          sm_pHeader = this->m_pNext;      }      else      {          while(p != NULL)          {              if (p->m_pNext == this)              {                  p->m_pNext = this->m_pNext;                  break;              }              p = p->m_pNext;          }      }  }
4. 在cpp中静态变量写好后,再编译,不然容易出现LINK错误
[u]复制代码[/u] 代码如下:
CAPIHOOK *CAPIHOOK::sm_pHeader = NULL;
源码: .cpp源文件如下:
[u]复制代码[/u] 代码如下:
#include "APIHOOK.h"  #include <Tlhelp32.h>    CAPIHOOK *CAPIHOOK::sm_pHeader = NULL;  CAPIHOOK CAPIHOOK::sm_LoadLibraryA("kernel32.dll", "LoadLibraryA", (PROC)CAPIHOOK::LoadLibraryA, TRUE);  CAPIHOOK CAPIHOOK::sm_LoadLibraryW("kernel32.dll", "LoadLibraryW", (PROC)CAPIHOOK::LoadLibraryW, TRUE);  CAPIHOOK CAPIHOOK::sm_LoadLibraryExA("kernel32.dll", "LoadLibraryExA", (PROC)CAPIHOOK::LoadLibraryExA, TRUE);  CAPIHOOK CAPIHOOK::sm_LoadLibraryExW("kernel32.dll", "LoadLibraryExW", (PROC)CAPIHOOK::LoadLibraryExW, TRUE);  CAPIHOOK CAPIHOOK::sm_GetProcAddress("kernel32.dll", "GetProcAddress", (PROC)CAPIHOOK::GetProcess, TRUE);  CAPIHOOK::CAPIHOOK(LPTSTR lpszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod)  {      //初始化变量      m_pszModName = lpszModName;      m_pszFuncName = pszFuncName;      m_pfnOrig = ::GetProcAddress(::GetModuleHandleA(lpszModName), pszFuncName);      m_pfnHook = pfnHook;        //将此对象加入链表中      m_pNext = sm_pHeader;      sm_pHeader = this;        //在当前已加载的模块中HOOK这个函数      ReplaceIATEntryInAllMods(lpszModName, m_pfnOrig, m_pfnHook, bExcludeAPIHookMod);  }    CAPIHOOK::~CAPIHOOK(void)  {      //取消对函数的HOOK      ReplaceIATEntryInAllMods(m_pszModName, m_pfnHook, m_pfnOrig, TRUE);        //把自己从链表中删除      CAPIHOOK* p = sm_pHeader;      if (p == this)      {          sm_pHeader = this->m_pNext;      }      else      {          while(p != NULL)          {              if (p->m_pNext == this)              {                  p->m_pNext = this->m_pNext;                  break;              }              p = p->m_pNext;          }      }  }  //防止程序运行期间动态加载模块  void CAPIHOOK::HookNewlyLoadedModule(HMODULE hModule, DWORD dwFlags)  {      if (hModule!=NULL && (dwFlags&LOAD_LIBRARY_AS_DATAFILE)==0)      {          CAPIHOOK* p = sm_pHeader;  //循环遍历链表,对每个CAPIHOOK进入HOOK          if (p != NULL)            {              ReplaceIATEntryInOneMod(p->m_pszModName, p->m_pfnOrig, p->m_pfnHook, hModule);              p = p->m_pNext;          }      }  }  //防止程序运行期间动态调用API函数  FARPROC WINAPI CAPIHOOK::GetProcess(HMODULE hModule, PCSTR pszProcName)  {      //得到函数的真实地址      FARPROC pfn = ::GetProcAddress(hModule, pszProcName);      //遍历列表 看是不是要HOOK的函数      CAPIHOOK* p = sm_pHeader;      while(p != NULL)      {          if (p->m_pfnOrig == pfn) //是要HOOK的函数          {              pfn = p->m_pfnHook; //HOOK掉              break;          }          p = p->m_pNext;      }      return pfn;  }    void CAPIHOOK::ReplaceIATEntryInOneMod(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, HMODULE hModCaller)  {      IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hModCaller;      IMAGE_OPTIONAL_HEADER* pOpNtHeader = (IMAGE_OPTIONAL_HEADER*)((BYTE*)hModCaller + pDosHeader->e_lfanew + 24); //这里加24      IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hModCaller + pOpNtHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);        BOOL bFindDll = FALSE;      while (pImportDesc->FirstThunk)      {          char* pszDllName = (char*)((BYTE*)hModCaller + pImportDesc->Name);            if (stricmp(pszDllName, pszExportMod) == 0)//如果找到pszExportMod模块,相当于hook messageboxa时的“user32.dll”          {              bFindDll = TRUE;              break;          }          pImportDesc++;        }        if (bFindDll)      {          DWORD n = 0;          //一个IMAGE_THUNK_DATA就是一个导入函数          IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hModCaller + pImportDesc->OriginalFirstThunk);          while (pThunk->u1.Function)          {              //取得函数名称              char* pszFuncName = (char*)((BYTE*)hModCaller+pThunk->u1.AddressOfData+2); //函数名前面有两个..              //printf("function name:%-25s,  ", pszFuncName);              //取得函数地址              PDWORD lpAddr = (DWORD*)((BYTE*)hModCaller + pImportDesc->FirstThunk) + n; //从第一个函数的地址,以后每次+4字节              //printf("addrss:%X\n", lpAddr);              //在这里是比较的函数地址              if (*lpAddr == (DWORD)pfnCurrent)  //找到iat中的函数地址              {                                                 DWORD* lpNewProc = (DWORD*)pfnNewFunc;                  MEMORY_BASIC_INFORMATION mbi;                  DWORD dwOldProtect;                  //修改内存页的保护属性                  ::VirtualQuery(lpAddr, &mbi, sizeof(MEMORY_BASIC_INFORMATION));                  ::VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect);                  ::WriteProcessMemory(GetCurrentProcess(), lpAddr, &lpNewProc, sizeof(DWORD), NULL);                  ::VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, NULL);                  return;              }                         n++; //每次增加一个DWORD          }         }  }    void CAPIHOOK::ReplaceIATEntryInAllMods(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, BOOL bExcludeAPIHookMod)  {      //取得当前模块句柄      HMODULE hModThis = NULL;      if (bExcludeAPIHookMod)      {          MEMORY_BASIC_INFORMATION mbi;          if (0 != ::VirtualQuery(ReplaceIATEntryInAllMods, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) //ReplaceIATEntryInAllMods必须为类的static函数          {              hModThis = (HMODULE)mbi.AllocationBase;          }      }      //取得本进程的模块列表      HANDLE hModuleSnap = INVALID_HANDLE_VALUE;       MODULEENTRY32 me32;      hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());      if (INVALID_HANDLE_VALUE == hModuleSnap)      {          return;      }      me32.dwSize = sizeof( MODULEENTRY32 );       if( !Module32First( hModuleSnap, &me32 ) )       {           return;      }      do       { //对每一个模块          if (me32.hModule != hModThis)          {              ReplaceIATEntryInOneMod(pszExportMod, pfnCurrent, pfnNewFunc, me32.hModule);          }      } while( Module32Next( hModuleSnap, &me32 ) );         ::CloseHandle(hModuleSnap); //配对写  }    //防止自动加载  HMODULE WINAPI CAPIHOOK::LoadLibraryA(LPCTSTR lpFileName)  {      HMODULE hModule = LoadLibraryA(lpFileName);      HookNewlyLoadedModule(hModule, 0); //这个函数中忆检测hModule 了      return hModule;  }  HMODULE WINAPI CAPIHOOK::LoadLibraryW(LPCTSTR lpFileName)  {      HMODULE hModule = LoadLibraryW(lpFileName);      HookNewlyLoadedModule(hModule, 0); //这个函数中忆检测hModule 了      return hModule;  }  HMODULE WINAPI CAPIHOOK::LoadLibraryExA(LPCTSTR lpFileName, HANDLE hFile,  DWORD dwFlags)  {      HMODULE hModule = LoadLibraryExA(lpFileName, hFile, dwFlags);      HookNewlyLoadedModule(hModule, dwFlags); //这个函数中忆检测hModule 了      return hModule;  }  HMODULE WINAPI CAPIHOOK::LoadLibraryExW(LPCTSTR lpFileName, HANDLE hFile,  DWORD dwFlags)  {      HMODULE hModule = LoadLibraryExW(lpFileName, hFile, dwFlags);      HookNewlyLoadedModule(hModule, dwFlags); //这个函数中忆检测hModule 了      return hModule;  }
.h头文件如下:
[u]复制代码[/u] 代码如下:
#pragma once  #include <Windows.h>    class CAPIHOOK  {  public:      CAPIHOOK(LPTSTR lpszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod = TRUE);      ~CAPIHOOK(void);    private:      static void ReplaceIATEntryInOneMod(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, HMODULE hModCaller);      static void ReplaceIATEntryInAllMods(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, BOOL bExcludeAPIHookMod);      //防止程序运行期间动态加载模块, 当一个新DLL被加载时调用      static void HookNewlyLoadedModule(HMODULE hModule,  DWORD dwFlags);        //跟踪当前进程加载新的DLL      static HMODULE WINAPI LoadLibraryA(LPCTSTR lpFileName);      static HMODULE WINAPI LoadLibraryW(LPCTSTR lpFileName);      static HMODULE WINAPI LoadLibraryExA(LPCTSTR lpFileName, HANDLE hFile,  DWORD dwFlags);      static HMODULE WINAPI LoadLibraryExW(LPCTSTR lpFileName, HANDLE hFile,  DWORD dwFlags);      //防止程序运行期间动态调用API函数 对于请求已HOOK的API函数,返回用户自定义的函数地址      static FARPROC WINAPI GetProcess(HMODULE hModule, PCSTR pszProcName);   private: //定义成静态的,会自动调用,从而实现自动HOOK      static CAPIHOOK sm_LoadLibraryA;      static CAPIHOOK sm_LoadLibraryW;      static CAPIHOOK sm_LoadLibraryExA;      static CAPIHOOK sm_LoadLibraryExW;      static CAPIHOOK sm_GetProcAddress;    private:      static CAPIHOOK* sm_pHeader; //钩子链表      CAPIHOOK* m_pNext;        //要钩子的函数      PROC m_pfnOrig;      PROC m_pfnHook;        //要钩子的函数所在的dll      LPSTR m_pszModName;      //要钩子的函数名称      LPSTR m_pszFuncName;  };
希望本文所述对大家的C++程序设计有所帮助。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部