鱼C论坛

 找回密码
 立即注册
查看: 3273|回复: 0

VC6release版本程序的HOOK函数无法实现对导入表中目标API的覆盖

[复制链接]
发表于 2013-4-29 07:34:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 dycc 于 2013-4-29 07:55 编辑

        根据《windows程序设计》中书上的演示代码,可以实现通过对目标模块导入表的覆盖实现对某AIP的拦截,然后调用自定义的函数。
        在VC++6.0编译器上的debug版本程序能够实现正常覆盖,但是编译成release版本就会出现在hook函数中覆盖掉而且会正确hook掉目标API,但是返回到主函数后就无法实现拦截,而是再次还原成目标API的真实地址,也不会导致崩溃,hook函数返回后能正常调用真正的目标API,这样就没有实现hook函数的功能,为什么会有这种现象?代码是书上的没错,思路也没错,但还是有这种现象,换到XP下运行也有这种现象,不知道是什么问题以及如何解决,请大大们解答下,不胜感激!!!


这是release版本

这是release版本

这是debug版本

这是debug版本



  1. #include <windows.h>
  2. #include <stdio.h>

  3.         // 挂钩指定模块hMod对MessageBoxA的调用
  4.         BOOL SetHook(HMODULE hMod);
  5.        // 定义MessageBoxA函数原型
  6.        typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType);
  7.        // 保存MessageBoxA函数的真实地址
  8.        PROC g_orgProc = (PROC)MessageBoxA;

  9. void main()
  10. {
  11.        // 调用原API函数
  12.        ::MessageBox(NULL, "原函数", "09HookDemo", 0);
  13.        // 挂钩后再调用
  14.        printf("覆盖前主函数MessageBoxA地址:\n%x\n",(PROC)MessageBoxA);
  15.        SetHook(::GetModuleHandle(NULL));
  16.        GetProcAddress(::GetModuleHandle(NULL),);
  17.        ::MessageBox(NULL, "原函数", "09HookDemo", 0);
  18. }

  19. // 用于替换MessageBoxA的自定义函数
  20. int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
  21. {
  22.        return ((PFNMESSAGEBOX)g_orgProc)(hWnd, "新函数", "09HookDemo", uType);
  23. }

  24. BOOL SetHook(HMODULE hMod)
  25. {
  26.        IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hMod;
  27.        IMAGE_OPTIONAL_HEADER * pOptHeader =
  28.        (IMAGE_OPTIONAL_HEADER *)((BYTE*)hMod + pDosHeader->e_lfanew + 24);
  29.         
  30.        IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)
  31.        ((BYTE*)hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  32.        // 在导入表中查找user32.dll模块。因为MessageBoxA函数从user32.dll模块导出
  33.        while(pImportDesc->FirstThunk)
  34.        {
  35.               char* pszDllName = (char*)((BYTE*)hMod + pImportDesc->Name);
复制代码
  1.              if(lstrcmpiA(pszDllName, "user32.dll") == 0)
复制代码
  1.             {
  2.                 break;
  3.             }
  4.             pImportDesc++;
  5.         }

  6.         if(pImportDesc->FirstThunk)
  7.         {
  8.             // 一个IMAGE_THUNK_DATA就是一个双字,它指定了一个导入函数
  9.             // 调入地址表其实是IMAGE_THUNK_DATA结构的数组,也就是DWORD数组
  10.             IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hMod + pImportDesc->FirstThunk);
  11.         while(pThunk->u1.Function)
  12.         {
  13.             // lpAddr指向的内存保存了函数的地址
  14.             DWORD* lpAddr = (DWORD*)&(pThunk->u1.Function);
  15.             if(*lpAddr == (DWORD)g_orgProc)
  16.             {
  17.                 printf("覆盖前自定义函数中保存MessageBoxA地址的地址与MessageBoxA的地址:\n%x %x\n",lpAddr,*lpAddr);

  18.                 DWORD dwOldProtect;
  19.                 MEMORY_BASIC_INFORMATION mbi;
  20.                 VirtualQuery(lpAddr,&mbi,sizeof(mbi));
  21.                 VirtualProtect(lpAddr,sizeof(DWORD),PAGE_EXECUTE_READWRITE,&dwOldProtect);

  22.                 // 修改IAT表项,使其指向我们自定义的函数,相当于“*lpAddr = (DWORD)MyMessageBoxA;”
  23. DWORD* lpNewProc = (DWORD*)MyMessageBoxA;
  24.                 ::WriteProcessMemory(::GetCurrentProcess(),
  25.                 lpAddr, &lpNewProc, sizeof(DWORD), NULL);
  26.                 printf("覆盖后自定义函数中保存MessageBoxA地址的地址与MessageBoxA的地址:\n%x %x\n",lpAddr,*lpAddr);
  27.                 printf("覆盖后自定义函数中MessageBoxA地址:\n%x\n",(PROC)MessageBoxA);
  28.                 ::MessageBox(NULL, "原函数", "09HookDemo", 0);
  29.                 VirtualProtect(lpAddr,sizeof(DWORD),dwOldProtect,0);
  30.                 return TRUE;
  31.             }

  32.             pThunk++;
  33.         }
  34.     }
  35. return TRUE;
  36. }
复制代码


小甲鱼最新课程 -> https://ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-31 02:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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