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