挂钩修改键盘输入

发布于 2024-12-19 02:00:23 字数 3085 浏览 0 评论 0原文

我正在尝试编写一个 DLL,它拦截键盘输入并在将值呈现给进程事件循环之前修改扫描/vkey 代码。简化的dll代码(由VS 2010生成):

#include "stdafx.h"
#include "hookdll.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif

static const char *LogFileName = "c:/tmp/hook_report.txt";
#define LogOpen() \
{\
        freopen(LogFileName, "w", stdout); \
}
#define Log(fmt, ...)   if ( 1 )\
{\
        fprintf(stdout, "%s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__);  \
        fflush(stdout); \
}


static HHOOK HookHandle;

char*
DbHookToString(LPARAM lParam)
{
    static char tmp[128];
    KBDLLHOOKSTRUCT* hs = (KBDLLHOOKSTRUCT*)lParam;
            sprintf(tmp,
            "vkCode=0x%02X"
            ", scanCode=0x%02X"
            ", flags=0x%08X"
            ", time=%d"
            ", dwExtraInfo=0x%08X",
            hs->vkCode
            , hs->scanCode
            , hs->flags
            , hs->time
            , hs->dwExtraInfo);
    return tmp;
}


LRESULT CALLBACK
keyHandler(int nCode, WPARAM wParam, LPARAM lParam) 
{
    // Checks whether params contain action about keystroke
    if(nCode == HC_ACTION)
    {
        KBDLLHOOKSTRUCT* hs = (KBDLLHOOKSTRUCT*)lParam;
        Log("IN:  %d: %s", wParam, DbHookToString(lParam));
        switch(hs->vkCode)
        {
            default:
                break;
            case 0x31:
                ++hs->vkCode;
                ++hs->scanCode;
                break;
            case 0x32:
                //--hs->vkCode;
                //--hs->scanCode;
                break;
        }
        Log("OUT: %d: %s\n", wParam, DbHookToString(lParam));
    }

    return CallNextHookEx(HookHandle, nCode, wParam, lParam);
}


BEGIN_MESSAGE_MAP(ChookdllApp, CWinApp)
END_MESSAGE_MAP()


ChookdllApp::ChookdllApp()
{
}



ChookdllApp theApp;



BOOL ChookdllApp::InitInstance()
{
    LogOpen();

    CWinApp::InitInstance();

    if (!AfxSocketInit())
    {
        Log("AfxSocketInit failed");
        return FALSE;
    }

    HookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, keyHandler, NULL, 0);
    if(HookHandle == NULL) 
    {
        Log("SetWindowsHookEx failed");
        return FALSE;
    }

    return TRUE;
}

应用程序代码的骨架形式是一个C++ Windows窗体应用程序,在单个窗体中包含单个文本框;问题是输入字符,特别是数字“1”键,即使 DLL 在日志文件中报告它正在被修改,也没有改变。帮助任何人吗?

...hookdll.cpp:84 IN:256:vkCode = 0x31,scanCode = 0x02,标志= 0x00000000,时间= 11326265,dwExtraInfo = 0x00000000 ...\hookdll.cpp:100 输出:256: vkCode=0x32, scanCode=0x03, flags=0x00000000, time=11326265, dwExtraInfo=0x00000000

...\hookdll.cpp:84 输入:257:vkCode=0x31,scanCode=0x02,标志=0x00000080,时间=11326374,dwExtraInfo=0x00000000 ...\hookdll.cpp:100 输出:257: vkCode=0x32, scanCode=0x03, flags=0x00000080, time=11326374, dwExtraInfo=0x00000000

...snip..

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e)
{
    HINSTANCE hinstDLL = LoadLibrary("hookdll.dll");
    if ( hinstDLL == NULL )
    {
        volatile int err = GetLastError();
        err += 1;
    }
}

...snip... 非常感谢。

I'm trying to write a DLL which intercepts keyboard input and modifies the scan/vkey codes prior to the values being presented to the process event loop. The simplified dll code (generated by VS 2010):

#include "stdafx.h"
#include "hookdll.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif

static const char *LogFileName = "c:/tmp/hook_report.txt";
#define LogOpen() \
{\
        freopen(LogFileName, "w", stdout); \
}
#define Log(fmt, ...)   if ( 1 )\
{\
        fprintf(stdout, "%s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__);  \
        fflush(stdout); \
}


static HHOOK HookHandle;

char*
DbHookToString(LPARAM lParam)
{
    static char tmp[128];
    KBDLLHOOKSTRUCT* hs = (KBDLLHOOKSTRUCT*)lParam;
            sprintf(tmp,
            "vkCode=0x%02X"
            ", scanCode=0x%02X"
            ", flags=0x%08X"
            ", time=%d"
            ", dwExtraInfo=0x%08X",
            hs->vkCode
            , hs->scanCode
            , hs->flags
            , hs->time
            , hs->dwExtraInfo);
    return tmp;
}


LRESULT CALLBACK
keyHandler(int nCode, WPARAM wParam, LPARAM lParam) 
{
    // Checks whether params contain action about keystroke
    if(nCode == HC_ACTION)
    {
        KBDLLHOOKSTRUCT* hs = (KBDLLHOOKSTRUCT*)lParam;
        Log("IN:  %d: %s", wParam, DbHookToString(lParam));
        switch(hs->vkCode)
        {
            default:
                break;
            case 0x31:
                ++hs->vkCode;
                ++hs->scanCode;
                break;
            case 0x32:
                //--hs->vkCode;
                //--hs->scanCode;
                break;
        }
        Log("OUT: %d: %s\n", wParam, DbHookToString(lParam));
    }

    return CallNextHookEx(HookHandle, nCode, wParam, lParam);
}


BEGIN_MESSAGE_MAP(ChookdllApp, CWinApp)
END_MESSAGE_MAP()


ChookdllApp::ChookdllApp()
{
}



ChookdllApp theApp;



BOOL ChookdllApp::InitInstance()
{
    LogOpen();

    CWinApp::InitInstance();

    if (!AfxSocketInit())
    {
        Log("AfxSocketInit failed");
        return FALSE;
    }

    HookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, keyHandler, NULL, 0);
    if(HookHandle == NULL) 
    {
        Log("SetWindowsHookEx failed");
        return FALSE;
    }

    return TRUE;
}

The app code, in skeleton form, is a C++ windows form app containing a single text box in a single form; problem is the input characters, specifically the number '1' key, are coming through unaltered even though the DLL is reporting in a log file that it is being modified. Help anyone?

...hookdll.cpp:84 IN: 256: vkCode=0x31, scanCode=0x02, flags=0x00000000, time=11326265, dwExtraInfo=0x00000000
...\hookdll.cpp:100 OUT: 256: vkCode=0x32, scanCode=0x03, flags=0x00000000, time=11326265, dwExtraInfo=0x00000000

...\hookdll.cpp:84 IN: 257: vkCode=0x31, scanCode=0x02, flags=0x00000080, time=11326374, dwExtraInfo=0x00000000
...\hookdll.cpp:100 OUT: 257: vkCode=0x32, scanCode=0x03, flags=0x00000080, time=11326374, dwExtraInfo=0x00000000

...snip..

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e)
{
    HINSTANCE hinstDLL = LoadLibrary("hookdll.dll");
    if ( hinstDLL == NULL )
    {
        volatile int err = GetLastError();
        err += 1;
    }
}

...snip...
Many thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文