首页 网络安全 安全学院 查看内容

简单Hook api 的实现

2009-6-26 09:38 653 0

摘要:   小菜最近在学习pe文件结构和windows编程 就写了如下代码 检验一下学习成果  ////////////////////////////////////  //HookDemo.cpp文件  ...
关键词: 函数 DWORD IMAGE pImportDesc MessageBoxA lpAddr hMod HookDemo MyMessageBoxA dwOldProtect

  小菜最近在学习pe文件结构和windows编程 就写了如下代码 检验一下学习成果  ////////////////////////////////////  //HookDemo.cpp文件  #include <windows.h>  #include <stdio.h>  // 挂钩指定模块hMod对MessageBoxA的调用  BOOL SetHookApi(HMODULE hMod);  // 定义MessageBoxA函数原型  typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);  // 保存MessageBoxA函数的真实地址  PROC g_orgProc = (PROC)MessageBoxA;  void main()  {  // 调用原API函数  ::MessageBox(NULL, "原函数", "HookDemo", 0);  // 挂钩后再调用  SetHook(::GetModuleHandle(NULL));  ::MessageBox(NULL, "原函数", "HookDemo", 0);  }  // 用于替换MessageBoxA的自定义函数  int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)  {  return ((PFNMESSAGEBOX)g_orgProc)(hWnd, "新函数", "HookDemo", uType);  }  BOOL SetHookApi(HMODULE hMod)  {  IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hMod;  IMAGE_OPTIONAL_HEADER * pOptHeader =  (IMAGE_OPTIONAL_HEADER *)((BYTE*)hMod + pDosHeader->e_lfanew + 24);  IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)  ((BYTE*)hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);  // 在导入表中查找user32.dll模块。因为MessageBoxA函数从user32.dll模块导出  while(pImportDesc->FirstThunk)  {  char* pszDllName = (char*)((BYTE*)hMod + pImportDesc->Name);  if(lstrcmpiA(pszDllName, "user32.dll") == 0)  {  break;  }  pImportDesc++;  }  if(pImportDesc->FirstThunk)  {  // 一个IMAGE_THUNK_DATA就是一个双字,它指定了一个导入函数  // 调入地址表其实是IMAGE_THUNK_DATA结构的数组,也就是DWORD数组  IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)  ((BYTE*)hMod + pImportDesc->FirstThunk);  while(pThunk->u1.Function)  {  // lpAddr指向的内存保存了函数的地址  DWORD* lpAddr = (DWORD*)&(pThunk->u1.Function);  if(*lpAddr == (DWORD)g_orgProc)  {  DWORD dwOldProtect;  MEMORY_BASIC_INFORMATION mb;  VirtualQuery(lpAddr, &mb, sizeof(mb));  VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect);  // 修改IAT表项,使其指向我们自定义的函数,相当于“*lpAddr = (DWORD)MyMessageBoxA;”  DWORD* lpNewProc = (DWORD*)MyMessageBoxA;  ::WriteProcessMemory(::GetCurrentProcess(),  lpAddr, &lpNewProc, sizeof(DWORD), NULL);  VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, 0);  return TRUE;  }  pThunk++;  }  }  return FALSE;  }
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部