其实就很简单,只是对TerminateProcess的HOOK,因为要阻止的不是本进程的,所以要用到全局钩子,也就是把他做成dll形式的!

首先,对前面的HOOK API进行封装CAPIHook:

[cpp] view plain copy

  1. /
  2. // APIHook.h文件
  3. #ifndef __APIHOOK_H__
  4. #define __APIHOOK_H__
  5. #include <windows.h>
  6. class CAPIHook
  7. {
  8. public:
  9. CAPIHook(LPSTR pszModName,
  10. LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod = TRUE);
  11. virtual ~CAPIHook();
  12. operator PROC() { return m_pfnOrig; }
  13. // 实现
  14. private:
  15. LPSTR m_pszModName;     // 导出要HOOK函数的模块的名字
  16. LPSTR m_pszFuncName;        // 要HOOK的函数的名字
  17. PROC m_pfnOrig;         // 原API函数地址
  18. PROC m_pfnHook;         // HOOK后函数的地址
  19. BOOL m_bExcludeAPIHookMod;  // 是否将HOOK API的模块排除在外
  20. private:
  21. static void ReplaceIATEntryInAllMods(LPSTR pszExportMod, PROC pfnCurrent,
  22. PROC pfnNew, BOOL bExcludeAPIHookMod);
  23. static void ReplaceIATEntryInOneMod(LPSTR pszExportMod,
  24. PROC pfnCurrent, PROC pfnNew, HMODULE hModCaller);
  25. // 下面的代码用来解决其它模块动态加载DLL的问题
  26. private:
  27. // 这两个指针用来将所有的CAPIHook对象连在一起
  28. static CAPIHook *sm_pHeader;
  29. CAPIHook *m_pNext;
  30. private:
  31. // 当一个新的DLL被加载时,调用此函数
  32. static void WINAPI HookNewlyLoadedModule(HMODULE hModule, DWORD dwFlags);
  33. // 用来跟踪当前进程加载新的DLL
  34. static HMODULE WINAPI LoadLibraryA(PCSTR  pszModulePath);
  35. static HMODULE WINAPI LoadLibraryW(PCWSTR pszModulePath);
  36. static HMODULE WINAPI LoadLibraryExA(PCSTR  pszModulePath, HANDLE hFile, DWORD dwFlags);
  37. static HMODULE WINAPI LoadLibraryExW(PCWSTR pszModulePath, HANDLE hFile, DWORD dwFlags);
  38. // 如果请求已HOOK的API函数,则返回用户自定义函数的地址
  39. static FARPROC WINAPI GetProcAddress(HMODULE hModule, PCSTR pszProcName);
  40. private:
  41. // 自动对这些函数进行挂钩
  42. static CAPIHook sm_LoadLibraryA;
  43. static CAPIHook sm_LoadLibraryW;
  44. static CAPIHook sm_LoadLibraryExA;
  45. static CAPIHook sm_LoadLibraryExW;
  46. static CAPIHook sm_GetProcAddress;
  47. };
  48. #endif // __APIHOOK_H__

[cpp] view plain copy

  1. //
  2. // APIHook.cpp文件
  3. #include "stdafx.h"
  4. #include "APIHook.h"
  5. #include "Tlhelp32.h"
  6. #include <ImageHlp.h> // 为了调用ImageDirectoryEntryToData函数
  7. #pragma comment(lib, "ImageHlp")
  8. // CAPIHook对象链表的头指针
  9. CAPIHook* CAPIHook::sm_pHeader = NULL;
  10. CAPIHook::CAPIHook(LPSTR pszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod)
  11. {
  12. // 保存这个Hook函数的信息
  13. m_bExcludeAPIHookMod = bExcludeAPIHookMod;
  14. m_pszModName = pszModName;
  15. m_pszFuncName = pszFuncName;
  16. m_pfnHook = pfnHook;
  17. m_pfnOrig = ::GetProcAddress(::GetModuleHandle(pszModName), pszFuncName);
  18. // 将此对象添加到链表中
  19. m_pNext = sm_pHeader;
  20. sm_pHeader = this;
  21. // 在所有当前已加载的模块中HOOK这个函数
  22. ReplaceIATEntryInAllMods(m_pszModName, m_pfnOrig, m_pfnHook, bExcludeAPIHookMod);
  23. }
  24. CAPIHook::~CAPIHook()
  25. {
  26. // 取消对所有模块中函数的HOOK
  27. ReplaceIATEntryInAllMods(m_pszModName, m_pfnHook, m_pfnOrig, m_bExcludeAPIHookMod);
  28. CAPIHook *p = sm_pHeader;
  29. // 从链表中移除此对象
  30. if(p == this)
  31. {
  32. sm_pHeader = p->m_pNext;
  33. }
  34. else
  35. {
  36. while(p != NULL)
  37. {
  38. if(p->m_pNext == this)
  39. {
  40. p->m_pNext = this->m_pNext;
  41. break;
  42. }
  43. p = p->m_pNext;
  44. }
  45. }
  46. }
  47. void CAPIHook::ReplaceIATEntryInOneMod(LPSTR pszExportMod,
  48. PROC pfnCurrent, PROC pfnNew, HMODULE hModCaller)
  49. {
  50. // 取得模块的导入表(import descriptor)首地址。ImageDirectoryEntryToData函数可以直接返回导入表地址
  51. ULONG ulSize;
  52. PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
  53. ::ImageDirectoryEntryToData(hModCaller, TRUE,
  54. IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
  55. if(pImportDesc == NULL) // 这个模块没有导入节表
  56. {
  57. return;
  58. }
  59. // 查找包含pszExportMod模块中函数导入信息的导入表项
  60. while(pImportDesc->Name != 0)
  61. {
  62. LPSTR pszMod = (LPSTR)((DWORD)hModCaller + pImportDesc->Name);
  63. if(lstrcmpiA(pszMod, pszExportMod) == 0) // 找到
  64. break;
  65. pImportDesc++;
  66. }
  67. if(pImportDesc->Name == 0) // hModCaller模块没有从pszExportMod模块导入任何函数
  68. {
  69. return;
  70. }
  71. // 取得调用者的导入地址表(import address table, IAT)
  72. PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)(pImportDesc->FirstThunk + (DWORD)hModCaller);
  73. // 查找我们要HOOK的函数,将它的地址用新函数的地址替换掉
  74. while(pThunk->u1.Function)
  75. {
  76. // lpAddr指向的内存保存了函数的地址
  77. PDWORD lpAddr = (PDWORD)&(pThunk->u1.Function);
  78. if(*lpAddr == (DWORD)pfnCurrent)
  79. {
  80. // 修改页的保护属性
  81. DWORD dwOldProtect;
  82. MEMORY_BASIC_INFORMATION mbi;
  83. ::VirtualQuery(lpAddr, &mbi, sizeof(mbi));
  84. ::VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect);
  85. // 修改内存地址  相当于“*lpAddr = (DWORD)pfnNew;”
  86. ::WriteProcessMemory(::GetCurrentProcess(),
  87. lpAddr, &pfnNew, sizeof(DWORD), NULL);
  88. ::VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, 0);
  89. break;
  90. }
  91. pThunk++;
  92. }
  93. }
  94. void CAPIHook::ReplaceIATEntryInAllMods(LPSTR pszExportMod,
  95. PROC pfnCurrent, PROC pfnNew, BOOL bExcludeAPIHookMod)
  96. {
  97. // 取得当前模块的句柄
  98. HMODULE hModThis = NULL;
  99. if(bExcludeAPIHookMod)
  100. {
  101. MEMORY_BASIC_INFORMATION mbi;
  102. if(::VirtualQuery(ReplaceIATEntryInAllMods, &mbi, sizeof(mbi)) != 0)
  103. hModThis = (HMODULE)mbi.AllocationBase;
  104. }
  105. // 取得本进程的模块列表
  106. HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ::GetCurrentProcessId());
  107. // 遍历所有模块,分别对它们调用ReplaceIATEntryInOneMod函数,修改导入地址表
  108. MODULEENTRY32 me = { sizeof(MODULEENTRY32) };
  109. BOOL bOK = ::Module32First(hSnap, &me);
  110. while(bOK)
  111. {
  112. // 注意:我们不HOOK当前模块的函数
  113. if(me.hModule != hModThis)
  114. ReplaceIATEntryInOneMod(pszExportMod, pfnCurrent, pfnNew, me.hModule);
  115. bOK = ::Module32Next(hSnap, &me);
  116. }
  117. ::CloseHandle(hSnap);
  118. }
  119. // 挂钩LoadLibrary和GetProcAddress函数,以便在这些函数被调用以后,挂钩的函数也能够被正确的处理
  120. CAPIHook CAPIHook::sm_LoadLibraryA("Kernel32.dll", "LoadLibraryA",
  121. (PROC)CAPIHook::LoadLibraryA, TRUE);
  122. CAPIHook CAPIHook::sm_LoadLibraryW("Kernel32.dll", "LoadLibraryW",
  123. (PROC)CAPIHook::LoadLibraryW, TRUE);
  124. CAPIHook CAPIHook::sm_LoadLibraryExA("Kernel32.dll", "LoadLibraryExA",
  125. (PROC)CAPIHook::LoadLibraryExA, TRUE);
  126. CAPIHook CAPIHook::sm_LoadLibraryExW("Kernel32.dll", "LoadLibraryExW",
  127. (PROC)CAPIHook::LoadLibraryExW, TRUE);
  128. CAPIHook CAPIHook::sm_GetProcAddress("Kernel32.dll", "GetProcAddress",
  129. (PROC)CAPIHook::GetProcAddress, TRUE);
  130. void WINAPI CAPIHook::HookNewlyLoadedModule(HMODULE hModule, DWORD dwFlags)
  131. {
  132. // 如果一个新的模块被加载,挂钩各CAPIHook对象要求的API函数
  133. if((hModule != NULL) && ((dwFlags&LOAD_LIBRARY_AS_DATAFILE) == 0))
  134. {
  135. CAPIHook *p = sm_pHeader;
  136. while(p != NULL)
  137. {
  138. ReplaceIATEntryInOneMod(p->m_pszModName, p->m_pfnOrig, p->m_pfnHook, hModule);
  139. p = p->m_pNext;
  140. }
  141. }
  142. }
  143. HMODULE WINAPI CAPIHook::LoadLibraryA(PCSTR pszModulePath)
  144. {
  145. HMODULE hModule = ::LoadLibraryA(pszModulePath);
  146. HookNewlyLoadedModule(hModule, 0);
  147. return(hModule);
  148. }
  149. HMODULE WINAPI CAPIHook::LoadLibraryW(PCWSTR pszModulePath)
  150. {
  151. HMODULE hModule = ::LoadLibraryW(pszModulePath);
  152. HookNewlyLoadedModule(hModule, 0);
  153. return(hModule);
  154. }
  155. HMODULE WINAPI CAPIHook::LoadLibraryExA(PCSTR pszModulePath, HANDLE hFile, DWORD dwFlags)
  156. {
  157. HMODULE hModule = ::LoadLibraryExA(pszModulePath, hFile, dwFlags);
  158. HookNewlyLoadedModule(hModule, dwFlags);
  159. return(hModule);
  160. }
  161. HMODULE WINAPI CAPIHook::LoadLibraryExW(PCWSTR pszModulePath, HANDLE hFile, DWORD dwFlags)
  162. {
  163. HMODULE hModule = ::LoadLibraryExW(pszModulePath, hFile, dwFlags);
  164. HookNewlyLoadedModule(hModule, dwFlags);
  165. return(hModule);
  166. }
  167. FARPROC WINAPI CAPIHook::GetProcAddress(HMODULE hModule, PCSTR pszProcName)
  168. {
  169. // 得到这个函数的真实地址
  170. FARPROC pfn = ::GetProcAddress(hModule, pszProcName);
  171. // 看它是不是我们要hook的函数
  172. CAPIHook *p = sm_pHeader;
  173. while(p != NULL)
  174. {
  175. if(p->m_pfnOrig == pfn)
  176. {
  177. pfn = p->m_pfnHook;
  178. break;
  179. }
  180. p = p->m_pNext;
  181. }
  182. return pfn;
  183. }

然后利用这个封装好的类开始做我们的DLL:

[cpp] view plain copy

  1. bool WINAPI Hook_TerminateProcess(HANDLE hProcess, UINT nExitCode)
  2. {
  3. typedef bool (WINAPI *PFNTERMINATEPROCESS)(HANDLE, UINT);
  4. char szPathName[256];
  5. ::GetModuleFileName(NULL, szPathName, 256);
  6. char sz[2048];
  7. wsprintf(sz, "进程号:%d   %s, 进程句柄: %X, 退出代码: %d/n", ::GetCurrentProcess(), szPathName, hProcess, nExitCode);
  8. COPYDATASTRUCT cds = {::GetCurrentProcessId(), strlen(sz) + 1, sz };
  9. if(::SendMessage(::FindWindow(NULL, "进程保护器"), WM_COPYDATA, 0, (LPARAM)&cds) != -1)
  10. {
  11. return ((PFNTERMINATEPROCESS)(PROC)g_TerminateProcess)(hProcess, nExitCode);
  12. }
  13. return true;
  14. }
  15. CAPIHook g_TerminateProcess("kernel32.dll", "TerminateProcess", (PROC)Hook_TerminateProcess );
  16. #pragma data_seg("YCIShared")
  17. HHOOK g_hHook = NULL;
  18. #pragma data_seg()
  19. static HMODULE ModuleFromAddress(void *pv)
  20. {
  21. MEMORY_BASIC_INFORMATION mbi;
  22. if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
  23. {
  24. return (HMODULE)mbi.AllocationBase;
  25. }
  26. return NULL;
  27. }
  28. static LRESULT WINAPI GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
  29. {
  30. return ::CallNextHookEx(g_hHook, code, wParam, lParam);
  31. }
  32. extern "C" int __declspec(dllexport)SetSysHook(bool bInstall, DWORD dwThreadId)
  33. {
  34. bool bOk;
  35. if(bInstall)
  36. {
  37. g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, ModuleFromAddress(GetMsgProc), dwThreadId);
  38. bOk = (g_hHook != NULL);
  39. }
  40. else
  41. {
  42. bOk = ::UnhookWindowsHookEx(g_hHook);
  43. g_hHook = NULL;
  44. }
  45. return bOk;
  46. }

编译,OK啦,已经做成我们要的DLL!

下面把他加载到我们所需要的程序中,因为DLL通过WM_COPYDATA发送了一个消息给了我们的程序的,因此我在程序中要响应此消息,重载WM_COPYDATA消息

[cpp] view plain copy

  1. BOOL CHookTermTestDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
  2. {
  3. // TODO: Add your message handler code here and/or call default
  4. GetDlgItem(IDC_EDIT1)->SetWindowText((char *)pCopyDataStruct->lpData);
  5. bool nForbid = ((CButton *)GetDlgItem(IDC_CHECK1))->GetCheck();
  6. if(nForbid)
  7. return -1;
  8. return TRUE;
  9. //return CDialog::OnCopyData(pWnd, pCopyDataStruct);
  10. }

当然,也别忘了要加载那DLL的钩子,和卸载那钩子

[cpp] view plain copy

  1. void CHookTermTestDlg::OnCheck1()
  2. {
  3. // TODO: Add your control notification handler code here
  4. typedef int(*PFNSETSYSHOOK)(BOOL, DWORD);
  5. char szDll[] = "HookTerm.dll";
  6. bool nNeedFree = false;
  7. HMODULE hModule = ::GetModuleHandle(szDll);
  8. if(hModule == NULL)
  9. {
  10. hModule = ::LoadLibrary(szDll);
  11. nNeedFree = true;
  12. }
  13. if(hModule == NULL)
  14. {
  15. }
  16. PFNSETSYSHOOK mSetSysHook = (PFNSETSYSHOOK)GetProcAddress(hModule, "SetSysHook");
  17. if(mSetSysHook == NULL)
  18. {
  19. if(nNeedFree)
  20. ::FreeLibrary(hModule);
  21. return ;
  22. }
  23. bool bRet = mSetSysHook(TRUE, 0);
  24. if(nNeedFree)
  25. {
  26. ::FreeLibrary(hModule);
  27. }
  28. //SetSysHook(true, 0);
  29. }

[cpp] view plain copy

  1. void CHookTermTestDlg::OnButton1()
  2. {
  3. // TODO: Add your control notification handler code here
  4. typedef int(*PFNSETSYSHOOK)(BOOL, DWORD);
  5. char szDll[] = "HookTerm.dll";
  6. bool nNeedFree = false;
  7. HMODULE hModule = ::GetModuleHandle(szDll);
  8. if(hModule == NULL)
  9. {
  10. hModule = ::LoadLibrary(szDll);
  11. nNeedFree = true;
  12. }
  13. if(hModule == NULL)
  14. {
  15. }
  16. PFNSETSYSHOOK mSetSysHook = (PFNSETSYSHOOK)GetProcAddress(hModule, "SetSysHook");
  17. if(mSetSysHook == NULL)
  18. {
  19. if(nNeedFree)
  20. ::FreeLibrary(hModule);
  21. return ;
  22. }
  23. bool bRet = mSetSysHook(false, 0);
  24. if(nNeedFree)
  25. {
  26. ::FreeLibrary(hModule);
  27. }
  28. CDialog::OnCancel();
  29. }

利用HOOK API做进程保护器相关推荐

  1. 利用百度API做图像识别(py3)(转)

    mark一下,感谢作者分享! https://blog.csdn.net/qq_40484582/article/details/82054009 第一次在CSND上发博客.过去都是上CSND参考大佬 ...

  2. 使用Native API 创建进程

    使用 Native API 创建进程 最近几个星期一直在研究这个题目.因为关于方面的资料比较多(可以看下面的参考文章),所以开始时以为很快就结束了.谁知道真正动起手来才发现有很多要考虑的地方,不过还好 ...

  3. 从龙之谷双开领悟出的——HOOK API

    第一部分--限制程序多开方法 这里有一篇文章讲得很详细了,http://wenku.baidu.com/view/ac9d0215a2161479171128af.html 龙之谷使用的是互斥体方法, ...

  4. 【API进阶之路】高考要考口语?我用多模态评测API做了一场10w+刷屏活动

    上一期故事说到,我成为了公司技术委员会副主席,上任后的第一件事是建立了一个云容器化的研发资料库,把每个研发硬盘里那点"好东西"都复用出来.(详情查看:<无法想象!大龄码农的硬 ...

  5. 通过Hook API调用打造进程监控程序

    *(收藏)http://hi.baidu.com/linuxetc/blog/item/1b91c813b017e4035baf53a7.html Hook(钩子)是Windows消息处理过程中的一个 ...

  6. Windows下Hook API技术小结 (转)

    1.基本概念 钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理函数之前 ...

  7. 9.3 挂钩API技术(HOOK API)

    HOOK API HOOK API是指截获特定进程或系统对某个API函数的调用,使得API的执行流程转向指定的代码.例如,在挂钩了系统对User32.dll模块中MessageBoxA函数的调用以后, ...

  8. 给 K8s API “做减法”:阿里巴巴云原生应用管理的挑战和实践

    作者 | 孙健波(天元)  阿里巴巴技术专家 本文整理自 11 月 21 日社群分享,每月 2 场高质量分享,点击加入社群. 早在 2011 年,阿里巴巴内部便开始了应用容器化,当时最开始是基于 LX ...

  9. 汇编Ring 3下实现 HOOK API

    [文章标题]汇编ring3下实现HOOK API [文章作者]nohacks(非安全,hacker0058) [作者主页]hacker0058.ys168.com [文章出处]看雪论坛(bbs.ped ...

最新文章

  1. 图神经网络如何对知识图谱建模? | 赠书
  2. 143. Leetcode 78. 子集 (回溯算法-子集问题)
  3. JSON与Struts2的结合使用
  4. java与c++的区别-转
  5. LATEX学习篇【二】:论文中的公式技巧QA
  6. 程序员结婚晚回家怕出轨吗?老婆:不怕,老公是写代码的,忙得很!
  7. jumpserver mysql跳板_jumpserver跳板机
  8. 空头平仓什么意思_什么是白糖期货期权仿真交易套利机会?
  9. Java基础问题整理
  10. html静态网页设计实训总结,html网页设计总结 html静态网页设计大作业
  11. batchplot 3.6.2 插件_插件分享 | 可在线查询子域名和同IP域名的RapidDNS
  12. SU插件情报局 | Selection Toys 过滤选择(附插件安装包)
  13. web前后端分离系统之间的单点登录
  14. 网络硬盘录像机、边缘存储和云存储的优缺点
  15. 2021年危险化学品经营单位安全管理人员考试内容及危险化学品经营单位安全管理人员考试试卷
  16. CentOS 7 几个版本
  17. 浅析cv::cuda::threshold函数的实现
  18. 计算机查看用户 组,查看工作组计算机的方法介绍
  19. 解决insmod error inserting 'hello ko' -1 Invalid module form
  20. 曝各城市娶妻成本:深圳208万 程序员成为“妻奴”?

热门文章

  1. mysql默认排序规则utf8mb4_Mysql字符集和排序规则 - UTF8mb4 520
  2. Linux嵌入式开发版贪吃蛇,嵌入式之贪吃蛇
  3. 深富策略酿酒板块等反弹
  4. 洛谷 P3904 三只小猪
  5. 不为人知但堪称神器的5款软件,用过的人都爱不释手
  6. JUC 概述 ---1
  7. Linux--LVM与磁盘配额
  8. python 数组 操作
  9. JS输出内容的五种方式详解
  10. 网站备份文件扫描小工具