Qt实战9.“杀不死”的Qt进程

1 需求描述

  1. 使Qt程序具备防杀效果,资源管理器无法直接结束进程;
  2. 模块化设计,使任意Qt程序可快速集成进程防杀模块,达到防杀效果。

2 设计思路

之前做的一个桌面监控服务软件,可监控USB的插入、非法IP的接入等,既然是监控软件自然是不能通过资源管理器结束进程的。于是上网查阅了各种方法,最后选择了Hook方式实现该功能。
关于Hook的一些理论知识,这里就直接引用网络上的一些描述了,有个概念就行:

2.1 什么是Hook技术?

Hook技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递。简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。

2.2 Hook的工作原理?

在正确使用钩子函数前,我们先讲解钩子函数的工作原理。当您创建一个钩子时,WINDOWS会先在内存中创建一个数据结构,该数据结构包含了钩子的相关信息,然后把该结构体加到已经存在的钩子链表中去。新的钩子将加到老的前面。当一个事件发生时,如果您安装的是一个线程钩子,您进程中的钩子函数将被调用。如果是一个系统钩子,系统就必须把钩子函数插入到其它进程的地址空间,要做到这一点要求钩子函数必须在一个动态链接库中,所以如果您想要使用系统钩子,就必须把该钩子函数放到动态链接库中去。

2.3 如何实现?

原文中提到一个进程正常的结束流程是:

  1. OpenProcess打开进程,获取进程的句柄;
  2. 将获取的进程句柄传递给TerminateProcess,最后由TermianteProcess来完成进程的关闭;
  3. TerminateProcess又会调用系统的NtTerminateProcess,然后逐步深入内核层,最终调用内核API完成进程的关闭和进程相关资源的释放。

在应用层大多数进程的关闭都是走的上述流程,包括任务管理器,所以我们知道在Opernprocess和TerminateProcess间,只要Hook OpenProcess让程序无法打开进程获取到句柄就可以了,那样TerminateProcess调用自然也就失败了,进程也就无法被终结。

3 代码实现

通过上述的一些理论知识,相信对Hook技术会有一个大体的认识,如果对实现过程感兴趣的话,可以参考原文,本文只做一个集成使用的示例。

3.1 Hook模块集成

这里已经把相关接口封装成动态库,并形成为pri模块,在pro文件中直接include即可。

include($$PWD/hook/hook.pri)

hook/lib目录中已包含32位和64位库文件,默认使用的是64位库文件,根据需要替换即可。
到此,Hook模块已经集成到Qt程序中了。

3.2 简单应用

使用就非常简单了,代码如下:

#include "MainWindow.h"
#include <QApplication>
#include "hook.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    DWORD processId = GetCurrentProcessId();
    InstallHook(processId);

    MainWindow w;
    w.show();

    int ret = a.exec();

    UninstallHook();

    return ret;
}

到此,Qt程序已经具备进程防杀效果了,是不是简单的一塌糊涂。

4 总结

虽然任务管理器无法直接结束安装Hook后的进程,但是仍可通过一些三方的任务管理工具关闭进程,里面涉及的知识会复杂一些,这里就不做展开了,可自行查阅相关资料。事实上,不仅仅是Qt应用程序,windows下的其它应用程序也可通过该方式实现进程防杀效果,头开好了,怎么玩得靠自己了。(#.#)

5 下载

示例程序

原文地址:https://www.cnblogs.com/luoxiang/p/14029831.html