HOOK MessageBoxA应用程序

HOOK 目标:  MessageBoxA
    所需知识:   PE Windows编程
 很久没写代码了,把原来学到的东西都忘的差不多都忘了,正好最近要写个程序,里面要HOOK几个API,源程序我就不贴出来了,另外简单写了个HOOK MessageBoxA的程序,所用的方法基本相同。
  
// message.cpp : 定义控制台应用程序的入口点。
//

#include “stdafx.h”
#include <Windows.h>
#include <stdio.h>

// 挂钩MessageBoxA
BOOL SetHookApi(HMODULE hMod);
// MessageBoxA函数原型
typedef int (WINAPI *PFUN)(HWND, LPCSTR, LPCSTR, UINT uType);
// 保存MessageBoxA函数的原地址
PROC g_orgProc = (PROC)MessageBoxA;

// HOOK后调用的MessageBoxA
int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
 return ((PFUN)g_orgProc)(hWnd, “new MSG”, “HookMSG”, 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;
}

int _tmain(int argc, _TCHAR* argv[])
{
 // 调用原API
 MessageBox(NULL, “原函数”, “HookMSG”, 0);
 // 挂钩程序
 SetHookApi(GetModuleHandle(NULL));
    //调用挂钩后的程序
 MessageBox(NULL, “原函数”, “HookMSG”, 0);
 return 0;
}

其实,HOOK API是可以从很多方面下手的,可以从程序开头、代码中间,还可以是结尾,只要你能想到的,就可以做到!初学这方面的知识的时候总习惯性的是在程序开头位置,很多程序会检测API有没有被HOOK掉,如果挂接在程序头部,很有可能被程序检测出来,所以这时候就需要考虑其它位置了。还有许多程序用到了反HOOK,上面的方面就不可行了,必须得先把反HOOK解决掉,这不在本文的范围,这里就不讨论了。

相关推荐

发表评论

您的电子邮箱地址不会被公开。

QQ点我咨询