• 全局钩子注入DLL


    0x00 原理说明:

    Windows系统基于消息驱动,每个进程都有各自的消息队列,每个进程都会GetMessage

    调用WIN32API SetWindowsHookEx 可以在系统的钩子链中安装一个指定的钩子

    如果使用 SetWindowsHookEx 安装 WH_GETMESSAGE 类型的钩子,并且钩子过程函数放在DLL中,就可以实现全局的DLL注入

    0x01 关键API说明:

    实现全局钩子注入DLL最核心的API:

    HHOOK WINAPI SetWindowsHookEx(
      _In_ int       idHook,
      _In_ HOOKPROC  lpfn,
      _In_ HINSTANCE hMod,
      _In_ DWORD     dwThreadId
    );
    

    参数说明:

    1、 idHook:钩子类型,此处填写WH_GETMESSAGE

    2、 lpfn:钩子的过程函数,也就是钩子触发的时候要执行的代码

    3、 hMod:钩子过程函数所在的DLL模块句柄,在DLL初始化的获得(DllMain的第一个参数)

    4、 dwThreadId:与钩子程序关联的线程ID,此处填0,表示关联系统中的所有线程

    返回值:

    钩子句柄

    0x02 编写需要注入的DLL:

    DLL大致需要实现以下内容:

    1、 设置钩子

    2、 取消钩子

    3、 钩子过程函数

    4、 导出相关函数

    DLL的主要实现代码如下:

    #include "pch.h"

    HHOOK g_hHook;
    HMODULE g_hModule;

    LRESULT CALLBACK GetMsgProc(
         _In_ int    code,
         _In_ WPARAM wParam,
         _In_ LPARAM lParam
    )
    {
         return CallNextHookEx(g_hHook, code, wParam, lParam);
    }

    BOOL LoadHook(void)
    {
         g_hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, g_hModule, 0);
         if (g_hHook){
             MessageBox(NULL, TEXT("钩子加载成功!"), TEXT("提示"), MB_OK);
             return TRUE;   
         }
         else
             return FALSE;
    }

    VOID UnloadHook(void)
    {
         if(g_hHook)
             UnhookWindowsHookEx(g_hHook);
    }

    BOOL APIENTRY DllMain( HMODULE hModule,
                            DWORD  ul_reason_for_call,
                            LPVOID lpReserved
                          )
    {
         switch (ul_reason_for_call)
         {
         case DLL_PROCESS_ATTACH:
             g_hModule = hModule;
             MessageBox(NULL, TEXT("加载DLL!"), TEXT("提示"), MB_OK);
             break;
         case DLL_THREAD_ATTACH:
         case DLL_THREAD_DETACH:
         case DLL_PROCESS_DETACH:
             break;
         }
         return TRUE;
    }

    新建def文件导出相关函数:

    LIBRARY


    EXPORTS
    LoadHook
    UnloadHook

    编译生成 TestDLL.dll 文件

    0x03 编写调用程序:

    DLL不能主动执行,因此需要编写调用程序:

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

    #define  DLL_NAME    "TestDLL.dll"

    int main(int argc, char* argv[])
    {
         do{
             HMODULE hModule = LoadLibraryA(DLL_NAME);
             if(hModule == NULL)
                 break;
             FARPROC pfnLoadHook = GetProcAddress(hModule, "LoadHook");
             FARPROC pfnUnloadHook = GetProcAddress(hModule, "UnloadHook");
             if(pfnLoadHook==NULL || pfnUnloadHook==NULL)
                 break;
             if (pfnLoadHook())
                 printf("全局钩子加载成功! ");
             else{
                 printf("全局钩子加载失败! ");
                 break;
             }
             printf("按任意键卸载全局钩子! ");
             getchar();
             pfnUnloadHook();
             printf("全局钩子卸载完成! ");
         }while(FALSE);

        getchar();
         return 0;
    }

    注:为了简化出错处理,使用了 do-while(0) 结构

    0x04 验证:

    先打开PCHunter查看:

    1

    可以看到此时系统应用层没有任何全局消息钩子

    为了方便观察,打开系统自带的Notepad,并使用调试器附加:

    2

    编译生成 TestDLL.dll 文件和调用程序放在同一路径下,并且执行调用程序:

    3

    可以发现已经成功将DLL注入到了当前系统的很多进程当中,用调试器附加的Notepad进程可以非常直观的看到结果

    同时在PCHunter中也可以直观的看到结果:

    4

  • 相关阅读:
    38) 收集centos所有版本镜像下载地址
    37) 查看linux 操作系统为多少位
    php面向对象高级应用一
    php form表单的验证+提交到数据库
    php获取form表单数据
    php form表单的提交
    php form表单概念
    php日期和时间的应用
    php日期和时间函数
    php字符串函数操作实例(2)
  • 原文地址:https://www.cnblogs.com/DarkBright/p/10835761.html
Copyright © 2020-2023  润新知