首页 >> 大全

C++如何禁用全局键盘钩子或者程序钩子?

2023-04-23 大全 122 作者:考证青年

今天给大家分享一下c++键盘钩子的知识,同时也讲解一下键盘钩子c#。如果你碰巧解决了你现在面临的问题,别忘了关注这个网站,现在就开始!

如何使用键盘挂钩

I:设置挂钩

设置钩子是通过()的API函数。

原型:hhook (int id hook, lpfn,,dword )

:装载挂钩的类型。

Lpfn:钩子进程的入口地址。

HMod:应用程序的事件处理器。

装载挂钩的螺纹ID。

参数:

:

该参数可以是下列值:

、、WH_C *** 、、、、、、、、、、、、WH_SY *** 。

我不想一一解释这些参数,因为它们在MSDN有详细的解释。我只选择其中的几个用中文解释。

WH _键盘:一旦有敲击键盘的消息(键盘被按下,键盘弹出),会调用你的钩子函数,然后把这个消息放入应用程序的消息队列中。钩子函数可以改变和丢弃击键消息。

WH _鼠标:在每个鼠标消息被放入应用程序的消息队列之前,会调用你的钩子函数。钩子函数可以改变和丢弃鼠标消息。

:每次你的应用程序调用()或()从应用程序的消息队列中请求消息时,都会调用你的钩子函数。钩子函数可以改变并丢弃这个消息。

二:松开挂钩。

钩子的释放使用()函数。

原型: (h hook HHK)

钩子函数释放钩子链中函数加载的钩子进程。

Hhk:要释放的钩子进程的句柄。

三:挂钩过程

钩子子程使用函数。实际上,只是应用程序定义的一个符号。比如你可以写。但是参数是一样的。Win32 API提供的函数有:、、、C *** Proc、、、等。关于他们的详细解释,请参考MSDN。我只是解释一下在这里的意思。

原型:回调键盘钩子(int ncode, , )

说明:钩子进程是一个附加在钩子上的函数,所以钩子进程只被调用,不被应用程序调用,所以有时候需要作为回调函数使用。

参数描述:

NCode:钩子代码,钩子进程用它来决定是否执行。钩子代码的值取决于钩子的种类。每种挂钩类型都有自己的一套特征代码。比如对于WH _键盘,钩子代码的参数是:,。的含义:参数和包含击键消息的信息,的含义:参数和包含击键消息的信息,击键消息从不从消息队列中删除。(应用程序调用函数并设置标志)。也就是说,当nCode等于时,钩子子程必须处理消息。当它是时,钩子子程必须将消息传递给函数而不做进一步的处理,并且必须有函数的返回值。

:键盘敲击产生的键盘消息,键盘按键的虚拟代码。

:包含消息的细节。

注意:如果钩子进程中的nCode小于零,钩子进程必须返回 (ncode,,);钩子子程中的nCode大于零,但是钩子子程不处理消息。作者建议你调用,返回这个函数的返回值。否则,如果另一个应用程序也装载了WH键盘钩子,钩子将不接受钩子通知并返回一个不正确的值。如果钩子进程处理一个消息,它可能会返回一个非零值,以防止系统将消息传递给其他剩余的钩子或进程。所以更好在钩子子程的最后返回的返回值。

IV:调用下一个钩子函数

调用下一个钩子函数时使用函数。

原型: (hhook hhk,int ncode, , )

函数的作用是:将钩子信息传递给当前钩子链中的下一个钩子子程。钩子子程可以在钩子信息被处理之前或之后调用这个函数。为什么要使用这个功能已经在hook iii过程中的"注意事项"中详细解释过了。

Hhk:当前钩子的句柄

NCode:传递给挂钩进程的挂钩代码。

:传递给挂钩进程的值。

:传递给挂钩进程的值。

参数:

当前钩子的句柄。应用程序接受这个句柄作为先前调用函数的结果。

NCode:传递给钩子进程的钩子代码,下一个钩子进程用它来决定如何处理钩子信息。

WPRAM:传输到挂钩进程的WPRAM参数值。参数值的具体含义与当前钩子链的钩子类型有关。

:传输给钩子进程的参数值。参数值的具体含义与当前钩子链的钩子类型有关。

返回值:返回值是链中下一个钩子子程返回的值。当前钩子子程必须返回这个值。返回值的具体含义与钩子的钩子类型有关。具体请参考具体的hook流程描述。

构建动态链接库(DLL)

当我们熟悉了上面的函数,就开始写动态链接库(dll)吧。我这里用WIN32 DLL代替MFC DLL。而下面的程序都是用C语言写的。这主要是因为使用WIN32 API可以更细致更全面的控制程序的执行,而使用MFC,一些底层的控制是做不到的(当然MFC也可以只用于这个程序)。

1.建立动态链接库。Cpp文件。例如,我们现在创建一个名为.cpp的文件。

#包括.h

#包含“.h”

#包含“stdio.h”

hInst

# (" ")

HHOOK旧key hook = 0;

# ()

#注释(链接器,“/:,RWS”)

# dll " C " _ _ (dll )

回调(int nCode, , );

void安装挂钩(int nCode);

void结束钩(void);

BOOL dll main(h h ,ULONG What, )

{

切换(什么)

{

案例:

hInst =

打破;

案例:

打破;

案例:

打破;

案例:

打破;

}

返回1;

}

void (int nCode)

{

old key hook = (wh _ ,(),hInst,0);

}

回调(int nCode, , )。

{

j;

文件* fp

if()

{

j =

fp=fopen("c:\hook\key.txt "," a ");

(fp," %4d ",j);

(FP);

}

返回(,nCode,,);

}

空中心端钩(空中心)

{

(旧钥匙钩);

}

这个动态链接库的源代码.cpp包含了键盘处理函数,设置钩子,退出钩子函数。键盘敲出来的键作为值存储在c:.txt文件中。以下是对这份文件的详细解释。

要使用DLL中包含的函数,您必须导入它。导入操作通过完成,和都是vc( C++)和bc( C++)支持的扩展关键字。但是,和关键字不能单独使用,因此必须在它之前添加另一个扩展关键字。一般格式如下:()其中是存储类标识符。对于dll,说明符将是和。此外,为了简化描述导入和导出函数的语句,使用了一个宏名来代替。在这个程序中,使用了。如果你把用户的DLL编译成C++程序,希望C程序也可以用,那就需要加一个“C”连接描述。#定义dll导出 "c" _ _ (DLL )以避免破坏标准C++命名。当然,如果读者是在编译C程序,就不要加“C”了,因为没有必要,编译器不会接受。使用宏定义,您现在可以用一个简单的语句导出函数,例如:

回调(int nCode, , ); void安装挂钩(int nCode); void结束钩(void);

之一个#语句创建了一个数据段,此处命名为。其实你爱怎么叫都行。#语句之后的所有初始化变量都进入段。第二个#语句是数据段的结束标记。对变量进行特殊的初始化是非常重要的,否则编译器会把它们放在普通的未初始化段中,而不是中。

但是链接器必须等到有一个段。我们可以在项目设置(vc6.0)对话框中选择链接选项。选择时,它位于项目选项字段(在发布和调试配置中)中,并包含以下连接语句:/: Hook data,字母RWS表示该段具有读取、写入和共享属性。当然,也可以直接使用DLL源代码指定链接器,就像hook DLL . c:# (,"/: hook data,rws ")。

因为有些dll需要特殊的开始和停止代码。因此,所有DLL都有一个名为()的函数,该函数在DLL初始化或终止时被调用。这个函数一般在动态链接库的资源文件中定义。但是,如果没有定义,编译器将自动提供默认形式。

原型是 dll min(h h ,Ulong What, )。

参数:

:DLL实例句柄

什么:具体说明发生了什么。

未使用的:保留参数

其中的值可以是:

:进程开始使用DLL。

:进程正在释放DLL。

:进程创建了一个新线程。

:进程放弃了一个线程。

一般来说,无论何时调用()函数,都必须根据内容采取适当的动作。这个适当的操作什么也不做,但是它不返回非零值。

()的下一步是设置钩子,处理键盘并释放钩子。

2.创建一个头文件

就像应用程序使用的任何其他库函数一样,程序也必须在dll中包含函数的原型。所有程序都必须包含.h的原因,所以我们现在创建一个头文件.h如下:

# " C " _ _ ()

void安装挂钩(int nCode);

调用 (int nCode, , );

void (void);

主要是用来让代码更高效,所以推荐使用。但是导入数据时需要。完成上述程序后,构建一个项目,比如,然后将.c插入试点项目并编译,这样就可以生成.dll和.lib。

3.建立程序主文件

以上我们所做的一切工作都是为当前的主程序打下基础。事实上,当我们完成Dll文件时,剩下的就是调用set hook函数:。如果熟悉编程,必要时可以调用。但是现在你必须记住,当你退出程序的时候,你需要调整来释放你加载的钩子函数。现在我正在构建一个.cpp,将生成的.lib和.lib复制到一个目录中,构建一个项目。插入钩子间谍。CPP,挂钩dll dll,挂钩dll Lib和挂钩Dll。h输入项目。然后在创建窗口时设置钩子,退出程序时退出钩子函数。例如:

案例:

安装钩子(TRUE);

打破;

案例WM _ ://终止程序。

();

(0);

打破;

键盘记录器(键盘钩子)的C++实现

什么都不要说,先去源码。

#包括.h

#包含.h

#包含一个字符串

#包括

#包括

在命名空之间使用std

(int Key) //确定键盘按的是什么键。

{

字符串 =

//判断符号输入

const int按键掩码= 0x //键盘掩码常量

int是s hift = 状态(0x 10);//判断Shift键状态

bool IS =(IS shift按键掩码)= =按键掩码;//表示按下Shift键。

if(Key =186 Key =222)

{

开关(钥匙)

{

案例186:

如果(为)

= ":";

其他的

= ";";

打破;

案例187:

如果(为)

= "+";

其他的

= " =

打破;

案例188:

如果(为)

密钥串=

其他的

= ",";

打破;

案例189:

如果(为)

钥匙串= " _

其他的

= "-";

打破;

案例190:

如果(为)

密钥串=

其他的

= ",";

打破;

案例191:

如果(为)

= "?";

其他的

= "/";

打破;

案例192:

如果(为)

= "~

其他的

密钥串=

打破;

案例219:

如果(为)

= " {

其他的

= "[";

打破;

案例220:

如果(为)

= " |

其他的

= " \ \

打破;

案例221:

如果(为)

= " }

其他的

= "]";

打破;

案例222:

如果(为)

=

其他的

=

打破;

}

}

//判断键盘的之一行

If (Key == ) //退出

= "[Esc]";

Else if (Key == VK_F1) // F1到F12

= "[F1]";

else if (Key == VK_F2)

= "[F2]";

else if (Key == VK_F3)

= "[F3]";

else if (Key == VK_F4)

= "[F4]";

else if (Key == VK_F5)

= "[F5]";

else if (Key == VK_F6)

= "[F6]";

else if (Key == VK_F7)

= "[F7]";

else if (Key == VK_F8)

= "[F8]";

else if (Key == VK_F9)

= "[F9]";

else if (Key == )

= "[F10]";

else if (Key == )

= "[F11]";

else if (Key == )

= "[F12]";

Else if (Key == VK快照)//打印屏幕。

= "[PRS CrN]";

Else if (Key == VK滚动)//滚动锁定

= "[ Lock]";

Else if(Key = = VK _暂停)//暂停,中断

= "[Pause]";

Else if (Key == VK大写)//大写锁定

= "[Caps Lock]";

// - //

//控制键

Else if (Key == 8) //-退格键

= "[back space]";

Else if (Key == ) //回车键,换行。

= "[Enter]\ n ";

(key = = vk _ space)/空格

密钥串=

//Shift键:键盘录音时,不需要录音。单个班次不会有任何字符,

Shift键与其他键组合来输出字符。

/*

Else if (Key == ) //向左键移动。

= "[Shift]";

Else if (Key == ) //向右键移动。

= "[SHIFT]";

*/

/*如果只记录键盘输入的字母:下列键可能不会输出到文件*/

Else if (Key == ) // tab键

= "[Tab]";

Else if(Key = = VK控制)//左控制键

= "[Ctrl]";

Else if(Key = = VK遥控)//右控制键

= "[CTRL]";

Else if(Key = = VK菜单)//移动左键

= "[Alt]";

Else if(Key = = VK菜单)//向右移动键。

= "[ALT]";

Else if (Key == ) //右键

= "[Win]";

Else if (Key == ) //右窗口键

= "[WIN]";

Else if (Key == VK应用程序)//右击键盘。

= "右键单击";

Else if(Key = = VK _插入)//插入

= "[]";

Else if(Key = = VK _删除)//删除

= "[]";

Else if (Key == ) // Start

= "[Home]";

否则if (Key == ) // End。

= "[End]";

Else if (Key == ) //上一页

= "[PgUp]";

Else if (Key == ) //下一页

= "[pg down]";

//几个不常用的键:一般键盘没有。

Else if(Key = = VK _取消)//取消

= "[]";

Else if (Key == ) //清除

= "[Clear]";

Else if (Key == VK选择)//选择

= "[]";

Else if(Key = = VK _ PRINT)//打印

= "[Print]";

Else if(Key = = VK _ )//执行

= "[]";

// - //

Else if(Key = = VK _左)//上、下、左、右。

= "[←]";

Else if(Key = = VK _右)

= "[→]";

else if (Key == VK_UP)

= "[↑]";

Else if (Key == VK向下)

= "[↓]";

Else if(Key = = VK _数字锁)//键盘数字锁

= "[]";

Else if (Key == ) //加减乘除。

= "+";

else if (Key == VK_SU *** RACT)

= "-";

Else if (Key == VK乘法)

= " *

Else if(Key = = VK _除)

= "/";

else if(Key = = 190 | | Key = = 110)// .和一个键盘。

= ",";

//键盘数字键:0-9

else if (Key == )

= " 0

else if (Key == )

= " 1

else if (Key == )

= " 2

else if (Key == )

= " 3

else if (Key == )

= " 4

else if (Key == )

= " 5

else if (Key == )

= " 6

Else if(Key = = VK数字键盘7)

= " 7

Else if(Key = = VK数字键盘8)

= " 8

Else if(Key = = VK数字键盘9)

= " 9

// - //

// - //

//*判断字母大小写*//

Else if (Key =97 Key = 122) //字母:a-z

{

If(get (vk _ ))//大写锁定

{

If(IS) //Shift键:小写字母。

= Key

Else //仅大写锁定:输出大写字母。

密钥串= Key-32;

}

Else//大写不锁定。

{

如果(为)//按Shift键:大写字母。

密钥串= Key-32;

Else // Shift键未按下:小写字母

= Key

}

}

Else if (Key =48 Key = 57) //键盘号:0-9及以上。

{

如果(为)

{

开关(钥匙)

{

案例48: //0

= ")";

打破;

案例49://1

= "!";

打破;

案例50://2

= " @

打破;

案例51://3

= " #

打破;

案例52://4

= " $

打破;

案例53://5

= " %

打破;

案例54://6

key = " ^ ";

打破;

案例55://7

密钥串=

打破;

案例56://8

= " *

打破;

案例57://9

= "(";

打破;

}

}

其他的

= Key

}

如果(关键!= || Key!= VK _按钮)

{

If (Key =65 Key =90) //ASCII 65-90是a-z。

{

If(get (vk _ ))//大写锁定:输出A-Z

{

如果(是)//大写锁定,按shift键:输出小写字母。

密钥串= Key+32;

Else //仅大写锁定:输出是大写字母。

= Key

}

Else //大写不锁定:a-z

{

如果(为)

{

= Key

}

其他的

{

Key = Key+32;

= Key

}

}

}

}

返回密钥串

}

int main()

{

= " D:\ \ log。txt ";//倾倒的记录文本存储在D盘的log.txt目录下..

字符串临时字符串=

Cout“现在开始键盘录音”;

.open(.c_str(),STD::::out | STD::::app);

While(真)

{

睡眠(5);

for(int I = 8;i = 255i++)

{

if((i)1 ==1)

{

= (I);

.write(.c_str()、。size());

。close();

.open(.c_str(),STD::::out | STD::::app);

}

}

}

}

C++如何禁用全局键盘钩子或者程序钩子?

对于普通程序,一个双缓冲钩子就够了(相当于一个假顶钩子),代码如下:

HHOOK =空,m _ =空

m _ HHOOK 1 =(HHOOK)(WH _ _ LL,(),(L“HOOK”),0);HOOK成为你的模块名。

m _ HHOOK 2 =(HHOOK)(WH _ _ LL,(),(L“HOOK”),0);//同上

while (/**/true)

{

(m _ hhook 1);

m _ HHOOK 1 =(HHOOK)(WH _ _ LL,(),(L“HOOK”),0);//同上

(m _ hhook 2);

m _ HHOOK 2 =(HHOOK)(WH _ _ LL,(),(L“HOOK”),0);//同上

}

对于TX ***(无亲测)登录部分等异常程序,建议使用winio或其高级库进行驱动级拦截(无亲测)。

如果还是抓鸡,那就只能把那个程序往前推做手术了,这需要楼主有一定的汇编语言知识(我没练过,不能保证成功)。

我想用C语言写一个全局键盘钩子程序,成功后发100分!

全局键盘挂钩需要在dll中实现。

我认为你还不能写出dll是什么。

但是我有好消息告诉你。

Log hook可以在程序中实现全局键盘捕获:

VC代码:

#.h

HHOOK = NULL

回调(int code, , )

{

event msg * =(event msg *);

if(code==)

{

开关(-消息)

{

case ():

字节bkey state[256];

无符号短UAS CII[4];

UINT

内部资源

(bkey状态);

bkey state[VK _ SHIFT]= state(VK _ SHIFT);

us can code =(-param h16);

iRet=(-,,,,0);

开关(iRet)

{

案例0:

打破;

案例1:

if((char)u ascii[0]= = ' t ' |(char)u ascii[0]= = ' t ')//t按键。

{

(空,“t已按下”,“按键提示”,MB _ ok);

/* * * * * * * * * * * *实现自己播放音乐的功能* * * * * * * * * * * * * * * *

}

else if((char)u ascii[0]= ' y ' | |(char)u ascii[0]= = ' y ')//y键按下。

{

(空,“y按”,“按键提示”,MB _ ok);

/* * * * * * * * * * * *我是来实现停止播放音乐的功能的* * * * * * * * * *

}

打破;

默认值:

打破;

}

默认值:

打破;

}

}

返回(,code,,);

}

int (h实例h实例,

LPSTR ,

int

)

{

log hook = (WH _日志记录,,,NULL);

以及(1)睡眠(100);

返回0;

}

日志挂钩不稳定。

以上是c++键盘钩子和键盘钩子c#的介绍。不知道你有没有从中找到你需要的信息?如果你想了解更多这方面的内容,记得关注这个网站。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了