【Inline Hook基础篇】框架搭建

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fzuim/article/details/81297578


  • Windows程序员对于HOOK技术应该都很熟悉,HOOK俗称:钩子。即将自己想实现的功能,挂钩到系统的函数上,达到调用系统的函数时能自动执行我们实现的功能。
  • 对于HOOK,也分为:消息钩子,API钩子,内核钩子。消息钩子和API钩子都是在应用层(Ring3)上实现,内核钩子则是在内核层(Ring0)上实现的。此次开篇,逐重讨论下Inline Hook的实现方式,Inline Hook也是API钩子的一种实现方式。
  • 搭建这个Hook框架时,我们需要先简单了解下消息钩子,因为消息钩子可以让我们编写的DLL轻松的注入到各个窗体当中。消息钩子安装涉及到一个API:

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

HHOOK SetWindowsHookEx(   
    int idHook,      // 钩子的类型,即它处理的消息类型   
    HOOKPROC lpfn,   // 钩子子程的地址指针。如果dwThreadId参数为0   
                     // 或是一个由别的进程创建的线程的标识,   
                     // lpfn必须指向DLL中的钩子子程。   
                     // 除此以外,lpfn可以指向当前进程的一段钩子子程代码。   
                     // 钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。   
    HINSTANCE hMod,  // 应用程序实例的句柄。标识包含lpfn所指的子程的DLL。   
                     // 如果dwThreadId 标识当前进程创建的一个线程,   
                     // 而且子程代码位于当前进程,hMod必须为NULL。   
                     // 可以很简单的设定其为本应用程序的实例句柄。   
    DWORD dwThreadId // 与安装的钩子子程相关联的线程的标识符。   
                     // 如果为0,钩子子程与所有的线程关联,即为全局钩子。   
);

//钩子类型 idHook 选项:
WH_MSGFILTER       = -1; {线程级; 截获用户与控件交互的消息}
WH_JOURNALRECORD   = 0;  {系统级; 记录所有消息队列从消息队列送出的输入消息, 在消息从队列中清除时发生; 可用于宏记录}
WH_JOURNALPLAYBACK = 1;  {系统级; 回放由 WH_JOURNALRECORD 记录的消息, 也就是将这些消息重新送入消息队列}
WH_KEYBOARD        = 2;  {系统级或线程级; 截获键盘消息}
WH_GETMESSAGE      = 3;  {系统级或线程级; 截获从消息队列送出的消息}
WH_CALLWNDPROC     = 4;  {系统级或线程级; 截获发送到目标窗口的消息, 在 SendMessage 调用时发生}
WH_CBT             = 5;  {系统级或线程级; 截获系统基本消息, 譬如: 窗口的创建、激活、关闭、最大最小化、移动等等}
WH_SYSMSGFILTER    = 6;  {系统级; 截获系统范围内用户与控件交互的消息}
WH_MOUSE           = 7;  {系统级或线程级; 截获鼠标消息}
WH_HARDWARE        = 8;  {系统级或线程级; 截获非标准硬件(非鼠标、键盘)的消息}
WH_DEBUG           = 9;  {系统级或线程级; 在其他钩子调用前调用, 用于调试钩子}
WH_SHELL           = 10; {系统级或线程级; 截获发向外壳应用程序的消息}
WH_FOREGROUNDIDLE  = 11; {系统级或线程级; 在程序前台线程空闲时调用}
WH_CALLWNDPROCRET  = 12; {系统级或线程级; 截获目标窗口处理完毕的消息, 在 SendMessage 调用后发生}
  • 消息钩子卸载API:

BOOL WINAPI UnhookWindowsHookEx( In HHOOK hhk );//函数成功返回TRUE,否则返回FALSE。

  • 系统钩子与线程钩子:
    SetWindowsHookEx()函数的最后一个参数决定了此钩子是系统钩子还是线程钩子。 0为系统钩子
    线程勾子用于监视指定线程的事件消息。线程勾子一般在当前线程或者当前线程派生的线程内。
    系统勾子监视系统中的所有线程的事件消息。因为系统勾子会影响系统中所有的应用程序,所以勾子函数必须放在独立的动态链接库(DLL) 中。系统自动将包含”钩子回调函数”的DLL映射到受钩子函数影响的所有进程的地址空间中,即将这个DLL注入了那些进程。
  • 几点说明:
    (1)如果对于同一事件(如鼠标消息)既安装了线程勾子又安装了系统勾子,那么系统会自动先调用线程勾子,然后调用系统勾子。
    (2)对同一事件消息可安装多个勾子处理过程,这些勾子处理过程形成了勾子链。当前勾子处理结束后应把勾子信息传递给下一个勾子函数。
    (3)勾子特别是系统勾子会消耗消息处理时间,降低系统性能。只有在必要的时候才安装勾子,在使用完毕后要及时卸载。
  • 介绍完消息,我们初步框架的实现方式也发现了:利用挂钩系统级消息,安装一个全局钩子,达到注入各个进程的目的。
  • 我们直接编写一个DLL(VS2008,选择MFC DLL项目),并开放:注册和释放两个接口。
HINSTANCE       g_hInstance = NULL;    // 模块实例句柄

//钩子回调,默认不处理直接传递给系统的下一个钩子
LRESULT WINAPI HookProc( int nCode, WPARAM wParam, LPARAM lParam ) 
{
    // 传给系统中的下一个钩子
    return CallNextHookEx( g_hHook, nCode, wParam, lParam ); 
}

/********************************************************************/
/* 安装钩子              */
/* 参数: (无)             */
/* 返回值: TRUE 成功, FALSE 失败         */
/********************************************************************/
BOOL WINAPI StartWork()
{
    // 如果已经安装钩子则返回 FALSE
    if (g_hHook != NULL) return FALSE;
    // 安装钩子
    g_hHook = SetWindowsHookEx( WH_CALLWNDPROC, HookProc, g_hInstance, NULL);
    if (g_hHook == NULL) 
    {
        return FALSE;
    }

    return TRUE;

}

/********************************************************************/
/* 释放钩子              */
/* 参数: (无)             */
/* 返回值: (无)         */
/********************************************************************/
void WINAPI StopWork()
{
    if (NULL != g_hHook)
    {
        UnhookWindowsHookEx(g_hHook);
        g_hHook = NULL;
    }
}
  • 在DLL被载入到内存的时候,进行一次g_hInstance的值设置。
BOOL CFileTransferApp::InitInstance() 
{
    g_hInstance = this->m_hInstance;
    return CWinApp::InitInstance();
}

int CFileTransferApp::ExitInstance() 
{
    return CWinApp::ExitInstance();
}

到此,全局消息钩子注入已经完成。看似很简单,但是这是我们进行API HOOK的基础,达到了能注入各个进程,我们就可以在InitInstance函数里面,进行API的挂钩操作。下一章节,我们将实现API挂钩(修改系统API前几个字节,实现JMP到我们自定义的API当中)。

猜你喜欢

转载自blog.csdn.net/fzuim/article/details/81297578