简体   繁体   English

使用钩子向 explorer.exe main window 发送消息会导致崩溃?

[英]Sending message to explorer.exe main window with a hook causes crash?

I am trying to set a WH_CALLWNDPROC hook on a window using the HWND I got from WindowFromPoint and send a message WM_USER+x after.我正在尝试使用从WindowFromPoint获得的HWND在 window 上设置WH_CALLWNDPROC挂钩,然后发送消息WM_USER+x But depending on the HWND I use it crashes the window.但是根据我使用的HWND ,它会导致 window 崩溃。

Let me explain the scenario:让我解释一下这个场景:

When getting an HWND through the WindowFromPoint function you sometimes get one of the children's instead of the main window.当通过WindowFromPoint function 获取HWND时,您有时会得到一个子项而不是主要的 window。

Pretty good visualized with the Finder tool inside spy++使用 spy++ 中的 Finder 工具可以很好地可视化

HWND的

So I simply get the window所以我只是得到 window

wcout << "INFO: Waiting 1 second before first hwnd...\n";
this_thread::sleep_for(chrono::milliseconds(1000));
HWND targetHwnd = getHwndFromMousePos(); //Gets hwnd from mouse pos with WindowFromPoint
outHwndData(targetHwnd);
DWORD targetPID;
DWORD targetTID = GetWindowThreadProcessId(targetHwnd, &targetPID);

then set the hook by using the exported function of the dll.然后使用 dll 导出的 function 设置挂钩。

hook = setHook(targetTID); //hook is the global HHOOK and setHook is a exported function in a dll
if (hook == NULL) {
    cout << "ERROR: Could not set hook\n";
    return 1;
}

The function inside the dll looks like so dll里面的function长这样

extern "C" __declspec(dllexport) HHOOK __stdcall setHook(DWORD targetTid) {
    return SetWindowsHookEx(WH_CALLWNDPROC, wmProcCallback, hInst, targetTid);
}

When targetHwnd is a children HWND , I hook, send message -> works finetargetHwnd是一个孩子HWND时,我挂钩,发送消息 - >工作正常

But when targetHwnd is the upper HWND (green marked one), I hook it, send a message -> it crashes.但是当targetHwnd是上层HWND (绿色标记的一个)时,我挂钩它,发送消息 -> 它崩溃了。

在此处输入图像描述

So at the end SetWindowsHookEx works, but I am unable to send any messages to that found window if it is the upper HWND (green marked one).所以最后SetWindowsHookEx工作,但我无法向找到的 window 发送任何消息,如果它是上部HWND (绿色标记的一个)。 Why is that so?为什么?

This full demo code will wait 1 second before picking up the HWND .这段完整的演示代码将等待 1 秒,然后再获取HWND By hovering the mouse over the title bar on an explorer.exe window you can get the HWND that causes the crash.通过将鼠标悬停在 explorer.exe window 的标题栏上,您可以获得导致崩溃的HWND

Application code:申请代码:

//This is the app
#include <Windows.h>
#include <iostream>
#include <thread>

using namespace std;

typedef HHOOK(WINAPI* DLLFUNC_SETHOOK) (DWORD);

HINSTANCE dllInstance;
DLLFUNC_SETHOOK setHook;

HHOOK hook;

HWND getHwndFromMousePos() {
    POINT cursorPos;
    if (GetCursorPos(&cursorPos) == FALSE) {
        cout << "ERROR: Could not get Cursor position...\n";
        return NULL;
    }
    HWND wnd = WindowFromPoint(cursorPos);
    if (wnd == NULL) {
        cout << "ERROR: No window found on this point\n";
        return NULL;
    }
    return wnd;
}


int main() {

    wcout << "INFO: Waiting 1 second before first hwnd...\n";
    this_thread::sleep_for(chrono::milliseconds(1000));
    HWND targetHwnd = getHwndFromMousePos();

    wcout << targetHwnd << endl;
    DWORD targetPID;
    DWORD targetTID = GetWindowThreadProcessId(targetHwnd, &targetPID);

    dllInstance = LoadLibrary(L"DLL1.dll");
    setHook = (DLLFUNC_SETHOOK)GetProcAddress(dllInstance, "setHook");
    if (dllInstance == NULL) {
        cout << "ERROR: dllInstance is NULL\n";
        return 1;
    }
    if (setHook == NULL) {
        cout << "ERROR: setHook function is NULL\n";
        return 1;
    }

    hook = setHook(targetTID);
    if (hook == NULL) {
        cout << "ERROR: Could not set hook\n";
        return 1;
    }

    cout << "INFO: Hooked successfully\n";

    //Works only when targetHwnd is a children
    SendMessage(targetHwnd, WM_USER + 1, 0, 0); //This causes the crash

    cin.ignore();

    BOOL success = UnhookWindowsHookEx(hook);
    if (success == FALSE) {
        cout << "ERROR: Could not unhook\n";
    }
    else {
        cout << "INFO: Unhooked hook. Exiting...\n";
    }
}

The DLL(DLL1):动态链接库(DLL1):

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <fstream>

extern HINSTANCE hInst;
extern std::wofstream logfile;
extern "C" __declspec(dllexport) HHOOK __stdcall setHook(DWORD targetTid);

HINSTANCE hInst;
std::wofstream logfile;

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    hInst = hModule;
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH: { 
            logfile.open("D:\\projects\\crashDemo\\log.txt"); //run "Get-Content -Path "log.txt" -Wait" in Powershell for realtime logs
            break;
        }
        case DLL_THREAD_ATTACH: break;
        case DLL_THREAD_DETACH: break;
        case DLL_PROCESS_DETACH: {
            logfile.close();
            break;
        }
    }
    return TRUE;
}

LRESULT CALLBACK wmProcCallback(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode >= HC_ACTION) {
        PCWPSTRUCT cwpStruct = (PCWPSTRUCT)lParam;
        switch (cwpStruct->message) {
        case WM_USER + 1:
            logfile << "WM_USER+1 Message received" << std::endl;
            break;
        }
    }
    return CallNextHookEx(NULL, nCode, wParam, lParam);
}

extern "C" __declspec(dllexport) HHOOK __stdcall setHook(DWORD targetTid) {
    return SetWindowsHookEx(WH_CALLWNDPROC, wmProcCallback, hInst, targetTid);
}

EDIT: I did debug through.编辑:我调试通过。 It looks like everything is ok with the dll. It loads and the wmProcCallback is called several times as it should.看起来 dll 一切正常。它加载并多次调用wmProcCallback Also my WM_USER+1 is recognized but after handling all messages in the wmProcCallback it closes the window immediately and leaves the following error message.我的WM_USER+1也被识别,但在处理wmProcCallback中的所有消息后,它立即关闭 window 并留下以下错误消息。

在此处输入图像描述

So I got 4 error messages in total:所以我总共收到了 4 条错误信息:

  1. & 2. An outgoing call cannot be made since the application is dispatching an input-asynchronous call & 2. An outgoing call cannot be made since the application is dispatching an input-asynchronous call

  2. The operation is not permitted because the calling application is not the owner of the data on the clipboard.

  3. Unspecified error

Does someone know which of them relevant because I don't know any of these errors?有人知道其中哪些是相关的,因为我不知道这些错误中的任何一个吗? Gonna do some research now.现在要做一些研究。 Would be nice if someone can help out on this.如果有人可以帮助解决这个问题,那就太好了。

Simple fix, don't use WM_USER+1:)简单修复,不要使用 WM_USER+1 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM