飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 8096|回复: 16

[C/C++] IAT HOOK 类封装 -- By 飘云

  [复制链接]
  • TA的每日心情
    难过
    5 天前
  • 签到天数: 11 天

    [LV.3]偶尔看看II

    发表于 2014-2-5 00:43:46 | 显示全部楼层 |阅读模式
    IAT HOOK,封装成类了,方便新手调用~~
    老手飘过,直接使用 detour

    1. // IAT_Hook.h: interface for the IAT_Hook class.
    2. //
    3. //////////////////////////////////////////////////////////////////////
    4. /************************************************************************/
    5. /* 单元名称: IAT_Hook类                                                 */
    6. /* 单元作者: PiaoYun/P.Y.G                                              */
    7. /* 官方网站: https://www.chinapyg.com                                    */
    8. /************************************************************************/

    9. #if !defined(AFX_IAT_HOOK_H__3A4E562C_C3BF_466C_9080_623F56289211__INCLUDED_)
    10. #define AFX_IAT_HOOK_H__3A4E562C_C3BF_466C_9080_623F56289211__INCLUDED_

    11. #if _MSC_VER > 1000
    12. #pragma once
    13. #endif // _MSC_VER > 1000

    14. #include <windows.h>

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

    20. class IAT_Hook  
    21. {
    22. public:
    23.         IAT_INFO IATInfo;     // 用于保存IAT项信息
    24.         BOOL WINAPI Init(PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc);//, PHOOK_INFO pHookInfo)
    25.         VOID Hook();
    26.         VOID UnHook();
    27.         DWORD GetOldFunAddr();  // 获取原始函数地址
    28.         IAT_Hook();
    29.         virtual ~IAT_Hook();
    30. };

    31. #endif // !defined(AFX_IAT_HOOK_H__3A4E562C_C3BF_466C_9080_623F56289211__INCLUDED_)
    复制代码
    1. // IAT_Hook.cpp: implementation of the IAT_Hook class.
    2. //
    3. //////////////////////////////////////////////////////////////////////
    4. /************************************************************************/
    5. /* 单元名称: IAT_Hook类                                                 */
    6. /* 单元作者: PiaoYun/P.Y.G                                              */
    7. /* 官方网站: https://www.chinapyg.com                                    */
    8. /************************************************************************/

    9. #include "IAT_Hook.h"

    10. //////////////////////////////////////////////////////////////////////
    11. // Construction/Destruction
    12. //////////////////////////////////////////////////////////////////////

    13. IAT_Hook::IAT_Hook()
    14. {
    15.         ZeroMemory(&IATInfo, sizeof(IATInfo));
    16. }

    17. IAT_Hook::~IAT_Hook()
    18. {
    19.         UnHook();
    20. }

    21. /************************************************************************/
    22. /* 函数名称: Init                                                       */
    23. /* 函数作者: PiaoYun/P.Y.G                                              */
    24. /* 函数参数: pDllName:目标API所在的DLL名称                              */
    25. /*           pFunName:目标API名称                                       */
    26. /*           dwNewProc:自定义的函数地址                                 */
    27. /* 函数作者: PiaoYun/P.Y.G                                              */
    28. /* 函数作者: PiaoYun/P.Y.G                                              */
    29. /************************************************************************/
    30. BOOL WINAPI IAT_Hook::Init(PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc)
    31. {
    32.         PIAT_INFO pIATInfo = &IATInfo;

    33.         // 检查参数是否合法
    34.         if (!pDllName || !pFunName || !dwNewProc || !pIATInfo)
    35.                 return FALSE ;
    36.         
    37.         // 检测目标模块是否存在
    38.         char szTempDllName[256] = {0};
    39.         DWORD dwBaseImage = (DWORD)GetModuleHandle(NULL);
    40.         if (dwBaseImage == 0)
    41.                 return FALSE;
    42.         
    43.         // 取得PE文件头信息指针
    44.         PIMAGE_DOS_HEADER   pDosHeader = (PIMAGE_DOS_HEADER)dwBaseImage;
    45.         PIMAGE_NT_HEADERS   pNtHeader = (PIMAGE_NT_HEADERS)(dwBaseImage + (pDosHeader->e_lfanew));
    46.         PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader);
    47.         PIMAGE_SECTION_HEADER  pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + 0x18 + pNtHeader->FileHeader.SizeOfOptionalHeader);
    48.         
    49.         // 遍历输入表
    50.         PIMAGE_THUNK_DATA pThunk, pIAT;
    51.         PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)(dwBaseImage+pOptionalHeader->DataDirectory[1].VirtualAddress);
    52.         while(pIID->FirstThunk)
    53.         {
    54.                 // 检测是否目标模块 -- 不分大小写
    55.                 if (stricmp((PCHAR)(dwBaseImage+pIID->Name), pDllName))
    56.                 {
    57.                         pIID++;
    58.                         continue;
    59.                 }
    60.                
    61.                 pIAT = (PIMAGE_THUNK_DATA)(dwBaseImage + pIID->FirstThunk);
    62.                 if (pIID->OriginalFirstThunk)
    63.                         pThunk = (PIMAGE_THUNK_DATA)(dwBaseImage + pIID->OriginalFirstThunk);
    64.                 else
    65.                         pThunk = pIAT;
    66.                
    67.                 // 遍历IAT表
    68.                 DWORD dwThunkValue = 0;
    69.                 while ((dwThunkValue = *(PDWORD)pThunk) != 0)  
    70.                 {
    71.                         if ((dwThunkValue & IMAGE_ORDINAL_FLAG32) == 0)
    72.                         {
    73.                                 // 检测是否目标函数 -- 分大小写
    74.                                 if (strcmp((PCHAR)(dwBaseImage + dwThunkValue + 2), pFunName) == 0)
    75.                                 {
    76.                                         // 填充函数重定位信息
    77.                                         pIATInfo->dwAddr  = (DWORD)pIAT;
    78.                                         pIATInfo->dwOldValue = *(PDWORD)pIAT;
    79.                                         pIATInfo->dwNewValue = dwNewProc;
    80.                                        
    81.                                         return TRUE;
    82.                                 }
    83.                         }
    84.                         
    85.                         pThunk ++;
    86.                         pIAT ++;
    87.                 }
    88.                
    89.                 pIID ++;
    90.         }
    91.         return FALSE;
    92. }

    93. VOID IAT_Hook::Hook()
    94. {
    95.         if (IATInfo.dwAddr)
    96.         {
    97.                 DWORD dwOldProtect = 0;
    98.                 VirtualProtect((LPVOID)IATInfo.dwAddr, 4, PAGE_READWRITE, &dwOldProtect);
    99.                 *(PDWORD)IATInfo.dwAddr = IATInfo.dwNewValue;
    100.                 VirtualProtect((LPVOID)IATInfo.dwAddr, 4, dwOldProtect, &dwOldProtect);
    101.         }
    102. }

    103. VOID IAT_Hook::UnHook()
    104. {
    105.         if (IATInfo.dwAddr)
    106.         {
    107.                 DWORD dwOldProtect = 0;
    108.                 VirtualProtect((LPVOID)IATInfo.dwAddr, 4, PAGE_READWRITE, &dwOldProtect);
    109.                 *(PDWORD)IATInfo.dwAddr = IATInfo.dwOldValue;
    110.                 VirtualProtect((LPVOID)IATInfo.dwAddr, 4, dwOldProtect, &dwOldProtect);
    111.         }
    112. }

    113. DWORD IAT_Hook::GetOldFunAddr()
    114. {
    115.         return IATInfo.dwOldValue;
    116. }
    复制代码

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

    3. IAT_Hook MyMessageBoxA_IATInfo;

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

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

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

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

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

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

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

    19.         MessageBoxA (0, "UnHook成功", "飘云", MB_OK);  
    20. }
    复制代码






    本帖被以下淘专辑推荐:

    相关帖子

    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2015-8-2 16:07
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-5-4 00:17:15 | 显示全部楼层
    感激不尽,正好最近想要自己写一个HOOK的代码出来
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    4 小时前
  • 签到天数: 5585 天

    [LV.Master]伴坛终老

    发表于 2014-5-8 19:22:44 | 显示全部楼层
    很好的学习材料。谢谢
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2023-3-9 12:06
  • 签到天数: 85 天

    [LV.6]常住居民II

    发表于 2014-6-14 15:36:02 | 显示全部楼层
    很好的学习材料   正好最近想学学HOOK
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-3-17 22:44
  • 签到天数: 132 天

    [LV.7]常住居民III

    发表于 2014-9-15 21:34:07 来自手机 | 显示全部楼层
    非常感谢,阅读完源码解决了手上的多时没有搞定的问题。多谢飘云
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-9-27 19:17
  • 签到天数: 31 天

    [LV.5]常住居民I

    发表于 2014-9-15 23:06:26 | 显示全部楼层
    这么好的东西居然现在才发现!感谢飘云分享!
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2019-3-4 07:54
  • 签到天数: 52 天

    [LV.5]常住居民I

    发表于 2014-10-9 11:43:47 | 显示全部楼层
    老大就是厉害啊!!
    PYG19周年生日快乐!
  • TA的每日心情
    奋斗
    2017-3-10 20:59
  • 签到天数: 243 天

    [LV.8]以坛为家I

    发表于 2014-10-9 12:00:43 | 显示全部楼层
    支持了,感谢分享啦
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-6-13 21:25
  • 签到天数: 38 天

    [LV.5]常住居民I

    发表于 2014-11-4 19:08:12 | 显示全部楼层
    这个正的有用,本坛还有个pyg.dll的权限太高看不了,还是飘大实在!
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    7 天前
  • 签到天数: 204 天

    [LV.7]常住居民III

    发表于 2014-11-25 13:04:56 | 显示全部楼层
    这个真实好东西 谢谢分享
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表