HOOK编程

HOOK编程引用地址:https://eason.blog.csdn.net/article/details/7707821通过安装Hook过程,可以用来屏蔽消息队列中某些消息HHOOKSetWindows

大家好,又见面了,我是你们的朋友全栈君。

引用地址:https://eason.blog.csdn.net/article/details/7707821

 

通过安装Hook过程,可以用来屏蔽消息队列中某些消息

HHOOK SetWindowsHookEx(

int idHook,//钩子过程的类型

HOOKPROC lpfn,//钩子过程,如果dwThreadId 为0 ,或者指向一个其他进程创建的线程,则该参数必须指向一个位于动态链接库的钩子过程。否则,指向当前进程相关的代码中定义的钩子过程。

HINSTANCE hMod,//动态链接库句柄。如果dwThreadId 指定当前线程定义钩子过程,则该参数为NULL

DWORD dwThreadId   //为零表示和所有安装的线程相关

);

 

一、下面我们来创建一个屏蔽鼠标过程的hook:

1.创建基于MFC的一个InnerHook工程项目

2.在BOOL CInnerHookerDlg::OnInitDialog()中添加hook

SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());//当前线程的钩子过程安装。

要获得当前线程句柄,使用函数DWORD GetCurrentThreadId(void);

3.实现鼠标过程MouseProc为:

<span role="heading" aria-level="2">HOOK编程

LRESULT CALLBACK MouseProc(

int nCode,//如何处理当前消息

WPARAM wParam,//鼠标消息的信息

LPARAM lParam

)

{

return 1;  //返回值为一表示屏蔽鼠标过程

}

 

二、如果要屏蔽键盘消息,可以添加如下代码

1.在CPP文件中添加一个变量:HHOOK g_hKeyBoard;

2.在CInnerHookerDlg::OnInitDialog()中添加hook

g_hKeyBoard=SetWindowsHookEx(WH_KEYBOARD,KeyBoardProc,NULL,GetCurrentThreadId());

 

3.实现键盘过程keybroadProc为(只屏蔽空格键):

<span role="heading" aria-level="2">HOOK编程

4.下边添加代码使程序在F2键按下后退出。

要关闭窗口,首先要获得窗口的句柄,先声明一个全局变量Hwnd g_hWnd,

在OnInitDialog()中把窗口句柄传给它:

g_hWnd=m_hWnd;

接下来为键盘钩子过程添加代码:

<span role="heading" aria-level="2">HOOK编程

这时我们只能屏蔽主线程的键盘消息,如果要屏蔽所有消息,就得把代码放到动态链接库中实现。

三、屏蔽所有线程的消息

首先要创建一个动态链接库

1.新建一个Win32 Dynamic-Link Library项目工程Hook

  得到动态链接库模块的句柄有两种方式:

     方法1。DllMain函数方式:

<span role="heading" aria-level="2">HOOK编程

HMODULE和HINSTANCE可以通用

     方法2。GetModuleHandle函数方式

SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle(“Hook”),0);

<span role="heading" aria-level="2">HOOK编程

这样我们所安装的钩子过程就和运行在同一个桌面上的所有进程相关了

2.编写MouseProc()

<span role="heading" aria-level="2">HOOK编程

3.之后新建一个模块文件Hook.def,添加代码:

LIBRARY Hook

EXPORTS

SetHook  @2   //@2用来指定序号。

4.编译生成dll文件

 

接下来新建一个工程,用来测试刚才的DLL

    首先安装一个鼠标Hook屏蔽所有的鼠标消息。

1.新建一个基于MFC对话框的项目工程HookTest

2.在BOOL CHookTestDlg::OnInitDialog()前声明SetHook函数

_declspec(dllimport) void SetHook();

3.在Setting对话框的Link选项卡的,添加库文件:../Hook/Debug/Hook.lib

4.在OnInitDialog()中调用 SetHook();

5.将生成好的动态链接库拷贝到测试程序项目工程目录下面。

 

调试运行,你会发现你的鼠标坏了,所有的鼠标操作都被屏蔽了。

 

 

    然后安装一个键盘Hook,我们可以按照刚才所做键盘Hook的过程在动态链接库中也做一个Hook,

    这是需要给SetHook带上参数HWND hwnd.

    在测试程序中要把函数也带上参数,并给SetHook传入窗口句柄 SetHook(m_hWnd)。

 

 

    接着,让程序窗口始终在其他窗口之前,而且将它最大化,从而使用户不能切换到窗口。

可以使用SetWindowPos函数

BOOL SetWindowPos(

HWND hWndInsertAfter,

int X,

int Y,

int cx,

int cy,

UINT uFlags

);

A window can be moved to the top of the Z-order either by setting the pWndInsertAfter parameter to &wndTopMost and ensuring that the SWP_NOZORDER flag is not set or by setting a window’s Z-order so that it is above any existing topmost windows. When a nontopmost window is made topmost, its owned windows are also made topmost. Its owners are not changed.

 

得到窗口的大小,可以使用函数GetSystemMetrics

int GetSystemMetrics(int nIndex);

代码:

int cxScreen,cyScreen;

cxScreen=GetSystemMetrics(SM_CXSCREEN);

cyScreen=GetSystemMetrics(SM_CYSCREEN);

SetWindowPos(&wndTopMost,0,0,cxScreen,cyScreen,SWP_SHOWWINDOW);

 

SetHook(m_hWnd);

因为第一个参数设置为&wndTopMost,这时程序始终处于顶层窗口,

不管怎样切换窗口,我们的窗口显示在最前面。

 

 

 

四、如何实现在切换到其他线程时,也能响应F2退出程序

在程序中,我们屏蔽了鼠标和键盘,但是我们留下了一个退出程序的后门(F2)。

前面讲过动态链接库共享性的原理,多个进程可以共享同一份代码与数据页,

按道理切换到其它线程之后,按下F2应该也可以退出程序才对,

但是发现当切换到其他程序后,再按F2 程序不会退出,

这是因为系统的页面拷贝机制,如果系统发现被某线程要修改某个数据页面,

它就会先拷贝一份页面数据,再对新的页面数据进行修改,

其它没有更新数据的线程继续使用旧的页面数据。

比如:SetHook(HWND hwnd)中将形参传递给了一个全局变量g_hWnd

,那么调用SetHook的线程将使用新的存放了hwnd的数据页面,

而其它的线程继续使用旧的数据页面,所以在其它线程成为活动窗口的时候,

按下F2时,因为没有g_hWnd没有传递到hwnd窗口,所以按下F2没有反应。

 

我们可以通过创建一个新的节,将全局变量放到这个节当中,然后将这个节设置为一个共享的节,

这样全局变量就可以在多个线程间共享,从而使切换到其他线程时也能按下F2退出程序。

要显示动态链接库的节,可以使用命令行:  dumpbin  -headers  Hook.dll

 

如何创建一个新的节?

如果确实想在其他程序窗口下关闭我们的程序窗口,可以把共享窗口句柄,使系统不再进行页面拷贝,方法是使用下面语句把窗口句柄设为共享:

 

#pragma data_seg(“MySec”)//MySec是新创建的节的名字(不能超过8个字节)

HWND g_hWnd=NULL;  //新变量必须初始化,否则没有新建节的信息

#pragma  data_seg()   //以上为新建节

 

新创建的节共享以后才有效,共享节有两种方法:

1.#pragma comment(linker,”/section:MySec,RWS”)  //设置节的属性,读,写,共享

2.也可以把#pragma comment(linker,”/section:MySec,RWS”)省略。

在Hook.def中添加如下代码:

SEGMENTS

MySec read write shared

也能对节的属性进行设置

 

把SetWindowsHookEx函数的第一个参数设为WH_GETMESSAGE,能够激活成功教程密码。

使用Hook时要小心。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155150.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • dwcss样式中英对照_dw-cs5-css规则英汉对照表.docx

    dwcss样式中英对照_dw-cs5-css规则英汉对照表.docxdw-cs5-css规则英汉对照表.docx一、类型FONTFAMILY字体FONTSIZE字体大小FONTSTYLE字体风格,如斜体、正常等LINEHEIGHT行高(用来设定字行间距)FONTWEIGHT字体浓淡FONTVARIANT字体变量(用来设定字体是正常显示,还是以小型大写字母显示)TEXTTRANS文本转换(用来设定字体的大小写转换)TEXTDECORATION(字体装饰)UNDER…

    2022年5月17日
  • 7-1 判断回文字符串

    7-1 判断回文字符串7-1判断回文字符串(15分)输入一个字符串,判断该字符串是否为回文。回文就是字符串中心对称,从左向右读和从右向左读的内容是一样的。输入格式:输入在一行中给出一个不超过80个字符长度的、以回车结束的非空字符串。输出格式:输出在第1行中输出字符串。如果它是回文字符串,在第2行中输出Yes,否则输出No。输入样例1:level输出样例1:levelYes输入样例2:1+2=2+1=输出样例2:1+2=2+1=No双指针法#include<s

    2022年5月29日
  • MAC电脑用adb命令安装APK

    MAC电脑用adb命令安装APK目录开始过程结果开始分别在命令行里面输入以下命令:touch.bash_profileopen-e.bash_profilesource.bash_profileadbversion过程这个时候会弹出一个这种框需要你配置路径比如我的路径是这个命令:exportPATH=${PATH}:–…

    2022年6月1日
  • Java课程设计之 学生成绩管理系统「建议收藏」

    Java课程设计之 学生成绩管理系统「建议收藏」实现内容:设计开发一个学生成绩管理系统(1)根据实现的功能,划分出合理的对象类,明确各个对象类之间的关系。为各个对象类设计正确的域和方法,为每个方法设计合理的方法体。同时,为对象类及内部的域和方法运用正确的修饰符。功能要求:(1)录入成绩(2)查询成绩(3)成绩排序(4)修改成绩(5)删除成绩(6)将数据保存在数据库表中该课程设计涉及MySQL数据库,建表操作,java操作SQL语句(JDBC数据库操作)以及JavaS

    2022年7月9日
  • C#中,判断一个字符串是否为数字

    C#中,判断一个字符串是否为数字

    2021年8月10日
  • nextline函数_Java 中nextLine()方法没有执行直接跳过解决办法[通俗易懂]

    nextline函数_Java 中nextLine()方法没有执行直接跳过解决办法[通俗易懂]使用Java的Scanner类nextLne()方法从显示器输入数据时,nextInt()后面的nextLine()直接跳过没有执行;截图:第三个输入直接跳过通过上网的查找我终于发现了问题出在哪里:原来nextLine()函数获取的是一整行的内容其中也包括了(\n)也就是换行符而nextInt()函数获取的仅仅是一个值不包含(\n),那么nextInt()后面的nextLine()读取一行,就把(…

    2022年5月3日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号