1 需求描述
- 使Qt程序具備防殺效果,資源管理器無法直接結束進程;
- 模塊化設計,使任意Qt程序可快速集成進程防殺模塊,達到防殺效果。
2 設計思路
之前做的一個桌面監控服務軟件,可監控USB的插入、非法IP的接入等,既然是監控軟件自然是不能通過資源管理器結束進程的。於是上網查閱了各種方法,最后選擇了Hook方式實現該功能。
關於Hook的一些理論知識,這里就直接引用網絡上的一些描述了,有個概念就行:
2.1 什么是Hook技術?
Hook技術又叫做鈎子函數,在系統沒有調用該函數之前,鈎子程序就先捕獲該消息,鈎子函數先得到控制權,這時鈎子函數既可以加工處理(改變)該函數的執行行為,還可以強制結束消息的傳遞。簡單來說,就是把系統的程序拉出來變成我們自己執行代碼片段。
2.2 Hook的工作原理?
在正確使用鈎子函數前,我們先講解鈎子函數的工作原理。當您創建一個鈎子時,WINDOWS會先在內存中創建一個數據結構,該數據結構包含了鈎子的相關信息,然后把該結構體加到已經存在的鈎子鏈表中去。新的鈎子將加到老的前面。當一個事件發生時,如果您安裝的是一個線程鈎子,您進程中的鈎子函數將被調用。如果是一個系統鈎子,系統就必須把鈎子函數插入到其它進程的地址空間,要做到這一點要求鈎子函數必須在一個動態鏈接庫中,所以如果您想要使用系統鈎子,就必須把該鈎子函數放到動態鏈接庫中去。
2.3 如何實現?
原文中提到一個進程正常的結束流程是:
- OpenProcess打開進程,獲取進程的句柄;
- 將獲取的進程句柄傳遞給TerminateProcess,最后由TermianteProcess來完成進程的關閉;
- 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下的其它應用程序也可通過該方式實現進程防殺效果,頭開好了,怎么玩得靠自己了。(∩_∩)