2016-06-08 59 views
-3

在DLL中的keyhook.cpp代碼:的keyboad掛鉤DLL不能正常工作

// 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; 
} 

當我運行應用程序,之後我輸入幾個單詞,它會下降。我花了很長時間來解決這個問題。

+0

pre標籤和「輸入代碼在這裏」不包括在內。請您忽略它們 – freshman

+0

什麼應用程序崩潰?記事本或你的鉤安裝程序?當安裝鉤子並將它的dll加載到進程地址空間中時,您可以使用調試器附加它並查看確切的問題。 – Ari0nhh

回答

2

您的KeyboardProc功能有幾個問題。第一個是你shift變量被分配,而不是測試:

if (shift = 0) 

的變量分配0,條件是因此總是假的。實際上,測試後執行的唯一代碼是return CallNextHookEx(...)。如果條件成立,您可能會遇到問題,因爲GetModuleFileNameA結果未經測試。如果發生錯誤,則以下strrchr可能會失敗,指針將爲NULL。這將導致在_stricmp的崩潰。爲什麼你特別使用ANSI版本的GetModuleFileName,你確定你沒有使用Unicode嗎?最後,在不調用CallNextHookEx的情況下返回鉤子程序是一個壞主意。下面介紹一下documentation說:

如果代碼大於或等於零,並掛鉤過程並 不處理消息,強烈建議您致電 CallNextHookEx方法和返回值返回

+0

考慮到OP的代碼塊中的Unicode,您的Unicode建議可能是一個安全的選擇,而且他們應該做的事情。 – theB

+0

感謝您的回答。即使這個過程沒有執行,DLL也無法正常工作。輸入幾個單詞後,它就會死掉。然後添加消息循環代碼。它會流利地工作,但功能不起作用。 – freshman