Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
254 views
in Technique[技术] by (71.8m points)

c++ - SetWindowsHookEx hooking into every running program

I have written a small DLL that is being injected into a game to apply runtime fixes. I've decided to add some Keyboard Listeners:

while (1)
    if (AsyncKeyState(...)) (...)

However, this is taking up CPU usage, and introducing some noticeable stuttering. So I decided to use a callback methodology as suggested by MSDN via SetWindowsHookExA and a KeyboardProc callback. At first, I was running the method via SetWindowsHookExA(WH_Keyboard, KeyboardProc, NULL, 0) but was getting error code ERROR_HOOK_NEEDS_HMOD (0x594). So I changed my code to become like this:

bool APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID lpRes)
{
    HHOOK hook_ = nullptr;
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
        
        if (!(hook_ = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hModule, 0)))
        {
            char x[100];
            sprintf(x, "Failed To Hook Keyboard FN: 0x%X", GetLastError());
            MessageBox(NULL, x, "Error", MB_ICONERROR);
        }
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        UnhookWindowsHookEx(hook_);
        break;
    }
    return true;
}

This was not giving the error anymore, and my hooking Keyboard function was working perfectly. However, a very unintended side-effect was that all keyboard captures from all running applications are being ignored. I noticed this quote from MSDN, so I added it to my code:

If code is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.

That fixed the keyboard issue, but now there's another issue, which is I'm unable to delete the DLL I created. When I attempt to delete it, it says "dll is running in Explorer.exe". when I kill explorer.exe, it says "dll is running in SteamHelper.exe". When I kill steamhelper.exe, it says "dll is running in Chrome.exe". This shows me that I've somehow hooked into every running application?

I'm unable to fix this issue, and I couldn't find any help on it. Any insight is greatly appreciated!

question from:https://stackoverflow.com/questions/65922595/setwindowshookex-hooking-into-every-running-program

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You ARE hooking every application process, because you are installing the hook globally, by setting the dwThreadId parameter of SetWindowsHookEx() to 0:

dwThreadId

Type: DWORD

The identifier of the thread with which the hook procedure is to be associated. For desktop apps, if this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread. For Windows Store apps, see the Remarks section.

Instead, you should set that parameter to the actual thread ID of the game thread that you want to hook events for.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...