- 相關(guān)推薦
利用進(jìn)程間通信實(shí)現程序自我保護分析
利用進(jìn)程間通信實(shí)現程序自我保護,重點(diǎn)研究進(jìn)程間通信技術(shù),最終實(shí)現程序運行的穩定。
1.引言
在計算機和網(wǎng)絡(luò )技術(shù)日益發(fā)展的今天,病毒這個(gè)字眼越來(lái)越多地出現在了媒體和人們的言論中。計算機病毒的發(fā)展必然會(huì )促進(jìn)計算機反病毒技術(shù)的發(fā)展,新型病毒的出現向以行為規則判定病毒的預防產(chǎn)品、以病毒特征為基礎的檢測產(chǎn)品,以及根據計算機病毒傳染宿主程序的方法而消除病毒的產(chǎn)品提出了挑戰,致使原有的反病毒技術(shù)和產(chǎn)品在新型的計算機病毒面前無(wú)能為力。這樣,勢必使人們認識到現有反病毒產(chǎn)品在對抗新型的計算機病毒方面的局限性,迫使人們在反病毒的技術(shù)和產(chǎn)品上進(jìn)行新的更新和換代。要打敗對手,就要從了解對手開(kāi)始,本文從模擬病毒隱藏性和寄生性的角度出發(fā),以進(jìn)程通信、進(jìn)程快照、多線(xiàn)程等技術(shù)基礎,利用Visual C++的MFC窗口界面設計了一組程序自我保護軟件,經(jīng)過(guò)測試實(shí)現了程序的穩定運行。
2.進(jìn)程的概念
當一個(gè)程序開(kāi)始運行時(shí),它就是一個(gè)進(jìn)程,進(jìn)程所指包括運行中的程序和程序所使用到的內存和系統資源。因此定義進(jìn)程(Process)是具有一定獨立功能的程序關(guān)于某個(gè)數據集合上的一次運行活動(dòng),是系統進(jìn)行資源分配和調度的一個(gè)獨立單位。程序只是一組指令的有序集合,它本身沒(méi)有任何運行的含義,只是一個(gè)靜態(tài)實(shí)體。而進(jìn)程則不同,它是程序在某個(gè)數據集上的執行,是一個(gè)動(dòng)態(tài)實(shí)體。它因創(chuàng )建而產(chǎn)生,因調度而運行,因等待資源或事件而被處于等待狀態(tài),因完成任務(wù)而被撤銷(xiāo),反映了一個(gè)程序在一定的數據集上運行的全部動(dòng)態(tài)過(guò)程。
進(jìn)程由兩個(gè)部分組成:
(1)操作系統用來(lái)管理進(jìn)程的內核對象。內核對象也是系統用來(lái)存放關(guān)于進(jìn)程的統計信息的地方。
(2)地址空間。它包含所有可執行模塊或DLL模塊的代碼和數據。它還包含動(dòng)態(tài)內存分配的空間,如線(xiàn)程堆棧和堆分配空間。
目前常用的操作系統都是并行的,就是多個(gè)進(jìn)程可以同步運行,這時(shí)就會(huì )牽扯到進(jìn)程間通信這個(gè)概念。所謂進(jìn)程通信,就是不同進(jìn)程之間進(jìn)行一些“接觸”,這種接觸有簡(jiǎn)單,也有復雜。機制不同,復雜度也不一樣。通信是一個(gè)廣義上的意義,不僅僅指傳遞一些信息。舉個(gè)例子來(lái)說(shuō)明:比如說(shuō)在使用IE上網(wǎng)時(shí),你想將網(wǎng)頁(yè)上的一段文字保存至你的電腦上,這時(shí)有一種簡(jiǎn)單的方法,就是復制粘貼。將你想保存的文字選中,然后將其復制,接下來(lái)將所復制的文字粘貼到.TXT文檔中,這時(shí)就形成了兩個(gè)進(jìn)程之間的通信,這里的通信媒介是剪貼板。
3.線(xiàn)程的概念
為了對線(xiàn)程模式有一定的理解,我們可以將其想象為把一所屋子里的東西搬到另一所屋子。如果采用單線(xiàn)程方法,則需要自己完成從打包到扛箱子再到拆包的所有工作。如果使用單元線(xiàn)程模式,則表示邀請了好朋友來(lái)幫忙。每個(gè)朋友在一個(gè)單獨的房間里工作,并且不能幫助在其他房間工作的人。他們各自負責自己的空間和空間內的物品搬運。如果采用自由線(xiàn)程方法,仍然邀請相同的朋友來(lái)幫忙,但是所有朋友可以隨時(shí)在任何一個(gè)房間工作,共同打包物品。與此類(lèi)似,房子就是運行所有線(xiàn)程的進(jìn)程,每個(gè)朋友都是一個(gè)代碼實(shí)例,搬運的物品為應用程序的資源和變量。
有了上面的例子,便能容易理解線(xiàn)程(Thread)是一個(gè)能獨立于程序的其他部分運行的作業(yè),是進(jìn)程的一個(gè)實(shí)體,是CPU調度和分派的基本單位。線(xiàn)程不能夠獨立執行,必須依存在應用程序中,由應用程序提供多個(gè)線(xiàn)程執行控制。線(xiàn)程是程序中的一個(gè)執行流,每個(gè)線(xiàn)程都有自己的專(zhuān)有寄存器(棧指針、程序計數器等),但代碼區是共享的,即不同的線(xiàn)程可以執行同樣的函數。一個(gè)線(xiàn)程可以執行應用程序代碼的任一部分,包括正在由另一線(xiàn)程執行的代碼。
線(xiàn)程由兩個(gè)部分組成:
(1)線(xiàn)程的內核對象,操作系統用它來(lái)對線(xiàn)程實(shí)施管理。內核對象也是系統用來(lái)存放線(xiàn)程統計信息的地方。
(2)線(xiàn)程堆棧,它用于維護線(xiàn)程在執行代碼時(shí)需要的所有參數和局部變量。
線(xiàn)程屬于一個(gè)過(guò)程,操作系統為每一個(gè)運行線(xiàn)程安排一定的CPU時(shí)間——時(shí)間片,線(xiàn)程是操作系統分配CPU時(shí)間的基本單位。系統通過(guò)一種循環(huán)的方式為線(xiàn)程提供時(shí)間片,線(xiàn)程在自己的時(shí)間內運行,因時(shí)間片相當短,因此,給用戶(hù)的感覺(jué),就好像線(xiàn)程是同時(shí)運行的一樣。如果計算機擁有多個(gè)CPU,線(xiàn)程就能真正意義上同時(shí)運行了。
4.進(jìn)程與線(xiàn)程的關(guān)系
根據操作系統的定義,進(jìn)程是系統資源管理的最小單位,線(xiàn)程是程序執行的最小單位。進(jìn)程是不活潑的,進(jìn)程可以理解為是線(xiàn)程的容器。若要使進(jìn)程完成某項操作,它必須擁有一個(gè)在它的環(huán)境中運行的線(xiàn)程,此線(xiàn)程負責執行包含在進(jìn)程的地址空間中的代碼。單個(gè)進(jìn)程可能包含若干個(gè)線(xiàn)程,這些線(xiàn)程都“同時(shí)”執行進(jìn)程地址空間中的代碼。每個(gè)進(jìn)程至少擁有一個(gè)線(xiàn)程,來(lái)執行進(jìn)程的地址空間中的代碼。當創(chuàng )建一個(gè)進(jìn)程時(shí),操作系統會(huì )自動(dòng)創(chuàng )建這個(gè)進(jìn)程的第一個(gè)線(xiàn)程,稱(chēng)為主線(xiàn)程。此后,該線(xiàn)程可以創(chuàng )建其他的線(xiàn)程。
線(xiàn)程是屬于進(jìn)程的,它沒(méi)有自己的獨立的數據地址空間,線(xiàn)程運行在進(jìn)程空間內,因此線(xiàn)程的切換速度比較快。同一進(jìn)程所產(chǎn)生的線(xiàn)程共享同一內存空間,而這些線(xiàn)程的執行由系統調度程序控制,調度程序決定哪個(gè)線(xiàn)程可執行以及什么時(shí)候執行線(xiàn)程。線(xiàn)程有優(yōu)先級別,優(yōu)先權較低的線(xiàn)程必須等到優(yōu)先權較高的線(xiàn)程執行完后再執行。當進(jìn)程退出時(shí)該進(jìn)程所產(chǎn)生的線(xiàn)程都會(huì )被強制退出并清除。線(xiàn)程可與屬于同一進(jìn)程的其他線(xiàn)程共享虛地址空間、全局變量,以及該進(jìn)程所擁有的全部資源,包括打開(kāi)的文件、信號標志及動(dòng)態(tài)分配的內存等。但是其本身基本上不擁有系統資源,只擁有一點(diǎn)在運行中必不可少的信息(如程序計數器、一組寄存器和棧)。
線(xiàn)程有點(diǎn)像進(jìn)程身體內的細胞,我們通常聽(tīng)過(guò)多進(jìn)程多線(xiàn)程,單進(jìn)程多線(xiàn)程。這就是說(shuō),一個(gè)系統內有幾個(gè)進(jìn)程,如果進(jìn)程是多個(gè),就是多進(jìn)程的,如果進(jìn)程內有多個(gè)線(xiàn)程,那就是多線(xiàn)程的,多進(jìn)程多線(xiàn)程的系統比單進(jìn)程多線(xiàn)程的系統速度慢,但是可靠性高。
5.程序的設計與實(shí)現
程序的自我保護是一個(gè)大的概念,其中有多種方式和手段來(lái)實(shí)現自身的保護。比如隱藏、自我復制、注冊為服務(wù),等等。我們實(shí)現的程序自我保護實(shí)際上是一個(gè)相互監督的過(guò)程。其中包括了程序之間的監督和報警,監聽(tīng)程序的隱藏與保護。
5.1監督
所謂監督,是利用進(jìn)程枚舉的方法,讓所有程序在運行同時(shí)不停地對進(jìn)程列表進(jìn)行快照,并檢查目標進(jìn)程是否存在的過(guò)程。
在Windows環(huán)境下可以通過(guò)調用ToolHelp API函數來(lái)達到枚舉系統進(jìn)程的目的。微軟的Windows NT開(kāi)發(fā)小組因為不喜歡ToolHelp函數,所以沒(méi)有將這些函數添加給Windows NT,所以開(kāi)發(fā)了自己的Process Status函數,就是PSAPI。但是后來(lái)微軟已經(jīng)將ToolHelp函數添加給了Windows 2000。ToolHelp32庫函數在KERNEL32.dll中,它們都是標準的API函數。
ToolHelp32庫中有各種各樣的函數可以用來(lái)枚舉系統中的進(jìn)程、線(xiàn)程,以及獲取內存和模塊信息。其中枚舉進(jìn)程只需用如下三個(gè)的函數:CreateToolhelp32Snapshot()、Process32First()和Process32Next()。
使用ToolHelp32函數的第一步是用CreateToolhelp32Snapshot()函數創(chuàng )建系統信息“快照”。這個(gè)函數可讓你選擇存儲在快照中的信息類(lèi)型。如果你只是對進(jìn)程信息感興趣,那么只要包含TH32CS_SNAPPROCESS標志即可。CreateToolhelp32Snapshot()函數返回一個(gè)HANDLE,完成調用之后,必須將此HANDLE傳給CloseHandle()。
接下來(lái)是調用一次Process32First函數,從快照中獲取進(jìn)程列表,然后重復調用Process32Next,直到函數返回FALSE為止。這樣將遍歷快照中進(jìn)程列表。這兩個(gè)函數都帶兩個(gè)參數,它們分別是快照句柄和一個(gè)PROCESSENTRY32結構。
調用完P(guān)rocess32First或Process32Next之后,PROCESSENTRY32中將包含系統中某個(gè)進(jìn)程的關(guān)鍵信息。它的具體內容如下:
typedef struct tagPROCESSENTRY32{
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
DWORD th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID; LONG pcPriClassBase;
DWORD dwFlags;
TCHAR szExeFile;
DWORD th32MemoryBase;
DWORD th32AccessKey;
}PROCESSENTRY32;
其中進(jìn)程ID就存儲在此結構的th32ProcessID。此ID可以被傳給OpenProcess()API以獲得該進(jìn)程的句柄。對應的可執行文件名及其存放路徑存放在szExeFile結構成員中。在該結構中還可以找到其他一些有用的信息。
5.2報警
這里的報警就涉及了進(jìn)程間通信的概念。本文中涉及的進(jìn)程間通信是用剪貼板的方法,剪貼板在我們實(shí)際應用中是用得比較多的,它實(shí)際上是系統維護管理的一個(gè)內存區域,當我們在一個(gè)程序中復制數據的時(shí)候,實(shí)際上是將這些數據放入了內存,相反,當我們在另一個(gè)程序中粘貼數據時(shí)實(shí)際上是從內存取出數據。下面介紹一下使用剪貼板時(shí)的主要函數:打開(kāi)剪貼板OpenClipboard(),不管是對剪貼板的讀還是寫(xiě),都要首先調用此函數,以判斷是否可以對剪貼板進(jìn)行操作。此函數是BOOL型的,如果調用成功就返回非零,否則返回零。清空剪貼板EmptyClipborad(),每次對剪貼板的寫(xiě)入操作之前,都應該調用此函數,這個(gè)函數的作用不僅是清空剪貼板,而且起到獲得剪貼板的使用權的作用。同樣,這個(gè)函數也是BOOL型的,如果調用成功就返回非零,否則返回零。對剪貼板寫(xiě)入SetClipboardData(UINT uFormat,HANDLE hMem),這個(gè)函數有兩個(gè)參數,第一個(gè)參數用來(lái)表示寫(xiě)入剪貼板數據的格式,第二個(gè)參數接收一個(gè)句柄值,在這里它接收一個(gè)指向內存對象的句柄,這個(gè)內存對象中存放著(zhù)準備寫(xiě)入剪貼板的數據內容。在調用SetClipboardData(UINT uFormat,HANDLE hMem)之前還需要調用GlobalAlloc(UINT uFlags,SIZE_T dwSytes)這樣一個(gè)函數,它專(zhuān)門(mén)用來(lái)為將要寫(xiě)入的數據分配一塊內存空間。這個(gè)函數接收兩個(gè)參數,第一個(gè)參數表示如何來(lái)分配內存空間,這里我們將它設置為GMEM_MOVEABLE,表示動(dòng)態(tài)分配內存。第二個(gè)參數是表示分配內存空間的大小。GlobalAlloc(UINT uFlags,SIZE_T dwSytes)返回一個(gè)句柄,我們無(wú)法使用句柄來(lái)間接的將數據放入內存,這時(shí)就需要調用另一個(gè)函數GlobalLock(HGLOBAL hMem),這個(gè)函數獲得一個(gè)內存對象的句柄,將這塊內存加鎖,返回一個(gè)指針,這時(shí)我們就可以給指針所指向的這塊內存寫(xiě)入數據了。這個(gè)函數使用一個(gè)內存計數,計數器基數為零,每調用一次計數器加一,所以每調用一次的同時(shí)還需要調用另外一個(gè)函數GlobalUnlock(HGLOBAL hMem)來(lái)給計數器減一,相當于取消對這塊內存的鎖定。本文設計的程序實(shí)現報警功能就是在枚舉進(jìn)程之后發(fā)現目標進(jìn)程被終止,從而在剪貼板中寫(xiě)入信息的過(guò)程。
5.3監聽(tīng)
所謂監聽(tīng),就是報警的反方向,即從剪貼板中讀出信息。從剪貼板讀取數據的函數GetClipboardData(UINT uFormat)。這個(gè)函數只接收一個(gè)參數,參數指定讀取的格式。讀取信息之后,我們還要對信息進(jìn)行if判斷,如果信息是我們預留的某個(gè)進(jìn)程被結束的話(huà),我們就啟動(dòng)保護措施。
5.4保護和隱藏
這里的保護是指監聽(tīng)程序對其他程序的保護,方法非常簡(jiǎn)單,利用進(jìn)程間通信實(shí)現程序自我保護只需要利用WinExec函數來(lái)實(shí)現目標進(jìn)程的啟動(dòng)就可以。而隱藏是指監聽(tīng)程序自身的隱藏,只要在OnPaint()函數里調用ShowWindow(SW_HIDE)函數就可以了,同時(shí)將監聽(tīng)程序命名為smss,就可以避免其被強行終止。
6.結語(yǔ)
本文中程序的設計是模仿病毒的一些特性而做成的。它實(shí)現了程序的隱藏,并且利用了系統的漏洞實(shí)現了不被終止。對我們了解病毒的特征提供了良好平臺,同時(shí)對一般程序自我保護的設計有很好的現實(shí)意義。
【利用進(jìn)程間通信實(shí)現程序自我保護分析】相關(guān)文章:
利用ASSP實(shí)現成本節約,加速產(chǎn)品上市進(jìn)程03-18
利用Excel執行審計分析程序03-22
利用Flash實(shí)現DSP對多個(gè)程序有選擇的加載03-19
利用VC中的通訊控件開(kāi)發(fā)串形通信程序03-18
利用EPP接口協(xié)議實(shí)現高速數據通信03-19
數字信號處理器間異步串口通信的研究與實(shí)現03-07