1. 程式人生 > 實用技巧 >Qt實戰9.“殺不死”的Qt程序

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 下載

示例程式