通过安装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为:

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时要小心。

孙鑫MFC笔记之十七--HOOK编程相关推荐

  1. 孙鑫MFC笔记之十三--多线程编程

    程序,进程,线程的区别 程序 是计算机指令的集合,它以文件的形式存储在磁盘上. 进程 通常被定义一个正在执行的程序实例,是一个程序在其自身的地址空间中的一次执行活动. 我们通常的exe程序是以文件的形 ...

  2. 孙鑫MFC笔记(15)--多线程和聊天室的创建

    孙鑫MFC笔记(15)--多线程和聊天室的创建 代码1分析: 说明:对于单核cpu的电脑来说,线程都在自己的时间片中运行,单位时间内,系统只能运行一个线程,交替运行:对于多核cpu或多cpu的电脑来说 ...

  3. 孙鑫MFC笔记之八--文档串行化

    1.CArchive在菜单打开保存时的代码 CFile file("1.txt",CFile::modeCreate | CFile::modeWrite); CArchive a ...

  4. 孙鑫MFC笔记之十四--多线程同步与异步套接字编程

    线程同步有三种方式: 1.      互斥对象涉及方法: HANDLE hMutex=CreateMutex(NULL,FALSE,NULL); //第二个参数为FALSE,将互斥对象声明为空闲状态 ...

  5. 孙鑫MFC笔记之十二--网络编程

    网络状况: ü多种通信媒介--有线.无线-- ü不同种类的设备--通用.专用-- ü不同的操作系统--Unix.Windows -- ü不同的应用环境--固定.移动-- ü不同业务种类--分时.交互. ...

  6. 孙鑫-MFC笔记九--菜单编程

    弹出菜单(Pop-up)是不能用来作命令响应的.即下拉等形式. 响应菜单响应命令的顺序是:视类,文档类,框架类,应用程序类. Windows消息分三类: 标准消息,WM_ (除WM_COMMAND)都 ...

  7. 孙鑫-MFC笔记四--文本编程

    1,创建插入符: void CreateSolidCaret( int nWidth, int nHeight );//创建插入符 void CreateCaret( CBitmap* pBitmap ...

  8. 孙鑫MFC笔记之十六--Active控件

    基本概念: 容器和服务器程序 容器应用程序时可以嵌入或链接对象的应用程序.Word 就是容器应用程序.服务器应用程序是创建对象并且当对象被双击时,可以被启动的应用程序.Excel 就是服务器应用程序. ...

  9. 孙鑫-MFC笔记十--修改应用程序外观

    修改应用程序的外观 窗口创建之前修改: 要改变一个框架窗口的外观和大小,我们应该在CMainFrame这个类当中的PreCreateWindow函数当中完成. PreCreateWindow这个函数有 ...

最新文章

  1. usaco Preface Numbering 序言页码
  2. 惊呆了!这样可以将Numpy加速700倍!
  3. JZOJ 5484. 【清华集训2017模拟11.26】快乐树
  4. 2.2.1 Sqoop1的基本架构
  5. VSCode 更新后打不开之解决办法
  6. ASP——判断数据库NULL值
  7. java springmvc mybatis mysql
  8. mysql往前一天同一时间_Mysql时间轴数据 获取同一天数据的前三条
  9. 栈——后缀表达式(洛谷 P1449)
  10. Python中内置函数的介绍
  11. pycharm安装javascript插件_IDEA必备插件系列-Rainbow
  12. iOS开发之基础面试题
  13. 关于在windows中配置flew,glfw
  14. php array函数 preg_match() 正则匹配
  15. CAD打开文件总是弹出要求选择字体怎么办
  16. linux bridge 添加fdb,Linux协议栈--网桥设备的实现
  17. 搜狗批量推送软件-搜狗批量推送工具【2022最新】
  18. 声学测试软件ios,只需要 iPhone 就能进行声学测量,AcoustiTools 用 AR 帮你解决大声场环境的听感问题...
  19. 菜鸡帆并不算长の编程之旅回顾
  20. python里面else什么意思_python中if else和if elif else有什么区别?

热门文章

  1. Linux基于v4l2的视频采集(可用)
  2. UE4之UMG用户界面
  3. windows清除记住的密码
  4. C#之double内存
  5. python识别_识别串口/ usb设备python
  6. python unicode函数_python 中的unicode详解
  7. vue怎么实现手风琴效果_Vue中使用v-for制作动态手风琴效果
  8. java判断是否失效_java – 如何在输入有效之前检查无效输入和循环?
  9. 19年北理考研计算机复试分数多少钱,2019年北京理工大学考研复试分数线已出现...
  10. typora 语法教程