首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EasyHook停止捕捉一些消息

EasyHook停止捕捉一些消息
EN

Stack Overflow用户
提问于 2021-09-15 00:47:10
回答 1查看 165关注 0票数 0

一旦EasyHook EasyHook64.dll拦截第一个DefWindowProcW消息,并从它启动一个线程,它就不再捕获任何DefWindowProcW

代码语言:javascript
复制
|___ DefWindowProcW (caught)
     |--
     |--
     |--
     |-- DefWindowProcW (don't 'intercept' anymore)
     |-- ...

它停止“捕获”所有DefWindowProcW消息,直到线程结束。

有人告诉我:

这是设计上的,它是线程死锁屏障的一部分。

和:

您可以为同一个函数安装两个钩子,在输入第一个钩子之前,将第二个钩子禁用,然后通过将其ACL包含在当前线程中来启用它,然后在离开第一个钩子时再次禁用它。

然后我试着把它叫做:

代码语言:javascript
复制
HOOK_TRACE_INFO hHook  = { NULL }; 
HOOK_TRACE_INFO hHook2 = { NULL }; 
HOOK_TRACE_INFO hHook3 = { NULL };


LRESULT __stdcall DefWindowProcW_Hook(  HWND   hWnd,    UINT   Msg, WPARAM wParam,  LPARAM lParam)
{

    switch (Msg) {
        //......
    }

    ULONG ACLEntries[1]  = { 0 };
    LhSetInclusiveACL(ACLEntries, 1, &hHook);
    ULONG ACLEntries2[1] = { 0 };
    LhSetInclusiveACL(ACLEntries2, 1, &hHook2);
    ULONG ACLEntries3[1] = { 0 };
    LhSetInclusiveACL(ACLEntries2, 1, &hHook3); 

   return DefWindowProcW(hWnd, Msg, wParam, lParam);
}


// =======================================

void __stdcall NativeInjectionEntryPoint(REMOTE_ENTRY_INFO* inRemoteInfo)
{

        LhInstallHook(
            GetProcAddress(GetModuleHandle(TEXT("user32")), "DefWindowProcW"),
            DefWindowProcW_Hook,    NULL,   &hHook);

        ULONG ACLEntries[1] = { 0 };
        LhSetExclusiveACL(ACLEntries4, 1, &hHook);
        

        LhInstallHook(
            GetProcAddress(GetModuleHandle(TEXT("user32")), "DefWindowProcW"),
            DefWindowProcW_Hook,    NULL,   &hHook2);

        LhInstallHook(
            GetProcAddress(GetModuleHandle(TEXT("user32")), "DefWindowProcW"),
            DefWindowProcW_Hook,    NULL,   &hHook3);
}

但是现在,看起来所有的钩子都在做同样的事情:

结果:

当有第二个或更多嵌套调用时,想问使用或已经使用EasyHook的人如何正确读取相同的函数。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-19 02:43:52

在EasyHook中没有这方面的优雅解决方案,但是如果您乐于安装嵌套级别所需的尽可能多的中间钩子,则可以将它们链接在一起。

最外层的钩子是最初启用的唯一一个。

它将首先确保所有最内部的钩子被禁用,然后启用下一个钩子。

为了防止为同一个DefWindowProcW调用调用钩子,我们可以检索下一个钩子的旁路地址并调用它,而不是像通常那样调用原始DefWindowProcW。

正如您已经发现的,一旦进入钩子的钩子处理程序,它将不会再次触发相同的钩子,直到返回语句完成,并且我们已经返回调用堆栈。这是由于EasyHook中的线程死锁屏障造成的。

示例:

代码语言:javascript
复制
HOOK_TRACE_INFO hHook  = { NULL };
HOOK_TRACE_INFO hHook2 = { NULL };
HOOK_TRACE_INFO hHook3 = { NULL };
typedef LRESULT __stdcall DefWindowProcFunc(HWND, UINT, WPARAM, LPARAM);

// Innermost hook handler
LRESULT __stdcall DefWindowProcW_Hook( HWND   hWnd, UINT   Msg, WPARAM wParam, LPARAM lParam)
{

switch (Msg) {
//......
}

   // Innermost hook just call original

   return DefWindowProcW(hWnd, Msg, wParam, lParam);
}


// Middle hook handler
LRESULT __stdcall DefWindowProcW_Hook2( HWND   hWnd, UINT   Msg, WPARAM wParam, LPARAM lParam)
{

switch (Msg) {
//......
}

   // Activate next hook handler for next nesting level
   ULONG ACLEntries[1]  = { 0 };
   LhSetInclusiveACL(ACLEntries, 1, &hHook);

   PVOID* bypass_address;
   LhGetHookBypassAddress(&hHook, &bypass_address);
   
   //return DefWindowProcW(hWnd, Msg, wParam, lParam);
   
   // Bypass the handler for THIS call to DefWindowProcW - the next nested call will be captured in  DefWindowProcW_Hook
   return ((DefWindowProcFunc*)bypass_address)(hWnd, Msg, wParam, lParam);
}

// Outermost hook handler
LRESULT __stdcall DefWindowProcW_Hook3( HWND   hWnd, UINT   Msg, WPARAM wParam, LPARAM lParam)
{
    // Outermost hook handler - this will be called first for new calls to DefWindowProcW

switch (Msg) {
//......
}

   // Disable innermost hook(s) - do this for each inner hook that isn't the next hook
   ULONG disableACLEntries[1]  = { 0 };
   LhSetExclusiveACL(disableACLEntries, 1, &hHook);

   // Activate next hook handler for first nesting level
   ULONG ACLEntries[1]  = { 0 };
   LhSetInclusiveACL(ACLEntries, 1, &hHook2);

   PVOID* bypass_address;
   LhGetHookBypassAddress(&hHook2, &bypass_address);
   
   //return DefWindowProcW(hWnd, Msg, wParam, lParam);

   // Bypass the handler for THIS call to DefWindowProcW - the next nested call will be captured in DefWindowProcW_Hook2
   return ((DefWindowProcFunc*)bypass_address)(hWnd, Msg, wParam, lParam);
}

// =======================================

void __stdcall NativeInjectionEntryPoint(REMOTE_ENTRY_INFO* inRemoteInfo)
{
    // NOTE: the last installed hook handler will be the first called i.e. hHook3, then hHook2 then hHook.
    LhInstallHook(
        GetProcAddress(GetModuleHandle(TEXT("user32")), "DefWindowProcW"),
        DefWindowProcW_Hook, NULL, &hHook);

    LhInstallHook(
        GetProcAddress(GetModuleHandle(TEXT("user32")), "DefWindowProcW"),
        DefWindowProcW_Hook2, NULL, &hHook2);
       
    LhInstallHook(
        GetProcAddress(GetModuleHandle(TEXT("user32")), "DefWindowProcW"),
        DefWindowProcW_Hook3, NULL, &hHook3);
       
    // Activate outermost hook (ie last installed hook which will be the first called - hHook3)
    ULONG ACLEntries[1] = { 0 };
    LhSetExclusiveACL(ACLEntries, 1, &hHook3);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69185909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档