通过安装Hook过程,可以用来屏蔽消息队列中某些消息
The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. You would install a hook procedure to monitor the system for certain types of events. These events are associated either with a specific thread or with all threads in the same desktop as the calling thread.
Syntax
HHOOK SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId   //为零表示和所有安装的线程相关
);
一、下面我们来创建一个屏蔽鼠标过程的hook:
1.创建基于MFC的一个InnerHook工程项目
2.在BOOL CInnerHookerDlg::OnInitDialog()中添加hook
SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());
要获得当前线程句柄,使用函数DWORD GetCurrentThreadId(void);
3.实现鼠标过程MouseProc为:
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为(只屏蔽空格键):
4.下边添加代码使程序在F2键按下后退出。
要关闭窗口,首先要获得窗口的句柄,先声明一个全局变量Hwnd g_hWnd,
在OnInitDialog()中把窗口句柄传给它:
g_hWnd=m_hWnd;
接下来为键盘钩子过程添加代码:
这时我们只能屏蔽主线程的键盘消息,如果要屏蔽所有消息,就得把代码放到动态链接库中实现。
三、屏蔽所有线程的消息
首先要创建一个动态链接库
1.新建一个Win32 Dynamic-Link Library项目工程Hook
得到动态链接库模块的句柄有两种方式:
方法1。DllMain函数方式:
HMODULE和HINSTANCE可以通用
方法2。GetModuleHandle函数方式
SetWindowsHookEx(WH_MOUSE,MouseProc,GetModuleHandle("Hook"),0);
这样我们所安装的钩子过程就和运行在同一个桌面上的所有进程相关了
2.编写MouseProc()
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时要小心。

孙鑫VC学习笔记:第二十讲 (一) Hook编程相关推荐

  1. 孙鑫VC++学习笔记(转载至程序员之家--虎非龙)[11--15] .

    第11课 1.创建4个菜单,为其添加消息响应,用成员变量保存绘画类型.添加LButtonDown和Up消息. 2.当窗口重绘时,如果想再显示原先画的数据,则需要保存数据.为此创建一个新类来记录绘画类型 ...

  2. 孙鑫VC++学习笔记(转载至程序员之家--虎非龙)[11--15]

    第11课 1.创建4个菜单,为其添加消息响应,用成员变量保存绘画类型.添加LButtonDown和Up消息. 2.当窗口重绘时,如果想再显示原先画的数据,则需要保存数据.为此创建一个新类来记录绘画类型 ...

  3. 孙鑫VC学习笔记:第七讲

    七.对话框 2006年8月5日 14:25 因为笔记是用OneNote做的,上传以后为看不到图片,于是我截图放到相册上面, 相册地址为:http://photo.163.com/photos/good ...

  4. 孙鑫mfc学习笔记第十四课

    第十四课 网络的相关知识,网络程序的编写,Socket是连接应用程序与网络驱动程序的桥梁,Socket在应用程序中创建,通过bind与驱动程序建立关系.此后,应用程序送给Socket的数据,由Sock ...

  5. 线性代数学习笔记——第二十讲——矩阵秩的定义

    1. 矩阵的k阶子式 2. 若矩阵的某个低阶子式全为零,则其更高阶的子式也全为零(用反证法证明) 3. 矩阵的秩的定义(满秩矩阵.非奇异矩阵.矩阵可逆.矩阵的行列式不等于零这几个概念是等价的) 4. ...

  6. Python学习笔记第二十九天(N维数组(ndarray))

    Python学习笔记第二十九天 N维数组(ndarray) 构建阵列 索引阵列 ndarray的内部内存布局 阵列属性 内存布局 数据类型 其他属性 阵列接口 ctypes外部功能接口 Array方法 ...

  7. ev3编程变量模块_英文视频教学翻译-机器人ev3编程学习的第二十讲:举例讲解数据变量模块编...

    机器人ev3编程学习的第二十讲:举例讲解数据变量模块编- Rob Widger (为了容易理解,在原文的翻译时做了修改 by EV3-TOM) 这一节我给大家讲解使用变量模块的编程,这些我喜欢的例子也 ...

  8. 2022Java学习笔记八十八(网络编程:UDP通信,一发一收,多发多收消息接收实现)

    2022Java学习笔记七十八(网络编程:UDP通信,一发一收,多发多收消息接收实现) 一.快速入门 DatagramPacket:数据包对象 实例代码 定义发送端 package com.zcl.d ...

  9. [go学习笔记.第十六章.TCP编程] 3.项目-海量用户即时通讯系统-redis介入,用户登录,注册

    1.实现功能-完成用户登录 在redis手动添加测试用户,并画出示意图以及说明注意事项(后续通过程序注册用户) 如:输入用户名和密码,如果在redis中存在并正确,则登录,否则退出系统,并给出相应提示 ...

  10. 孙鑫VC学习系列教程

    教程简介 1.循序渐进 从Win32SDK编程开始讲解,帮助大家理解掌握Windows编程的核心 -- 消息循环机制. 2.通俗易懂 编程语言枯燥难懂,然而通过孙鑫老师形象化的讲解,Windows和M ...

最新文章

  1. mysql keepalived_mysql高可用+keepalived
  2. (c#)数据结构与算法分析 --递归
  3. 十八般武艺教你如何解决问题
  4. MariaDB安装、卸载以及相关设置(Linux服务器Mysql部署)
  5. cocoapods 详尽使用
  6. input 密码框调出手机的数字键盘
  7. smbinning包:R语言下的分箱处理工具
  8. bash脚本编程之十 函数
  9. SDUT 2138 图结构练习——BFSDFS——判断可达性
  10. php json schema,json-schema-php
  11. 云星数据VP楼炜:CMP是混合云、多云管理的必然选择
  12. 如何安装uclient_UClient软件下载-UClient客户端下载 v2.0.0.1580官方版--pc6下载站
  13. 父与子的编程python_父与子的编程之旅:与小卡特一起学Python 完整版
  14. Linux如何运行exe驱动,在Linux下可用Wine安装和运行360驱动大师、CCleaner
  15. 51nod-1429 巧克力
  16. 几何公差(GDT)的特征项目及符号
  17. 华为nova7星耀版和华为nova7普通版 的区别 哪个好
  18. Python Windows发出警报声、蜂鸣器、声音报警
  19. QQ是怎么处理消息的
  20. Android.bp 添加宏开关

热门文章

  1. nagios 监控slave(check_mysql_health插件)
  2. 最长不下降子序列//序列dp
  3. jdk HashMap源码解读
  4. java内存堆栈的区别
  5. Android NFC技术解析,附Demo源码
  6. 静态NAT、动态NAT、PAT(端口多路复用)的配置
  7. keras小程序(一),用cnn做分类
  8. 在Ubuntu上使用apt-get安装MySQL+安全优化
  9. 禁用生成8.3字符长文件名解决单目录存储大量文件写入性能下降问题
  10. CISCO路由器NAT-T与IPSec ×××配置实验【实践闯未来】