首页
社区
课程
招聘
实现全局键盘钩子,但不知为什么SetWindowsHookEx总是失败
发表于: 2005-5-28 22:47 13572

实现全局键盘钩子,但不知为什么SetWindowsHookEx总是失败

2005-5-28 22:47
13572
想实现全局键盘钩子,但不知为什么SetWindowsHookEx返回的总是失败,也查了许多资料,从原理上来看实在想不出有什么错误,各位能不能帮我看一下?

/*************************************************************
*KeyBoardHookLib.h
**************************************************************/

#define EXPORT extern "C" __declspec (dllexport)

#pragma data_seg ( "shared" )
HHOOK hKeyboard = NULL ;
HINSTANCE hDllInstance = NULL ;
#pragma data_seg ()
#pragma comment ( linker, "/section:shared,rws" )

EXPORT BOOL WINAPI SetHook ( BOOL isInstall ) ;

/**************************************************************
*KeyBoardHookLib.cpp
**************************************************************/
#include <windows.h>
#include "KeyBoardHookLib.h"

int WINAPI DLLMain ( HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved )
{ 
	hDllInstance = hInstance ;
	return true ;
}

LRESULT CALLBACK KeyboardProc ( int nCode, WPARAM wParam, LPARAM lParam )
{
	EVENTMSG *keyMSG = ( EVENTMSG * )lParam ;
	if( ( nCode == HC_ACTION ) && ( keyMSG->message == WM_KEYDOWN ))
	{
		char KeyName[10] ;
		ZeroMemory ( KeyName, 10 ) ;

		GetKeyNameText ( lParam, KeyName, 50 ) ;
		MessageBox ( NULL, KeyName, NULL, MB_OK ) ;
	}

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

EXPORT BOOL WINAPI SetHook ( BOOL isInstall ) 
{
	if ( isInstall )
	{
		hKeyboard =	SetWindowsHookEx ( WH_KEYBOARD, KeyboardProc, hDllInstance, 0 ) ;
		if ( hKeyboard != NULL )
			return true ;
	}

	else
	{
		UnhookWindowsHookEx ( hKeyboard ) ;
		hKeyboard = NULL ;
		hDllInstance = NULL ;
	}

	return false ;
}

/*************************************************************
*KeyBoardHookTest.cpp
*************************************************************/
#include <windows.h>
#include "KeyBoardHookLib.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
					PSTR szCmdLine, int iCmdShow )
{
	static TCHAR szAppName[] = TEXT ( "全局键盘钩子" ) ;
	
	WNDCLASS wndClass ;
	wndClass.style         = CS_HREDRAW | CS_VREDRAW ;
    wndClass.lpfnWndProc   = WndProc ;
    wndClass.cbClsExtra    = 0 ;
    wndClass.cbWndExtra    = 0 ;
    wndClass.hInstance     = hInstance ;
    wndClass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
    wndClass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
    wndClass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
    wndClass.lpszMenuName  = NULL ;
    wndClass.lpszClassName = szAppName ;
     
    if ( !RegisterClass ( &wndClass ) )
    {
		MessageBox ( NULL, TEXT ( "This program requires Windows NT!" ),
			szAppName, MB_ICONERROR ) ;

		return 0 ;
    }
    
	HWND hwnd ;
    hwnd = CreateWindow ( szAppName, TEXT ("实现全局键盘钩子"),
						WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        NULL, NULL, hInstance, NULL ) ;
     
	ShowWindow (hwnd, iCmdShow) ;
    UpdateWindow (hwnd) ;

	if ( SetHook ( true ) )			//安装键盘钩子函数
		MessageBox ( NULL, "HOOK SUCCESS!", NULL, MB_OK ) ;
	else
		MessageBox ( NULL, "HOOK FAILED!", NULL, MB_OK ) ;
	
	MSG msg ;
    while (GetMessage (&msg, NULL, 0, 0))
    {
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
    }

    return msg.wParam ;    
}

LRESULT CALLBACK WndProc ( HWND hwnd, UINT message,
						  WPARAM wParam, LPARAM lParam )
{
	switch ( message )
	{
	case WM_DESTROY:
		SetHook ( false ) ;  //卸载键盘钩子函数
		PostQuitMessage (0) ;
        return 0 ; 
	}

	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 200
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
DllMain
实在是太初级了!!!
2005-5-29 03:22
0
雪    币: 200
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
编译也不会提示出错,Kick VC
2005-5-29 03:23
0
雪    币: 4908
活跃值: (2343)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
4
对C代码并不熟悉
2005-5-29 12:44
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
5
2楼的朋友,我改为DllMain后,SetWindowsHookEx返回的还是失败

通过调试,很明显DLL的代码已经被执行,就是这句执行返回的是失败  hKeyboard =  SetWindowsHookEx ( WH_KEYBOARD, KeyboardProc, hDllInstance, 0 ) ;
2005-5-29 17:53
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
6
自己顶一下,

我用LordPE查看进程,也有自己的DLL

哎~~~

救命啊~~
2005-5-29 22:30
0
雪    币: 200
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我用了你的代码试过,是可以的哦。

你SetWindowsHookEx后用GetLastError看看错误的原因呀。
2005-5-30 08:31
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
8
最初由 Boneasher 发布
我用了你的代码试过,是可以的哦。


朋友你不要吓我,怎么可能??

用GetLastError()得到
    1428L      ERROR_HOOK_NEEDS_HMOD
(不能在无模块句柄的情况下设置非本地的钩子程序。 )

用GOOGLE搜索ERROR_HOOK_NEEDS_HMOD,结构吓了我一跳,好象这个错误只存在理论上,没有解决方法。哎~~~
2005-5-30 10:00
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
9
又出现奇怪的事了,

刚才在菜单不小心按了下“重建全部”就OK了。

真想不通这是为什么?
郁闷了这么多天的 问题竟然这样的解决,我该 还是
2005-5-30 10:14
0
雪    币: 151
活跃值: (66)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
10
呵呵,在帮顶以下..
2005-5-30 10:39
0
雪    币: 228
活跃值: (85)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
11
我试了一下,发现跟楼主一样,无法 hook
后来把 DLLMain -> DllMain 就 Hook 成功了..
2005-5-30 10:51
0
雪    币: 1852
活跃值: (504)
能力值: (RANK:1010 )
在线值:
发帖
回帖
粉丝
12
顺便再问个问题,你们VC编译时用什么?

我一般都用F7,

如果上面这个程序成功之后,再把DllMain随便改成什么比如DddMain,   再F7编译没问题,运行,于是HOOK出错。
此时再改回DllMain,F7编译,再运行,HOOK还是出错。
但若此时“重建全部”,一切都可以了。

问题就在这里
2005-5-30 10:59
0
雪    币: 228
活跃值: (85)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
13
我是用 cl
因为我都是用 Delphi 开发.. 所以 C or C++ 我都是直接用
command prompt 下的 cl ^^b
2005-5-30 11:15
0
游客
登录 | 注册 方可回帖
返回
//