飘云 发表于 2014-2-5 00:43:46

IAT HOOK 类封装 -- By 飘云

IAT HOOK,封装成类了,方便新手调用~~
老手飘过,直接使用 detour
// IAT_Hook.h: interface for the IAT_Hook class.
//
//////////////////////////////////////////////////////////////////////
/************************************************************************/
/* 单元名称: IAT_Hook类                                                 */
/* 单元作者: PiaoYun/P.Y.G                                              */
/* 官方网站: https://www.chinapyg.com                                    */
/************************************************************************/

#if !defined(AFX_IAT_HOOK_H__3A4E562C_C3BF_466C_9080_623F56289211__INCLUDED_)
#define AFX_IAT_HOOK_H__3A4E562C_C3BF_466C_9080_623F56289211__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <windows.h>

typedef struct _IAT_INFO {
      DWORD dwAddr ;      // IAT所在地址
      DWORD dwOldValue ;// IAT原始函数地址
      DWORD dwNewValue ;// IAT新函数地址
} IAT_INFO, *PIAT_INFO;

class IAT_Hook
{
public:
      IAT_INFO IATInfo;   // 用于保存IAT项信息
      BOOL WINAPI Init(PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc);//, PHOOK_INFO pHookInfo)
      VOID Hook();
      VOID UnHook();
      DWORD GetOldFunAddr();// 获取原始函数地址
      IAT_Hook();
      virtual ~IAT_Hook();
};

#endif // !defined(AFX_IAT_HOOK_H__3A4E562C_C3BF_466C_9080_623F56289211__INCLUDED_)

// IAT_Hook.cpp: implementation of the IAT_Hook class.
//
//////////////////////////////////////////////////////////////////////
/************************************************************************/
/* 单元名称: IAT_Hook类                                                 */
/* 单元作者: PiaoYun/P.Y.G                                              */
/* 官方网站: https://www.chinapyg.com                                    */
/************************************************************************/

#include "IAT_Hook.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

IAT_Hook::IAT_Hook()
{
      ZeroMemory(&IATInfo, sizeof(IATInfo));
}

IAT_Hook::~IAT_Hook()
{
      UnHook();
}

/************************************************************************/
/* 函数名称: Init                                                       */
/* 函数作者: PiaoYun/P.Y.G                                              */
/* 函数参数: pDllName:目标API所在的DLL名称                              */
/*         pFunName:目标API名称                                       */
/*         dwNewProc:自定义的函数地址                                 */
/* 函数作者: PiaoYun/P.Y.G                                              */
/* 函数作者: PiaoYun/P.Y.G                                              */
/************************************************************************/
BOOL WINAPI IAT_Hook::Init(PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc)
{
      PIAT_INFO pIATInfo = &IATInfo;

      // 检查参数是否合法
      if (!pDllName || !pFunName || !dwNewProc || !pIATInfo)
                return FALSE ;
      
      // 检测目标模块是否存在
      char szTempDllName = {0};
      DWORD dwBaseImage = (DWORD)GetModuleHandle(NULL);
      if (dwBaseImage == 0)
                return FALSE;
      
      // 取得PE文件头信息指针
      PIMAGE_DOS_HEADER   pDosHeader = (PIMAGE_DOS_HEADER)dwBaseImage;
      PIMAGE_NT_HEADERS   pNtHeader = (PIMAGE_NT_HEADERS)(dwBaseImage + (pDosHeader->e_lfanew));
      PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader);
      PIMAGE_SECTION_HEADERpSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + 0x18 + pNtHeader->FileHeader.SizeOfOptionalHeader);
      
      // 遍历输入表
      PIMAGE_THUNK_DATA pThunk, pIAT;
      PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)(dwBaseImage+pOptionalHeader->DataDirectory.VirtualAddress);
      while(pIID->FirstThunk)
      {
                // 检测是否目标模块 -- 不分大小写
                if (stricmp((PCHAR)(dwBaseImage+pIID->Name), pDllName))
                {
                        pIID++;
                        continue;
                }
               
                pIAT = (PIMAGE_THUNK_DATA)(dwBaseImage + pIID->FirstThunk);
                if (pIID->OriginalFirstThunk)
                        pThunk = (PIMAGE_THUNK_DATA)(dwBaseImage + pIID->OriginalFirstThunk);
                else
                        pThunk = pIAT;
               
                // 遍历IAT表
                DWORD dwThunkValue = 0;
                while ((dwThunkValue = *(PDWORD)pThunk) != 0)
                {
                        if ((dwThunkValue & IMAGE_ORDINAL_FLAG32) == 0)
                        {
                              // 检测是否目标函数 -- 分大小写
                              if (strcmp((PCHAR)(dwBaseImage + dwThunkValue + 2), pFunName) == 0)
                              {
                                        // 填充函数重定位信息
                                        pIATInfo->dwAddr= (DWORD)pIAT;
                                        pIATInfo->dwOldValue = *(PDWORD)pIAT;
                                        pIATInfo->dwNewValue = dwNewProc;
                                       
                                        return TRUE;
                              }
                        }
                        
                        pThunk ++;
                        pIAT ++;
                }
               
                pIID ++;
      }
      return FALSE;
}

VOID IAT_Hook::Hook()
{
      if (IATInfo.dwAddr)
      {
                DWORD dwOldProtect = 0;
                VirtualProtect((LPVOID)IATInfo.dwAddr, 4, PAGE_READWRITE, &dwOldProtect);
                *(PDWORD)IATInfo.dwAddr = IATInfo.dwNewValue;
                VirtualProtect((LPVOID)IATInfo.dwAddr, 4, dwOldProtect, &dwOldProtect);
      }
}

VOID IAT_Hook::UnHook()
{
      if (IATInfo.dwAddr)
      {
                DWORD dwOldProtect = 0;
                VirtualProtect((LPVOID)IATInfo.dwAddr, 4, PAGE_READWRITE, &dwOldProtect);
                *(PDWORD)IATInfo.dwAddr = IATInfo.dwOldValue;
                VirtualProtect((LPVOID)IATInfo.dwAddr, 4, dwOldProtect, &dwOldProtect);
      }
}

DWORD IAT_Hook::GetOldFunAddr()
{
      return IATInfo.dwOldValue;
}

测试代码:#include <windows.h>
#include "IAT_Hook.h"

IAT_Hook MyMessageBoxA_IATInfo;

// 函数原型声明
typedef int (WINAPI* pfnMessageBoxA)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);

int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
      pfnMessageBoxA Kernel_MessageBoxA = (pfnMessageBoxA)MyMessageBoxA_IATInfo.GetOldFunAddr();

      ShellExecute(NULL, "open", "https://www.chinapyg.com", NULL, NULL, SW_SHOWNORMAL);

      return Kernel_MessageBoxA( hWnd, "函数被劫持!原始内容被我替换了", lpCaption, uType) ;
}

VOID main()
{
      MessageBoxA(0, "Hook前,能看到我吧?", "飘云", MB_OK);

      MyMessageBoxA_IATInfo.Init("USER32.dll", "MessageBoxA", (DWORD)MyMessageBoxA);

      MyMessageBoxA_IATInfo.Hook();
      MessageBoxA(0, "还能看到我么?", "飘云", MB_OK);
      MyMessageBoxA_IATInfo.UnHook();

      MessageBoxA (0, "UnHook成功", "飘云", MB_OK);
}






F8LEFT 发表于 2014-5-4 00:17:15

感激不尽,正好最近想要自己写一个HOOK的代码出来

atompure 发表于 2014-5-8 19:22:44

很好的学习材料。谢谢

pyingyue 发表于 2014-6-14 15:36:02

很好的学习材料   正好最近想学学HOOK

tree_fly 发表于 2014-9-15 21:34:07

非常感谢,阅读完源码解决了手上的多时没有搞定的问题。多谢飘云

lucky_789 发表于 2014-9-15 23:06:26

这么好的东西居然现在才发现!感谢飘云分享!

lhmxn 发表于 2014-10-9 11:43:47

老大就是厉害啊!!

开心啦 发表于 2014-10-9 12:00:43

支持了,感谢分享啦

小柯师傅 发表于 2014-11-4 19:08:12

这个正的有用,本坛还有个pyg.dll的权限太高看不了,还是飘大实在!

fzx118 发表于 2014-11-25 13:04:56

这个真实好东西 谢谢分享
页: [1] 2
查看完整版本: IAT HOOK 类封装 -- By 飘云