摘要:本文對進程及線程運行原理上的分析,通過模擬病毒的隱藏性和寄生性,運用進程通信、進程快照、多線程等技術基礎,從實例分析角度來模擬病毒特征,介紹了如何利用多進程實現程序的自我防護,最終實現程序運行的可靠性和安全性。
關鍵詞: 病毒;進程與線程;自我防護;程序
中圖分類號:G4
引言
一、計算機進程與線程
進程是程序在計算機上的一次執行活動 ,在Windows下,進程又被細化為線程,也就是一個進程下有多個能獨立運行的更小的單位。在同一個時間里,同一個計算機系統中如果允許兩個或兩個以上的進程處于運行狀態,這便是多任務。現代的操作系統幾乎都是多任務操作系統,能夠同時管理多個進程的運行。我們通常使用的計算機中只有一個CPU,也就是說只有一顆心,要讓它一心多用,同時運行多個進程,就必須使用并發技術。實現并發技術相當復雜,最容易理解的是“時間片輪轉進程調度算法”,它的思想簡單介紹如下:在操作系統的管理下,所有正在運行的進程輪流使用CPU,每個進程允許占用CPU的時間非常短(比如10毫秒),這樣用戶根本感覺不出來CPU是在輪流為多個進程服務,就好象所有的進程都在不間斷地運行一樣。
在Windows中,進行CPU分配是以線程為單位的,一個進程可能由多個線程組成,這時情況更加復雜,但簡單地說,有如下關系:
總線程數<= CPU數量:并行運行
總線程數> CPU數量:并發運行
并行運行的效率顯然高于并發運行,所以在多CPU的計算機中,多任務的效率比較高。但是,如果在多CPU計算機中只運行一個進程(線程),就不能發揮多CPU的優勢。
這里涉及到多任務操作系統的問題,多任務操作系統(如Windows)的基本原理是:操作系統將CPU的時間片分配給多個線程,每個線程在操作系統指定的時間片內完成。操作系統不斷的從一個線程的執行切換到另一個線程的執行,如此往復,宏觀上看來,就好像是多個線程在一起執行。由于這多個線程分屬于不同的進程,因此在我們看來。就好像是多個進程在同時執行,這樣就實現了多任務。
二、程序的設計與實現
1、監督過程的實現
監督是指利用進程枚舉的方法,讓所有程序在運行同時不停地對進程列表進行快照,并檢查目標進程是否存在的過程。 在Windows環境下通過調用ToolHelp API函數來達到枚舉系統進程的目的。ToolHelp32庫函數在KERNEL32.dll中,它們都是標準的API函數。
ToolHelp32庫中有各種各樣的函數可以用來枚舉系統中的進程、線程,以及獲取內存和模塊信息。其中枚舉進程只需用如下三個的函數:CreateToolhelp32Snapshot()、Process32First()和Process32Next()。 使用ToolHelp32函數的第一步是用CreateToolhelp32Snapshot()函數創建系統信息“快照”。這個函數可讓你選擇存儲在快照中的信息類型。如果你只是對進程信息感興趣,那么只要包含TH32CS_SNAPPROCESS標志即可。CreateToolhelp32Snapshot()函數返回一個HANDLE,完成調用之后,必須將此HANDLE傳給CloseHandle()。接下來是調用一次Process32First函數,從快照中獲取進程列表,然后重復調用Process32Next,直到函數返回FALSE為止。這樣將遍歷快照中進程列表。這兩個函數都帶兩個參數,它們分別是快照句柄和一個PROCESSENTRY32結構。
2、報警進程的實現
一個程序中復制數據的時候,實際上是將這些數據放入了內存,相反,在另一個程序中粘貼數據時實際上是從內存取出數據,這些都是通過使用剪貼板來實現的。使用剪貼板的主要函數有:打開剪貼板OpenClipboard(),不管是對剪貼板的讀還是寫,都要首先調用此函數,以判斷是否可以對剪貼板進行操作。此函數是BOOL型的,如果調用成功就返回非零,否則返回零。清空剪貼板EmptyClipborad(),每次對剪貼板的寫入操作之前,都應該調用此函數,這個函數的作用不僅是清空剪貼板,而且起到獲得剪貼板的使用權的作用。同樣,這個函數也是BOOL型的,如果調用成功就返回非零,否則返回零。對剪貼板寫入SetClipboardData(UINT uFormat,HANDLE hMem),這個函數有兩個參數,第一個參數用來表示寫入剪貼板數據的格式,第二個參數接收一個句柄值,在這里它接收一個指向內存對象的句柄,這個內存對象中存放著準備寫入剪貼板的數據內容。在調用SetClipboardData(UINT uFormat,HANDLE hMem)之前還需要調用GlobalAlloc(UINT uFlags,SIZE_T dwSytes)這樣一個函數,它專門用來為將要寫入的數據分配一塊內存空間。這個函數接收兩個參數,第一個參數表示如何來分配內存空間,這里我們將它設置為GMEM_MOVEABLE,表示動態分配內存。第二個參數是表示分配內存空間的大小。GlobalAlloc(UINT uFlags,SIZE_T dwSytes)返回一個句柄,我們無法使用句柄來間接的將數據放入內存,這時就需要調用另一個函數GlobalLock(HGLOBAL hMem),這個函數獲得一個內存對象的句柄,將這塊內存加鎖,返回一個指針,這時我們就可以給指針所指向的這塊內存寫入數據了。這個函數使用一個內存計數,計數器基數為零,每調用一次計數器加一,所以每調用一次的同時還需要調用另外一個函數GlobalUnlock(HGLOBAL hMem)來給計數器減一,相當于取消對這塊內存的鎖定。程序實現報警功能就是在枚舉進程之后發現目標進程被終止,從而在剪貼板中寫入信息的過程。
3、監聽進程的實現
所謂監聽,就是報警的反方向,即從剪貼板中讀出信息。從剪貼板讀取數據的函數GetClipboardData(UINT uFormat)。這個函數只接收一個參數,參數指定讀取的格式。讀取信息之后,我們還要對信息進行if判斷,如果信息是我們預留的某個進程被結束的話,我們就啟動保護措施。
4、防護和隱藏進程的實現
這里的保護是指監聽程序對其他程序的保護,方法非常簡單,只需要利用WinExec函數來實現目標進程的啟動就可以。而隱藏是指監聽程序自身的隱藏,只要在OnPaint()函數里調用ShowWindow(SW_HIDE)函數就可以了,同時將監聽程序命名為smss,就可以避免其被強行終止。
三、結束語
由于網絡及信息資源的特殊性質,決定了信息安全問題的客觀存在。本程序的設計是模仿病毒的一些特性實現。它體現了程序的隱藏、保證了程序的安全運行,利用系統的漏洞實現不被其他進程終止。對一般程序自我保護的設計有很好的借鑒參考意義。