SetWinEventHook应用于进程注入

SetWinEventHook


函数原型:

HWINEVENTHOOK SetWinEventHook(
  DWORD        eventMin,
  DWORD        eventMax,
  HMODULE      hmodWinEventProc,
  WINEVENTPROC pfnWinEventProc,
  DWORD        idProcess,
  DWORD        idThread,
  DWORD        dwFlags
);

引用微软开发文档:

This function allows clients to specify which processes and threads they are interested in.

If the idProcess parameter is nonzero and idThread is zero, the hook function receives the specified events from all threads in that process. If the idProcess parameter is zero and idThread is nonzero, the hook function receives the specified events only from the thread specified by idThread. If both are zero, the hook function receives the specified events from all threads and processes.

Clients can call SetWinEventHook multiple times if they want to register additional hook functions or listen for additional events.

The client thread that calls SetWinEventHook must have a message loop in order to receive events.

When you use SetWinEventHook to set a callback in managed code, you should use the GCHandle structure to avoid exceptions. This tells the garbage collector not to move the callback.

For out-of-context events, the event is delivered on the same thread that called SetWinEventHook. In some situations, even if you request WINEVENT_INCONTEXT events, the events will still be delivered out-of-context. These scenarios include events from console windows and events from processes that have a different bit-depth (64 bit versus 32 bits) than the caller.

While a hook function processes an event, additional events may be triggered, which may cause the hook function to reenter before the processing for the original event is finished. The problem with reentrancy in hook functions is that events are completed out of sequence unless the hook function handles this situation. For more information, see Guarding Against Reentrancy.

Windows Store app development If dwFlags is WINEVENT_INCONTEXT AND (idProcess = 0 | idThread = 0), then window hook DLLs are not loaded in-process for the Windows Store app processes and the Windows Runtime broker process unless they are installed by UIAccess processes (accessibility tools). The notification is delivered on the installer’s thread.

This behavior is similar to what happens when there is an architecture mismatch between the hook DLL and the target application process, for example, when the hook DLL is 32-bit and the application process 64-bit.

着重关注:调用SetWinEventHook的客户端线程必须具有消息循环才能接收事件。如果没有消息循环,则会发现SetWinEventHook成功,但是并没有任何事件进入回调!!!

The client thread that calls SetWinEventHook must have a message loop in order to receive events.

微软官方,同时也给处理调用示例:

// Global variable.在这里插入代码片
HWINEVENTHOOK g_hook;

// Initializes COM and sets up the event hook.
//
void InitializeMSAA()
{
    CoInitialize(NULL);
    g_hook = SetWinEventHook(
        EVENT_SYSTEM_MENUSTART, EVENT_SYSTEM_MENUEND,  // Range of events (4 to 5).
        NULL,                                          // Handle to DLL.
        HandleWinEvent,                                // The callback.
        0, 0,              // Process and thread IDs of interest (0 = all)
        WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); // Flags.
}

// Unhooks the event and shuts down COM.
//
void ShutdownMSAA()
{
    UnhookWinEvent(g_hook);
    CoUninitialize();
}

// Callback function that handles events.
//
void CALLBACK HandleWinEvent(HWINEVENTHOOK hook, DWORD event, HWND hwnd, 
                             LONG idObject, LONG idChild, 
                             DWORD dwEventThread, DWORD dwmsEventTime)
{
    IAccessible* pAcc = NULL;
    VARIANT varChild;
    HRESULT hr = AccessibleObjectFromEvent(hwnd, idObject, idChild, &pAcc, &varChild);  
    if ((hr == S_OK) && (pAcc != NULL))
    {
        BSTR bstrName;
        pAcc->get_accName(varChild, &bstrName);
        if (event == EVENT_SYSTEM_MENUSTART) 
        {
            printf("Begin: ");
        }
        else if (event == EVENT_SYSTEM_MENUEND)
        {
            printf("End:   ");
        }
        printf("%S\n", bstrName);
        SysFreeString(bstrName);
        pAcc->Release();
    }
}

通过以上官方说明,已经对事件钩子有了一定了解,我们此时只关注:怎么实现DLL注入到拥有某些事件的进程?微软对此函数参数说明中:

hmodWinEventProc

Type: HMODULE

Handle to the DLL that contains the hook function at lpfnWinEventProc, if the WINEVENT_INCONTEXT flag is specified in the dwFlags parameter. If the hook function is not located in a DLL, or if the WINEVENT_OUTOFCONTEXT flag is specified, this parameter is NULL.
直译:如果在dwFlags参数中指定了WINEVENT_INCONTEXT标志,则处理包含在lpfnWinEventProc上的钩子函数的DLL。 如果挂钩函数不在DLL中,或者指定了WINEVENT_OUTOFCONTEXT标志,则此参数为NULL。

通过此说明,想要实现DLL注入,必须指定hmodWinEventProc为当前DLL的HMODULE,并且dwFlags必须包含:WINEVENT_INCONTEXT 。dwFlags可组合有:

WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS
WINEVENT_INCONTEXT | WINEVENT_SKIPOWNTHREAD
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNTHREAD

SetWinEventHook实现DLL注入,则需要调用此接口为DLL项目,并且SetWinEventHook参数需指定类似为:

SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_VALUECHANGE, (HMODULE)m_hInstance, s_WinEventProc, 0, 0, WINEVENT_INCONTEXT | WINEVENT_SKIPOWNPROCESS);

m_hInstance:值为DllMain传入的hModule。
以上调用,安装事件钩子成功后,只要进程拥有GUI属性,基本都能捕获并且注入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值