病毒與引擎的變遷
簡單特征碼 80年代末期,基於個人電腦病毒的誕生,隨即就有了清除病毒的工具──反病毒軟件。這一時期,病毒所使用的技術還比較簡單,從而檢測相對容易,最廣泛使用的就是特征碼匹配的方法。 特征碼是什麼呢?比如說,“如果在第1034字節處是下面的內容:0xec , 0x99, 0x80,0x99,就表示是大麻病毒。”這就是特征碼,一串表明病毒自身特征的十六進制的字串。特征碼一般都選得很長,有時可達數十字節,一般也會選取多個,以保證正確判斷。殺毒軟件通過利用特征串,可以非常容易的查出病毒。 廣譜特征
為了躲避殺毒軟件的查殺,電腦病毒開始進化。病毒為了躲避殺毒軟件的查殺,逐漸演變為變形的形式,每感染一次,就對自身變一次形,通過對自身的變形來躲避查殺。這樣一來,同一種病毒的變種病毒大量增加,甚至可以到達天文數字的量級。大量的變形病毒不同形態之間甚至可以做到沒有超過三個連續字節是相同的。 為了對付這種情況,首先特征碼的獲取不可能再是簡單的取出一段代碼來,而是分段的,中間可以包含任意的內容(也就是增加了一些不參加比較的“掩碼字節”,在出現“掩碼字節”的地方,出現什麼內容都不參加比較)。這就是曾經提出的廣譜特征碼的概念。這個技術在一段時間內,對於處理某些變形的病毒提供了一種方法,但是也使誤報率大大增加,所以采用廣譜特征碼的技術目前已不能有效的對新病毒進行查殺,並且還可能把正規程序當作病毒誤報給用戶。 啟發式掃描 為了對付病毒的不斷變化和對未知病毒的研究,啟發式掃描方式出現了。啟發式掃描是通過分析指令出現的順序,或特定組合情況等常見病毒的標准特征來決定文件是否感染未知病毒。因為病毒要達到感染和破壞的目的,通常的行為都會有一定的特征,例如非常規讀寫文件,終結自身,非常規切入零環等等。所以可以根據掃描特定的行為或多種行為的組合來判斷一個程序是否是病毒。 這種啟發式掃描比起靜態的特征碼掃描要先進的多,可以達到一定的未知病毒處理能力,但還是會有不准確的時候。特別是因為無法確定一定是病毒,而不可能做未知病毒殺毒。 行為判定 針對變形病毒、未知病毒等復雜的病毒情況,極少數殺毒軟件采用了虛擬機技術,達到了對未知病毒良好的查殺效果。它實際上是一種可控的,由軟件模擬出來的程序虛擬運行環境,就像我們看的電影《黑客帝國》一樣。在這一環境中虛擬執行的程序,就像生活在母體(Matrix)中的人,不論好壞,其一切行為都是受到建築師(architect)控制的。雖然病毒通過各種方式來躲避殺毒軟件,但是當它運行在虛擬機中時,它並不知道自己的一切行為都在被虛擬機所監控,所以當它在虛擬機中脫去偽裝進行傳染時,就會被虛擬機所發現,如此一來,利用虛擬機技術就可以發現大部分的變形病毒和大量的未知病毒。 引擎技術對比 各種引擎技術相比,虛擬機就像是一個偵探,可以根據對人的行為識別犯罪活動;啟發式掃描就像是警察,看你身上攜帶了槍支而懷疑你;廣譜特征是拿著照片追查已知的罪犯,但是會注意是否帶了假發或者墨鏡來逃避檢查;而特征碼識別就只是通過對人的外貌來判斷。簡單總結一下各種引擎技術的優缺點:
特征碼技術 靜態廣譜特征掃描技術 啟發式掃描技術 (靜態掃描 未知特征) 行為判定技術 速度快,准確率高 可以檢測部分變形病毒 誤報率低,能檢測變形病毒和病毒變種 基於強大而完整的虛擬機技術 能夠對未知病毒進行判別,對標准病毒准確率高 不能對付變形病毒或加密病毒 誤報率高 對未知病毒的檢測能力較低 實現難度大,速度慢 解壓縮與去殼 病毒隱藏自身的方法還有加殼和壓縮兩種方法。加殼是通過一系列的數學運算,將可執行程序或動態鏈接文件的編碼進行改變,以達到縮小程序體積或加密程序編碼的目的。通常常見的加殼工具有UPX、ASPack等。病毒通過使用不同種類或者版本的加殼軟件,對自身進行加殼,使得殺毒軟件無法發現真正的病毒體,以逃避查殺。並且由於加殼的工具種類很多,同一個工具也存在不同的版本。為了檢測已加殼的病毒,就必須要針對不同種類不同版本的殼編寫脫殼程序才可以發現殼內隱藏的真正病毒體。所以,殺毒軟件對病毒的查殺能力也在一定程度上取決於他自身的脫殼能力。 壓縮是普通用戶日常經常使用的減小文件體積的方法,常見的工具軟件有WinZip、WinRAR等。病毒有時候會隱藏在壓縮包內部,如果一個殺毒軟件沒有解壓縮的能力就不可能查殺壓縮包內的病毒。同時,如果殺毒軟件不具備相應格式的壓縮能力,在查殺病毒後就不能復原壓縮包,導致壓縮包破壞。可見,殺毒軟件要想做到對病毒的全面捕獲與查殺,脫殼解壓能力也是至關重要的。 利用特征碼技術的靜態殺毒引擎特征碼的選取
在進入程序的詳細講解之前,自學教程,先來講一下對於病毒程序的特征碼通常是如何選取出來的,以及特征碼的結構是什麼樣子的。
通常選擇特征碼是按照以下思路。 1. 獲取一個病毒程序的長度,根據長度可以將文件分為幾份,份數根據樣本長度而定,可以是3~5份,也可以更多。分成幾段獲取特征碼的方法可以很大程度上避免采用單一特征碼誤報病毒現象的發生,也可以避免特征碼過於集中造成的誤報。 2. 每份中選取通常為16或32個字節長的特征串。 在選取時,5自學網,應該采取如下的原則: 1. 如果選出來的信息是通用信息,即很多文件該位置都是一樣的信息,那麼捨棄,調整偏移量後重新選取。 2. 如果選取出來的信息是全零的字節。那麼也要調整偏移後重新選取。 當然調整的偏移量多少可以人為事先規定,也可以自動隨機調節。最後,將選取出來的幾段特征碼及它們的偏移量存入病毒庫,標示出病毒的名稱即可。為了方便選取特征碼,通常根據以上的思路編寫出特征碼提取程序,自動提取特征碼並作為病毒記錄存入病毒庫。 關鍵數據結構 下面我們來介紹一下整個引擎中關於特征碼掃描部分的代碼,整個引擎框架的結構由於篇幅有限,放在下期文章中進行介紹。 首先介紹程序中的兩個重要結構VSIGNATURE和VRECORD。一個VSIGNATURE是一個特征,很多個特征組成了一條病毒記錄,也就是一個VRECORD。 typedef struct tagVSIGNATURE { BAV_SIGN_TYPE eType; DWORD dwOffset; DWORD dwSize; BYTE Signature[MAX_SIGNATURE_LEN]; }VSIGNATURE,*PVSIGNATURE; typedef struct tagVRECORD { int nSize; DWORD dwVirusID; DWORD dwSignCount; PVSIGNATURE pVSing[8]; DWORD dwTreatCount; PVTREATMENT pVTreat[8]; }VRECORD,*PVRECORD; VSIGNATURE結構是用於存放單一特征碼的,其中的eType成員變量是一個枚舉結構,用來定義特征碼的類型,這裡演示工程裡目前我們只定義了一種簡單文件特征。dwOffset成員存儲該特征碼的偏移量。dwSize成員存儲特征碼的長度。字節型的Signature數組成員存放特征碼串,最大長度由 MAX_SIGNATURE_LEN宏控制,目前為32字節。 VRECORD結構用於存放病毒庫中每個病毒記錄的內容。其中nSize用於控制結構的版本,目前我們不用過多關心。dwVirusID成員指定病毒的ID編號。dwSignCount成員存放特征碼(VSIGNATURE)的段數,也就是對於該病毒取了多少段特征碼。pVSing數組成員存放每段特征碼的內容,這裡用數組是為了演示方便,以後我們會改為可變長度的數據結構。dwTreatCount成員存放處理該病毒的方法數量。pVTreat數組成員存放處理該病毒的每種方法的內容。這兩個成員要到我們增加殺毒方法的時候才會用到。 為了演示程序的簡單,這一版的病毒庫沒有從文件加載,而是直接在CVirusDB::Load()中編碼進去的。比如第一個eicar測試病毒的第一條特征是這樣的: { BS_PHY_FILE, 0, 32, 0x58, 0x35, 0x4F, 0x21, 0x50, 0x25, 0x40, 0x41, 0x50, 0x5B, 0x34, 0x5C, 0x50, 0x5A, 0x58, 0x35, 0x34, 0x28, 0x50, 0x5E, 0x29, 0x37, 0x43, 0x43, 0x29, 0x37, 0x7D, 0x24, 0x45, 0x49, 0x43, 0x41,}
它表明這是一個簡單文件特征,特征起始地址0,特征長度32,後