S.l.e!ep.¢%

像打了激速一样,以四倍的速度运转,开心的工作
简单、开放、平等的公司文化;尊重个性、自由与个人价值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理
DLL Inject -- 一、Windows 钩子(Hooks) - (1)

之前搞复杂了,其实可以很简单

有个要点:
The global hooks are a shared resource, and installing one affects all applications in the same desktop as the calling thread. All global hook functions must be in libraries. Global hooks should be restricted to special-purpose applications or to use as a development aid during application debugging. Libraries that no longer need a hook should remove its hook procedure.

作为一个全局或跨进程的钩子,钩子的实现函数必须在DLL中实现,不然目标程序触发到钩子时就会挂掉

DLL实现

// DLLInject.cpp : Defines the entry point for the DLL application.
//

#include 
"stdafx.h"
#include 
<stdio.h>

LRESULT CALLBACK CallWndProc(
int code, WPARAM wParam, LPARAM lParam)

    
return CallNextHookEx (NULL, code, wParam, lParam);
}

BOOL APIENTRY DllMain( HANDLE hModule, 
                      DWORD  ul_reason_for_call, 
                      LPVOID lpReserved
                      )
{
    
switch ( ul_reason_for_call )
    {
    
case DLL_PROCESS_ATTACH:
        {
            
char szDllName[MAX_PATH]={0};
            GetModuleFileName((HMODULE)hModule, szDllName, MAX_PATH);
            LoadLibrary(szDllName);        
            
break;
        }
    
case DLL_PROCESS_DETACH:
        {
        }
        
break;
    }
    
    
return TRUE;
    
}

在DLL加载时,调用多一次,LoadLibrary的目的,是为了增加引用计数,这样即使我们的程序关掉了,系统也不会卸载掉DLL,DLL还在内存中(所以通常情况下 LoadLibrary 和 FreeLibrary 要成对调用, 具体可以了解下 Windows 的内存管理机制)

调用代码:
HHOOK g_hHook = NULL;
UINT  g_nHOOKMsg 
= 0;

//---------------------------------------------------------------------------
// ModuleFromAddress
//
// Returns the HMODULE that contains the specified memory address
//---------------------------------------------------------------------------
static HMODULE ModuleFromAddress(PVOID pv) 
{
    MEMORY_BASIC_INFORMATION mbi;
    
    
return ((::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0? (HMODULE) mbi.AllocationBase : NULL);
}

void CDLLInjectBySetHookDlg::OnButton1() 
{    
    HMODULE hModule 
= ::LoadLibrary("DLLInject.dll");
    
if ( hModule == NULL )
    {
        AfxMessageBox(
"Failed to LoadLibrary!");
        
return ;
    }

    typedef LRESULT (CALLBACK 
*CallWndProc)(int code, WPARAM wParam, LPARAM lParam);
    CallWndProc pfnCallWndProc 
= (CallWndProc)::GetProcAddress(hModule, "CallWndProc");

    
if ( pfnCallWndProc == NULL )
    {
        AfxMessageBox(
"Failed to GetProcAddress!");
        
return ;
    }

    HWND hWnd 
= ::FindWindow(NULL, "testHooked");
    
if (hWnd == NULL)
    {
        AfxMessageBox(
"Failed to Find Window!");
        
return ;
    }

    DWORD dwThreadID 
= ::GetWindowThreadProcessId(hWnd, NULL);
    
if ( dwThreadID == 0 )
    {
        AfxMessageBox(
"Failed to Get Window Thread Process ID");
        
return ;
    }

    g_hHook 
= ::SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)(pfnCallWndProc), ModuleFromAddress(pfnCallWndProc), dwThreadID);

    
if ( g_hHook == NULL )
    {
        AfxMessageBox(
"Failed to Set Windows Hook");
        
return ;
    }

    ::SendMessage(::FindWindow(NULL, 
"testHooked"), WM_USER, 00);
    ::UnhookWindowsHookEx(g_hHook);
}


按下按钮,使用工具查看,目标程序的加载模块列表中已经有了 DLLInject.dll ,注入成功!

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理