在控制台程序中使用键盘钩子的问题

nostopping 2008-10-23 10:31:53
程序的功能是:当按键盘上的某个键时,弹出按键提示,并退出钩子

下面是钩子DLL的内容:
**************.h*************
#ifndef Hdll_H
#define Hdll_H

extern "C" int _declspec(dllexport)InstallHOOK();

extern "C" int _declspec(dllexport)UninstallHOOK();

LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam);
#endif


********.cpp****************
#include "stdafx.h"

#include "Hdll.h"
#include <stdio.h>

#pragma data_seg ("shared")
static HHOOK g_hHook=NULL;
#pragma data_seg ()

HINSTANCE g_hInst;
DWORD ProcessID = 0;
LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam);

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = HINSTANCE(hModule);
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return 1;
}

LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{

MessageBox(NULL,"key pressed","",MB_OK);

return CallNextHookEx(g_hHook,code,wParam,lParam);
}
int InstallHOOK()
{
g_hHook=SetWindowsHookEx(WH_KEYBOARD,GetMsgProc,g_hInst,0);
if (g_hHook)
return TRUE;
else
return FALSE;
}

int UninstallHOOK()
{
if (UnhookWindowsHookEx(g_hHook)==0)
return FALSE;
else
return TRUE;
}

1.请问如何屏蔽win键?
2.我这个DLL是在控制台程序中调用的,当焦点位于控制台窗口之外的时候,按键盘上的某个键钩子能够获取到信息,
但当焦点处于控制台窗口时,再按键盘的话就没有反应,这是为什么?
3.如何在获取第一次键盘信息之后,退出钩子?

...全文
1089 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
supercow 2008-11-04
  • 打赏
  • 举报
回复
挂钩 NtResumeThread 实现全局Hook 来自安焦的文章.
http://www.xfocus.net/articles/200805/981.html

楼主,上面的方法已经是比较底层了, 希望对你有用.
针对hook Consle 貌似看到过比较巧妙的方法, 不过找不到了, 以后再次看到再贴吧.
yjgx007 2008-11-04
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 dandycheung 的回复:]
yjgx007:你说的不是事情的本质。getchar 什么的只不过是 CRT 对系统 API 的封装,虽然说从 console 相关的 API 中并不能看到有消息循环的影子,但是那仅仅是因为 console API 以及 console 窗口的实现者把消息循环掩盖起来了而已。在系统内部的实现,console 仍然是一个窗口,自然有自己的消息循环,这是由 Windows 系统的本质决定的。
[/Quote]
i'm study now, waiting for more better answers.
nostopping 2008-11-04
  • 打赏
  • 举报
回复
31楼的内容很强啊!
虽然没有全部看懂,但是感觉通过这种方法HOOK控制台应该是可以实现的.
我先学习一下这方面的知识,有结果了再贴出来.
希望大家继续关注并参与讨论,谢谢!
qinde025 2008-11-03
  • 打赏
  • 举报
回复
asdfsdf
pleasechangegreat 2008-10-31
  • 打赏
  • 举报
回复
先收藏,有功夫再看
nostopping 2008-10-31
  • 打赏
  • 举报
回复
回复26楼:
d:\vcpro\hooktest\hooktest\hooktest.cpp(20) : error C2065: 'MSG' : undeclared identifier
我是在控制台用的,是不是还要包含头文件?
dandycheung 2008-10-29
  • 打赏
  • 举报
回复
yjgx007:你说的不是事情的本质。getchar 什么的只不过是 CRT 对系统 API 的封装,虽然说从 console 相关的 API 中并不能看到有消息循环的影子,但是那仅仅是因为 console API 以及 console 窗口的实现者把消息循环掩盖起来了而已。在系统内部的实现,console 仍然是一个窗口,自然有自己的消息循环,这是由 Windows 系统的本质决定的。
yjgx007 2008-10-29
  • 打赏
  • 举报
回复
int _tmain(int argc, _TCHAR* argv[])
{
char ch;
if (!InstallHook())
{
cout < < "Install Hook Fail" < < endl;
}

MSG msg;
while (ret = GetMessage(&msg, NULL, 0, 0))
{
if (ret == -1) break; // error...
TranslateMessage(&msg);
DispatchMessage(&msg);
}


return 0;
}


建议你写个简单的有消息循环的窗口测试程序,入口在WinMain
yjgx007 2008-10-29
  • 打赏
  • 举报
回复
如果你的console程序不是用getchar,而是用while(getmessage(...)),有消息循环,是可以捕获到的。
SetWindowsHookEx是干什么的?是拦截消息的,对吧?没有消息,只有键盘中断 - getchar,怎么能捕获?
dandycheung 2008-10-29
  • 打赏
  • 举报
回复
控制台程序的窗口和桌面窗口在系统里比较特殊,这两类窗口的窗口过程是在内核中的,基本上用户态的钩子不能对这两类窗口产生作用。

其实 9 楼提供的信息非常有帮助,不知道大家为什么一点都不去理会。
nostopping 2008-10-29
  • 打赏
  • 举报
回复
回复21楼:(cnzdgs)
所有代码如下:

//**********HOOKDLL.h*************
#ifndef HOOKDLL_H
#define HOOKDLL_H

#ifdef _HOOK_PORT
#define HOOKPORT __declspec(dllexport)
#else
#define HOOKPORT __declspec(dllimport)
#endif

extern "C" bool HOOKPORT InstallHook(void);
extern "C" bool HOOKPORT UninstallHook(void);

#endif

//*********HOOKDLL.cpp***************
#define _HOOK_PORT
#include "stdafx.h"
#include "HOOKDLL.h"
//#include <window.h>

#pragma data_seg ("shared")
static HHOOK g_hHook=NULL;
#pragma data_seg ()

HINSTANCE g_hInst;

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hInst = HINSTANCE(hModule);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
PKBDLLHOOKSTRUCT klhs = (PKBDLLHOOKSTRUCT)lParam;
if (klhs->vkCode == 'A') //注释条件,直接return true也不行
{
return TRUE;
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

bool InstallHook()
{
g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, g_hInst, 0);
if (g_hHook)
return true;
else
return false;
}

bool UninstallHook()
{
if (UnhookWindowsHookEx(g_hHook))
return true;
else
return false;

}

//***********Win 32 控制台 .cpp******************
#include "stdafx.h"
#include "HookDLL.h"
#include <iostream>
using namespace std;

#pragma comment(lib,"HookDLL.lib")


int _tmain(int argc, _TCHAR* argv[])
{
char ch;
if (!InstallHook())
{
cout << "Install Hook Fail" << endl;
}

do
{
ch = getchar();

}while(ch != 'q');

return 0;
}

运行控制台程序,在程序中输入a,程序反应倒是慢了点,但还是接收到了.
怎么才能HOOK住控制台输入?
WinEggDrop 2008-10-28
  • 打赏
  • 举报
回复
有人说控制台程序"没消息循环当然也没有钩子",我写了个控制台程序去屏蔽win键

http://210.17.223.165/DisableKey.exe

控制台程序,在命令行下执行,执行后就会屏蔽win键.想退出,使用CTRL+C组合键.单个exe程序,没带任何DLL,压缩后3K不到,VC 6.0编译.

cnzdgs 2008-10-28
  • 打赏
  • 举报
回复
很简单的问题怎么搞得这么麻烦,这问题与远程线程一点关系都没有。你用下面这段代码,看看控制台能不能输入字母A。注意SetWindowHookEx不要写错。
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
{
PKBDLLHOOKSTRUCT klhs = (PKBDLLHOOKSTRUCT)lParam;
if (klhs->vkCode == 'A')
{
return TRUE;
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}

g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, g_hInst, 0);
nostopping 2008-10-28
  • 打赏
  • 举报
回复
WH_KEYBOARD_LL 已经试过了,也是不行的.
楼上有说用远程线程注入的,不知道是怎么一回事,
能不能再说得详细点,或给个大至的思路?
谢了!
sanshao27 2008-10-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zmlovelx 的回复:]
利用底层键盘钩子屏蔽任意按键
http://blog.chinaunix.net/u2/67530/showart_602918.html
[/Quote]
这个里面说的挺详细的
编程-鸟人-_-- 2008-10-28
  • 打赏
  • 举报
回复
UP!
cnzdgs 2008-10-27
  • 打赏
  • 举报
回复
是用的WH_KEYBOARD_LL吗?你用上面我给的代码试试,在控制台窗口按WIN键,在没有Hook的时候可以显示出开始菜单,Hook之后就显示不出来了。

分只能加1次,不过已经不少了。
nostopping 2008-10-27
  • 打赏
  • 举报
回复
代码如上啊,我在MFC里面调用上面的DLL是没有问题的,但是用控制台程序调用的话,钩子就不能获取到控制台窗口的输入了,也就是钩子HOOK不了控制台窗口的键盘输入消息,网上也有关于此类的问题,但都是不了了之,希望大家积极参与,提出自己的想法.这个问题解决之后,我一定总结一下,发到网上,供他人之用.当然,分,还可以再加,请多多观注,谢谢!
yeah920 2008-10-27
  • 打赏
  • 举报
回复
帮你顶一下.
cnzdgs 2008-10-26
  • 打赏
  • 举报
回复
代码怎么写的?
加载更多回复(13)
Windows环境下32位汇编语言程序设计 第2版(罗文斌) 完整光盘内容,包含每章内容的完整代码 本光盘所包含目录的说明 根目录下的 *.pdf ;附录A、B、C的电子版文档 Chapter02\Test ;测试编译环境 Chapter03\HelloWorld ;Hello World Chapter04\FirstWindow ;用Win32汇编写第一个窗口 Chapter04\FirstWindow-1 ;用Win32汇编写第一个窗口 Chapter04\SendMessage ;窗口间的消息互发 Chapter04\SendMessage-1 ;窗口间的消息互发 Chapter05\Menu ;使用资源 - 使用菜单 Chapter05\Icon ;使用资源 - 使用图标 Chapter05\Dialog ;使用资源 - 使用对话框 Chapter05\Listbox ;使用资源 - 使用列表框 Chapter05\Control ;使用资源 - 使用子窗口控件 Chapter05\ShowVersionInfo ;使用资源 - 显示版本信息资源的程序 Chapter05\VersionInfo ;使用资源 - 使用版本信息资源 Chapter06\Timer ;定时器的使用 Chapter07\DcCopy ;在两个窗口的 DC 间互相拷贝屏幕 Chapter07\Clock ;模拟时钟程序 Chapter07\BmpClock ;用 Bitmap 图片做背景的模拟时钟程序 Chapter07\TestObject ;一些常见的绘图操作 Chapter08\CommDlg ;使用通用对话框 Chapter09\Toolbar ;使用工具栏 Chapter09\StatusBar ;使用状态栏 Chapter09\Richedit ;使用丰富编辑控件 Chapter09\Wordpad ;一个完整的文本编辑器例子 Chapter09\SubClass ;窗口的子类化例子 Chapter09\SuperClass ;窗口的超类化例子 Chapter10\MemInfo ;显示当前内存的使用情况 Chapter10\Fragment ;内存碎片化的演示程序 Chapter10\FindFile ;全盘查找文件的例子 Chapter10\FormatText ;文件读写例子 Chapter10\FormatText\FileMap ;使用内存映射文件进行文件读写的例子 Chapter10\MMFShare ;使用内存映射文件进行进程间数据共享 Chapter11\Dll\Dll ;最简单的动态链接库例子 - 编写 DLL Chapter11\Dll\MASM Sample ;最简单的动态链接库例子 - 使用 DLL Chapter11\Dll\VC++ Sample ;最简单的动态链接库例子 - 在VC++使用汇编编写的DLL Chapter11\KeyHook ;Windows 钩子的例子 - 监听键盘动作 Chapter11\RecHook ;Windows 日志记录钩子的例子 - 监听键盘动作 Chapter12\Counter ;有问题程序 - 一个计数程序 Chapter12\Thread ;用多线程的方

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧