keyboad hook dll无法正常工作

时间:2016-06-08 05:50:14

标签: winapi keyboard hook

dll中keyhook.cpp的代码:

// KeyHook.cpp : 定义 DLL 应用程序的导出函数。
//
#include "stdafx.h"

#include "stdio.h"
#include "Windows.h"
#pragma comment(linker, "/SECTION:.SHARED,RWS")
#pragma data_seg(".SHARED")
#define DEF_PROCESS_NAME "notepad.exe"

HINSTANCE g_hInstance = NULL;
HHOOK g_hHook = NULL;

HWND g_hWnd = NULL;
#pragma data_seg()
BOOL APIENTRY DllMain(HINSTANCE hModule,DWORD  ul_reason_for_call,LPVOID        lpReserved)
{
    printf("main function in dll\n");
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        g_hInstance = hModule;  
        printf("max=%d\n", MAX_PATH);
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{

//OutputDebugString("what the hell\n");
    char szPath[MAX_PATH] = { 0, };
    char *p = NULL;
//printf("the callback function");
    int shift = nCode;
    if (shift = 0) 
    {

        if (!(lParam & 0x80000000))
        {
            GetModuleFileNameA(NULL, szPath, MAX_PATH);
            p = strrchr(szPath, '\\');
        //printf("szPath=%s\n", szPath);
            OutputDebugString("what the hell\n");
            if (!_stricmp(p + 1, DEF_PROCESS_NAME))
                return 1;
        }
    }
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
#ifdef __cplusplus
extern "C" {
#endif // DEBUG

    __declspec(dllexport) void HookStart()
    {
        printf("hookstart function\n");
        g_hHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, g_hInstance, 0);
        if (g_hHook == NULL)
            printf("failed to install the keyboard hook");
        else
        {
            printf("Succeed in installing the keyboard hook");
        }

    }

    __declspec(dllexport) void HookStop()
    {
        if (g_hHook)
        {
            UnhookWindowsHookEx(g_hHook);
            g_hHook = NULL;
        }
        printf("hookstop function\n");
    }
#ifdef __cplusplus
}
#endif // DEBUG

调用应用程序代码:

// hkeybi.cpp : 定义控制台应用程序的入口点。

#include "stdafx.h"
#include<stdio.h>
#include<conio.h>
#include<Windows.h> 

#define DEF_DLL_NAME "KeyHook.dll"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"

typedef void(*PFN_HOOKSTART)();
typedef void(*PFN_HOOKSTOP)();

int main()
{
    int ch = -1;
    HMODULE hDll = NULL;
    PFN_HOOKSTART HookStart = NULL;
    PFN_HOOKSTOP HookStop = NULL;

    hDll = LoadLibraryA(DEF_DLL_NAME);
    HookStart = (PFN_HOOKSTART)GetProcAddress(hDll, DEF_HOOKSTART);
    HookStop = (PFN_HOOKSTOP)GetProcAddress(hDll, DEF_HOOKSTOP);
    if ((HookStart != NULL) && (HookStop != NULL))
        printf("hello start\n");
    HookStart();

    printf("press q to exit!\n");
    while (_getch() != 'q');

    HookStop();

    FreeLibrary(hDll);
    return 0;
}

当我运行应用程序时,在我输入几个单词后,它会下降。我花了很长时间来解决这个问题。

1 个答案:

答案 0 :(得分:2)

您的KeyboardProc功能有几个问题。第一个是分配了shift变量而不是测试:

if (shift = 0)

变量分配为0,因此条件始终为false。实际上,测试后执行的唯一代码是return CallNextHookEx(...)。如果条件为真,则可能会遇到问题,因为GetModuleFileNameA结果未经过测试。如果出现错误,则以下strrchr可能会失败,p指针将为NULL。这将导致_stricmp崩溃。为什么你专门使用GetModuleFileName的ANSI版本,你确定你没有使用Unicode吗?最后,在不调用CallNextHookEx的情况下返回钩子proc是一个坏主意。以下是documentation所说的内容:

  

如果代码大于或等于零,则钩子程序执行   不处理消息,强烈建议您拨打电话   CallNextHookEx并返回它返回的值