windows钩子保护自身进程不被破坏

这篇具有很好参考价值的文章主要介绍了windows钩子保护自身进程不被破坏。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

代码来自于《windows核心编程》作者:

APIHOOK.h头文件:

#pragma once 
#include <Windows.h> 
 
class CAPIHOOK 
{ 
public: 
    CAPIHOOK(LPTSTR lpszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod = TRUE); 
    ~CAPIHOOK(void); 
 
private: 
    static void ReplaceIATEntryInOneMod(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, HMODULE hModCaller); 
    static void ReplaceIATEntryInAllMods(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, BOOL bExcludeAPIHookMod); 
    //防止程序运行期间动态加载模块, 当一个新DLL被加载时调用 
    static void HookNewlyLoadedModule(HMODULE hModule,  DWORD dwFlags); 
 
    //跟踪当前进程加载新的DLL 
    static HMODULE WINAPI LoadLibraryA(LPCTSTR lpFileName); 
    static HMODULE WINAPI LoadLibraryW(LPCTSTR lpFileName); 
    static HMODULE WINAPI LoadLibraryExA(LPCTSTR lpFileName, HANDLE hFile,  DWORD dwFlags); 
    static HMODULE WINAPI LoadLibraryExW(LPCTSTR lpFileName, HANDLE hFile,  DWORD dwFlags); 
    //防止程序运行期间动态调用API函数 对于请求已HOOK的API函数,返回用户自定义的函数地址 
    static FARPROC WINAPI GetProcess(HMODULE hModule, PCSTR pszProcName);
 
private: //定义成静态的,会自动调用,从而实现自动HOOK 
    static CAPIHOOK sm_LoadLibraryA; 
    static CAPIHOOK sm_LoadLibraryW; 
    static CAPIHOOK sm_LoadLibraryExA; 
    static CAPIHOOK sm_LoadLibraryExW; 
    static CAPIHOOK sm_GetProcAddress; 
 
private: 
    static CAPIHOOK* sm_pHeader; //钩子链表 
    CAPIHOOK* m_pNext; 
 
    //要钩子的函数 
    PROC m_pfnOrig; 
    PROC m_pfnHook; 
 
    //要钩子的函数所在的dll 
    LPSTR m_pszModName; 
    //要钩子的函数名称 
    LPSTR m_pszFuncName; 
};

APIHOOK.cpp实现文件:文章来源地址https://www.toymoban.com/news/detail-656684.html

#include "APIHOOK.h" 
#include <Tlhelp32.h> 
 
CAPIHOOK *CAPIHOOK::sm_pHeader = NULL; 
CAPIHOOK CAPIHOOK::sm_LoadLibraryA("kernel32.dll", "LoadLibraryA", (PROC)CAPIHOOK::LoadLibraryA, TRUE); 
CAPIHOOK CAPIHOOK::sm_LoadLibraryW("kernel32.dll", "LoadLibraryW", (PROC)CAPIHOOK::LoadLibraryW, TRUE); 
CAPIHOOK CAPIHOOK::sm_LoadLibraryExA("kernel32.dll", "LoadLibraryExA", (PROC)CAPIHOOK::LoadLibraryExA, TRUE); 
CAPIHOOK CAPIHOOK::sm_LoadLibraryExW("kernel32.dll", "LoadLibraryExW", (PROC)CAPIHOOK::LoadLibraryExW, TRUE); 
CAPIHOOK CAPIHOOK::sm_GetProcAddress("kernel32.dll", "GetProcAddress", (PROC)CAPIHOOK::GetProcess, TRUE);

CAPIHOOK::CAPIHOOK(LPTSTR lpszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod) 
{ 
    //初始化变量 
    m_pszModName = lpszModName; 
    m_pszFuncName = pszFuncName; 
    m_pfnOrig = ::GetProcAddress(::GetModuleHandleA(lpszModName), pszFuncName); 
    m_pfnHook = pfnHook; 
 
    //将此对象加入链表中 
    m_pNext = sm_pHeader; 
    sm_pHeader = this; 
 
    //在当前已加载的模块中HOOK这个函数 
    ReplaceIATEntryInAllMods(lpszModName, m_pfnOrig, m_pfnHook, bExcludeAPIHookMod); 
} 
 
CAPIHOOK::~CAPIHOOK(void) 
{ 
    //取消对函数的HOOK 
    ReplaceIATEntryInAllMods(m_pszModName, m_pfnHook, m_pfnOrig, TRUE); 
 
    //把自己从链表中删除 
    CAPIHOOK* p = sm_pHeader; 
    if (p == this) 
    { 
        sm_pHeader = this->m_pNext; 
    } 
    else 
    { 
        while(p != NULL) 
        { 
            if (p->m_pNext == this) 
            { 
                p->m_pNext = this->m_pNext; 
                break; 
            } 
            p = p->m_pNext; 
        } 
    } 
} 
//防止程序运行期间动态加载模块 
void CAPIHOOK::HookNewlyLoadedModule(HMODULE hModule, DWORD dwFlags) 
{ 
    if (hModule!=NULL && (dwFlags&LOAD_LIBRARY_AS_DATAFILE)==0) 
    { 
        CAPIHOOK* p = sm_pHeader;  //循环遍历链表,对每个CAPIHOOK进入HOOK 
        if (p != NULL)   
        { 
            ReplaceIATEntryInOneMod(p->m_pszModName, p->m_pfnOrig, p->m_pfnHook, hModule); 
            p = p->m_pNext; 
        } 
    } 
} 
//防止程序运行期间动态调用API函数 
FARPROC WINAPI CAPIHOOK::GetProcess(HMODULE hModule, PCSTR pszProcName) 
{ 
    //得到函数的真实地址 
    FARPROC pfn = ::GetProcAddress(hModule, pszProcName); 
    //遍历列表 看是不是要HOOK的函数 
    CAPIHOOK* p = sm_pHeader; 
    while(p != NULL) 
    { 
        if (p->m_pfnOrig == pfn) //是要HOOK的函数 
        { 
            pfn = p->m_pfnHook; //HOOK掉 
            break; 
        } 
        p = p->m_pNext; 
    } 
    return pfn; 
} 
 
void CAPIHOOK::ReplaceIATEntryInOneMod(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, HMODULE hModCaller) 
{ 
    IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hModCaller; 
    IMAGE_OPTIONAL_HEADER* pOpNtHeader = (IMAGE_OPTIONAL_HEADER*)((BYTE*)hModCaller + pDosHeader->e_lfanew + 24); //这里加24 
    IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hModCaller + pOpNtHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 
 
    BOOL bFindDll = FALSE; 
    while (pImportDesc->FirstThunk) 
    { 
        char* pszDllName = (char*)((BYTE*)hModCaller + pImportDesc->Name); 
 
        if (stricmp(pszDllName, pszExportMod) == 0)//如果找到pszExportMod模块,相当于hook messageboxa时的“user32.dll” 
        { 
            bFindDll = TRUE; 
            break; 
        } 
        pImportDesc++;   
    } 
 
    if (bFindDll) 
    { 
        DWORD n = 0; 
        //一个IMAGE_THUNK_DATA就是一个导入函数 
        IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*)((BYTE*)hModCaller + pImportDesc->OriginalFirstThunk); 
        while (pThunk->u1.Function) 
        { 
            //取得函数名称 
            char* pszFuncName = (char*)((BYTE*)hModCaller+pThunk->u1.AddressOfData+2); //函数名前面有两个.. 
            //printf("function name:%-25s,  ", pszFuncName); 
            //取得函数地址 
            PDWORD lpAddr = (DWORD*)((BYTE*)hModCaller + pImportDesc->FirstThunk) + n; //从第一个函数的地址,以后每次+4字节 
            //printf("addrss:%X\n", lpAddr); 
            //在这里是比较的函数地址 
            if (*lpAddr == (DWORD)pfnCurrent)  //找到iat中的函数地址 
            {                                
                DWORD* lpNewProc = (DWORD*)pfnNewFunc; 
                MEMORY_BASIC_INFORMATION mbi; 
                DWORD dwOldProtect; 
                //修改内存页的保护属性 
                ::VirtualQuery(lpAddr, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); 
                ::VirtualProtect(lpAddr, sizeof(void*), PAGE_READWRITE, &dwOldProtect); 
                ::WriteProcessMemory(GetCurrentProcess(), lpAddr, &lpNewProc, sizeof(void*), NULL); 
                ::VirtualProtect(lpAddr, sizeof(void*), dwOldProtect, NULL); 
                return; 
            }            
            n++; //每次增加一个DWORD 
        }    
    } 
} 
 
void CAPIHOOK::ReplaceIATEntryInAllMods(LPCTSTR pszExportMod, PROC pfnCurrent, PROC pfnNewFunc, BOOL bExcludeAPIHookMod) 
{ 
    //取得当前模块句柄 
    HMODULE hModThis = NULL; 
    if (bExcludeAPIHookMod) 
    { 
        MEMORY_BASIC_INFORMATION mbi; 
        if (0 != ::VirtualQuery(ReplaceIATEntryInAllMods, &mbi, sizeof(MEMORY_BASIC_INFORMATION))) //ReplaceIATEntryInAllMods必须为类的static函数 
        { 
            hModThis = (HMODULE)mbi.AllocationBase; 
        } 
    } 
    //取得本进程的模块列表 
    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;  
    MODULEENTRY32 me32; 
    hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); 
    if (INVALID_HANDLE_VALUE == hModuleSnap) 
    { 
        return; 
    } 
    me32.dwSize = sizeof( MODULEENTRY32 );  
    if( !Module32First( hModuleSnap, &me32 ) )  
    {  
        return; 
    } 
    do  
    { //对每一个模块 
        if (me32.hModule != hModThis) 
        { 
            ReplaceIATEntryInOneMod(pszExportMod, pfnCurrent, pfnNewFunc, me32.hModule); 
        } 
    } while( Module32Next( hModuleSnap, &me32 ) );  
 
    ::CloseHandle(hModuleSnap); //配对写 
} 
 
//防止自动加载 
HMODULE WINAPI CAPIHOOK::LoadLibraryA(LPCTSTR lpFileName) 
{ 
    HMODULE hModule = LoadLibraryA(lpFileName); 
    HookNewlyLoadedModule(hModule, 0); //这个函数中忆检测hModule 了 
    return hModule; 
} 
HMODULE WINAPI CAPIHOOK::LoadLibraryW(LPCTSTR lpFileName) 
{ 
    HMODULE hModule = LoadLibraryW(lpFileName); 
    HookNewlyLoadedModule(hModule, 0); //这个函数中忆检测hModule 了 
    return hModule; 
} 
HMODULE WINAPI CAPIHOOK::LoadLibraryExA(LPCTSTR lpFileName, HANDLE hFile,  DWORD dwFlags) 
{ 
    HMODULE hModule = LoadLibraryExA(lpFileName, hFile, dwFlags); 
    HookNewlyLoadedModule(hModule, dwFlags); //这个函数中忆检测hModule 了 
    return hModule; 
} 
HMODULE WINAPI CAPIHOOK::LoadLibraryExW(LPCTSTR lpFileName, HANDLE hFile,  DWORD dwFlags) 
{ 
    HMODULE hModule = LoadLibraryExW(lpFileName, hFile, dwFlags); 
    HookNewlyLoadedModule(hModule, dwFlags); //这个函数中忆检测hModule 了 
    return hModule; 
}

到了这里,关于windows钩子保护自身进程不被破坏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用Pyarmor保护Python脚本不被反向工程

    Python可读性强,使用广泛。虽然这种可读性有利于协作,但也增加了未授权访问和滥用的风险。如果未采取适当的保护,竞争对手或恶意攻击者可以复制您的算法和专有逻辑,这将对您软件的完整性和用户的信任产生负面影响。 实施可靠的安全措施(比如混淆和许可证验证)

    2024年02月07日
    浏览(27)
  • 【云原生】Kubernetes之 Pod hook(钩子)

    Pod hook(钩子)是由 Kubernetes 管理的 kubelet 发起的,当容器中的进程启动前或者容器中的进程终止之前运行,这是包含在容器的生命周期之中。可以同时为 Pod 中的所有容器都配置 hook。 Hook 的类型包括两种: exec:执行一段命令 HTTP:发送 HTTP 请求 示例如下: 说明: postStar

    2024年02月15日
    浏览(36)
  • 前端数据安全:保护你的应用不被黑客入侵

    在当今数字化时代,前端开发者的一个主要职责是确保应用程序中的数据安全。黑客们总是在寻找机会来窃取敏感信息,所以作为前端开发者,我们需要采取一些措施来保护用户数据。本文将介绍一些前端数据安全的基本原则和技术。 HTTPS 是一种加密通信协议,可以确保数据

    2024年02月11日
    浏览(52)
  • c#使用Hook钩子全局监听键盘和鼠标

    背景:今天接到客户一个需求,就是在收银员在用扫码枪扫顾客会员码或者微信付款码的时候判断用户有没有加企微好友和进企微群,然后根据这个状态进行语音播报,判断顾客能不能享受优惠价。关键难点就是用户用的收银系统是别家的,线上小程序用的是我们家的,两家

    2024年01月22日
    浏览(49)
  • 【小沐学C++】C++ 实现鼠标键盘钩子HOOK

    https://learn.microsoft.com/zh-cn/windows/win32/winmsg/about-hooks 挂钩是应用程序截获消息、鼠标操作和击键等事件的机制。 截获特定类型的事件的函数称为 挂钩过程。 挂钩过程可以对其接收的每个事件执行操作,然后修改或放弃该事件。 挂钩是系统消息处理机制中的一个点,其中应用

    2024年02月02日
    浏览(48)
  • 密码安全:保护你的数据不被入侵的重要性

    在数字时代,密码安全是保护个人和机构数据的关键。然而,不安全的密码可能导致严重的后果,包括个人隐私泄露、金融损失和声誉受损等。本文将探讨密码安全的重要性,揭示不安全密码的危害,列举一些因密码不安全而发生的真实事件,介绍安全的密码特征以及不安全

    2024年03月09日
    浏览(71)
  • Angular--父子组件生命周期钩子(lifecycle hooks)执行过程

    组件初始化过程中,生命周期钩子执行顺序: constructor()构造函数,初始化class,(constructor不属于Angular生命周期钩子的范畴,这里只是说明组件组件初始化会先调用构造函数)。 ngOnChanges()--如果组件没有输入属性(@Input()),或者使用时没有提供任何输入属性,那么angular不会调用它

    2024年01月20日
    浏览(52)
  • 测试框架pytest教程(6)钩子函数hook开发pytest插件

    pytest hook 函数也叫钩子函数,pytest 提供了大量的钩子函数,可以在用例的不同生命周期自动调用。 比如,在测试用例收集阶段,可利用 hook 函数修改测试用例名称的编码。 pytest的hook是基于Python的插件系统实现的,使用特定的命名规范和装饰器来定义钩子函数。你可以在py

    2024年02月12日
    浏览(36)
  • winform C#键盘钩子(Hook)拦截器,屏蔽键盘深入解析

    钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。  钩子实际上是一个

    2024年02月02日
    浏览(43)
  • Angular 17+ 高级教程 – Component 组件 の 生命周期钩子 (Lifecycle Hooks)

    之前在 Component 组件 の Angular Component vs Custom Elements 文章中,我们有学习过几个基础的 Lifecycle Hooks。 比如 OnChanges、OnInit、AfterViewInit、OnDestroy,但那篇只是微微带过而已。 这篇让我们来深入理解 Angular 的 Lifecycle Hooks。   在 Component 组件 の Dependency Injection NodeInjector 文章中

    2024年03月09日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包