• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            道。道。道

            安全特性不等于安全的特性

               :: 首頁 :: 聯系 :: 聚合  :: 管理

            常用鏈接

            搜索

            •  

            最新評論

            1 .緒論

            本文研究的主要內容正如其題目所示是設計并編寫一個先進的反病毒引擎。首先需要對這先進二字做一個解釋,何為先進?眾所周知,傳統的反病毒軟件使用的是基于特征碼的靜態掃描技術,即在文件中尋找特定十六進制串,如果找到,就可判定文件感染了某種病毒。但這種方法在當今病毒技術迅猛發展的形勢下已經起不到很好的作用了。原因我會在以下的章節中具體描述。因此本文將不對殺毒引擎中的特征碼掃描和病毒代碼清除模塊做分析。我們要討論的是為應付先進的病毒技術而必需的兩大反病毒技術--虛擬機和實時監控技術。具體什么是虛擬機,什么是實時監控,我會在相應的章節中做詳盡的介紹。這里我要說明的一點是,這兩項技術雖然在前人的工作中已有所體現(被一些國內外先進的反病毒廠家所使用),但出于商業目的,這些技術并沒有被完全公開,所以你無論從書本文獻還是網路上的資料中都無法找到關于這些技術的內幕。而我會在相關的章節中剖析大量的程序源碼(主要是2.4節中的一個完整的虛擬機源碼)或是逆向工程代碼(3.3.3節和3.4.3節中三個我逆向工程的某著名反病毒軟件的實時監控驅動程序及客戶程序的反匯編代碼),并同時公布一些我個人挖掘的操作系統內部未公開的機制和數據結構。下面就開始進入正題。

            目錄?

            1.1
            背景
            1.2
            當今病毒技術的發展狀況
            ? 1.2.1
            系統核心態病毒
            ? 1.2.2
            駐留病毒
            ? 1.2.3
            截獲系統操作
            ? 1.2.4
            加密變形病毒
            ? 1.2.5
            反跟蹤/反虛擬執行病毒
            ? 1.2.6
            直接API調用
            ? 1.2.7
            病毒隱藏
            ? 1.2.8
            病毒特殊感染法

            1.1 背景

            本文涉及的兩個主要技術,也是當今反病毒界使用的最為先進的技術中的兩個,究竟是作何而用的呢?首先說說虛擬機技術,它主要是為查殺加密變形病毒而設計的。簡單地來說,所謂虛擬機并不是個虛擬的機器,說得更合適一些應該是個虛擬CPU(用軟件實現的CPU),只不過病毒界都這么叫而已。它的作用主要是模擬INTEL X86 CPU的工作過程來解釋執行可執行代碼,與真正的CPU一樣能夠取指,譯碼并執行相應機器指令規定的操作。當然什么是加密變形病毒,它們為什么需要被虛擬執行以及怎樣虛擬執行等問題會在合適的章節中得到解答。再說另一個重頭戲--實時監控技術,它的用處更為廣泛,不僅局限于查殺病毒。被實時監控的對象也很多,如中斷(Intmon),頁面錯誤(Pfmon),磁盤訪問(Diskmon)等等。用于殺毒的監控主要是針對文件訪問,在你要對一個文件進行訪問時,實時監控會先檢查文件是否為帶毒文件,若是,則由用戶選擇是清除病毒還是取消此次操作請求。這樣就給了用戶一個相對安全的執行環境。但同時,實時監控會使系統性能有所下降,不少殺毒軟件的用戶都抱怨他們的實時監控讓系統變得奇慢無比而且不穩定。這就給我們的設計提出了更高的要求,即怎樣在保證準確攔截文件操作的同時,讓實時監控占用的系統資源更少。我會在病毒實時監控一節中專門討論這個問題。這兩項技術在國內外先進的反病毒廠家的產品中都有使用,雖然它們的源代碼沒有公開,但我們還是可以通過逆向工程的方法來窺視一下它們的設計思路。其實你用一個十六進制編輯器來打開它們的可執行文件,也許就會看到一些沒有剝掉的調試符號、變量名字或輸出信息,這些蛛絲馬跡對于理解代碼的意圖大有裨益。同時,在反病毒軟件的安裝目錄中后綴為.VXD.SYS就是執行實時監控的驅動程序,可以拿來逆向一下(參看我在后面分析驅動源代碼中的討論)。相信至此,我們對這兩項技術有了一個大體的了解。后面我們將深入到技術的細節中去。

            1.2 當今病毒技術的發展狀況

            要討論怎樣反病毒,就必須從病毒技術本身的討論開始。正是所謂知己知彼,百戰不殆。其實,我認為目前規定研究病毒技術屬于違法行為存在著很大的弊端。很難想象一個毫無病毒寫作經驗的人會成為殺毒高手。據我了解,目前國內一些著名反病毒軟件公司的研發隊伍中不乏病毒寫作高手。只不過他們將同樣的技術用到了正道上,以。所以我希望這篇論文能起到拋磚引玉的作用,期待著有更多的人會將病毒技術介紹給大眾。當今的病毒與DOSWIN3.1時代下的從技術角度上看有很多不同。我認為最大的轉變是:引導區病毒減少了,而腳本型病毒開始泛濫。原因是在當今的操作系統下直接改寫磁盤的引導區會有一定的難度(DOS則沒有保護,允許調用INT13直接寫盤),而且引導區的改動很容易被發現,所以很少有人再寫了;而腳本病毒以其傳播效率高且容易編寫而深得病毒作者的青睞。當然由于這兩種病毒用我上面說過的基于特征碼的靜態掃描技術就可以查殺,所以不在我們的討論之列。我要討論的技術主要來自于二進制外殼型病毒(感染文件的病毒),并且這些技術大都和操作系統底層機制或386以上CPU的保護模式相關,所以值得研究。大家都知道DOS下的外殼型病毒主要感染16位的COMEXE文件,由于DOS沒有保護,它們能夠輕松地進行駐留,減少可用內存(通過修改MCB鏈),修改系統代碼,攔截系統服務或中斷。而到了WIN9XWINNT/2000時代,想寫個運行其上的32WINDOWS病毒絕非易事。由于頁面保護,你不可能修改系統的代碼頁。由于I/O許可位圖中的規定,你也不能進行直接端口訪問。在WINDOWS中你不可能象在DOS中那樣通過截獲INT21H來攔截所有文件操作。總之,你以一個用戶態程序運行,你的行為將受到操作系統嚴格的控制,不可能再象DOS下那樣為所欲為了。另外值得一提的是,WINDOWS下采用的可執行文件格式和DOS下的EXE截然不同(普通程序采用PE格式,驅動程序采用LE),所以病毒的感染文件的難度增大了(PELE比較復雜,中間分了若干個節,如果感染錯了,將導致文件不能繼續執行)。因為當今病毒的新技術太多,我不可能將它們逐一詳細討論,于是就選取了一些重要并具有代表性的在本章的各小節中進行討論。

            1.2.1 系統核心態病毒

            在介紹什么是系統核心態病毒之前,有必要討論一下核心態與用戶態的概念。其實只要隨便翻開一本關于386保護模式匯編程序設計的教科書,都可以找到對這兩個概念的講述。386及以上的CPU實現了4個特權級模式(WINDOWS只用到了其中兩個),其中特權級0Ring0)是留給操作系統代碼,設備驅動程序代碼使用的,它們工作于系統核心態;而特權極3Ring3)則給普通的用戶程序使用,它們工作在用戶態。運行于處理器核心態的代碼不受任何的限制,可以自由地訪問任何有效地址,進行直接端口訪問。而運行于用戶態的代碼則要受到處理器的諸多檢查,它們只能訪問映射其地址空間的頁表項中規定的在用戶態下可訪問頁面的虛擬地址,且只能對任務狀態段(TSS)中I/O許可位圖(I/O Permission Bitmap)中規定的可訪問端口進行直接訪問(此時處理器狀態和控制標志寄存器EFLAGS中的IOPL通常為0,指明當前可以進行直接I/O的最低特權級別是Ring0)。以上的討論只限于保護模式操作系統,象DOS這種實模式操作系統則沒有這些概念,其中的所有代碼都可被看作運行在核心態。既然運行在核心態有如此之多的優勢,那么病毒當然沒有理由不想得到Ring0。處理器模式從Ring3Ring0的切換發生在控制權轉移時,有以下兩種情況:訪問調用門的長轉移指令CALL,訪問中斷門或陷阱門的INT指令。具體的轉移細節由于涉及復雜的保護檢查和堆棧切換,不再贅述,請參閱相關資料。現代的操作系統通常使用中斷門來提供系統服務,通過執行一條陷入指令來完成模式切換,在INTEL X86上這條指令是INT,如在WIN9X下是INT30(保護模式回調),在LINUX下是INT80,在WINNT/2000下是INT2E。用戶模式的服務程序(如系統DLL)通過執行一個INTXX來請求系統服務,然后處理器模式將切換到核心態,工作于核心態的相應的系統代碼將服務于此次請求并將結果傳給用戶程序。下面就舉例子說明病毒進入系統核心態的方法。

            WIN9X下進程虛擬地址空間中映射共享系統代碼的部分(3G--4G)中除了最上面4M頁表有頁面保護外其它地方可由用戶程序讀寫。如果你用Softice(系統級調試器)的PAGE命令查看這些地址的頁屬性,則你會驚奇地發現U RW位,這說明這些地址可從用戶態直接讀出或寫入。這意味著任何一個用戶程序都能夠在其運行過程中惡意或無意地破壞操作系統代碼頁。由此病毒就可以在GDT(全局描述符表),LDT(局部描述符表)中隨意構造門描述符并借此進入核心態。當然,也不一定要借助門描述,還有許多方法可以得到Ring0。據我所知的方法就不下10余種之多,如通過調用門(Callgate),中斷門(Intgate),陷阱門(Trapgate),異常門(Fault),中斷請求(IRQs),端口(Ports),虛擬機管理器(VMM),回調(Callback),形式轉換(Thunks),設備IO控制(DeviceIOControl,API函數(SetThreadContext ,中斷2E服務(NTKERN.VxD)。由于篇幅的限制我不可能將所有的方法逐一描述清楚,這里我僅選取最具有代表性的CIH病毒1.5版開頭的一段代碼。

            人們常說CIH病毒運用了VXD(虛擬設備驅動)技術,其實它本身并不是VXD。只不過它利用WIN9X上述漏洞,在IDT(中斷描述符表)中構造了一個DPL(段特權級)為3的中斷門(意味著可以從Ring3下執行訪問該中斷門的INT指令),并使描述符指向自己私有地址空間中的一個需要工作在Ring0下的函數地址。這樣一來CIH就可以通過簡單的執行一條INTXX指令(CIH選擇使用INT3,是為了使同樣接掛INT3的系統調試器Softice無法正常工作以達到反跟蹤的目的)進入系統核心態,從而調用系統的VMMVXD服務。以下是我注釋的一段CIH1.5的源代碼:

            ???????????????????????????????????????????????? ???????????????????????????????????????????????? ??????? ??????? ; *************************************

            ? ; * 修改IDT以求得核心態特權級 *

            ? ; *************************************

            ? push eax

            ? sidt [esp-02h] ;取得IDT表基地址

            ? pop ebx

            ? add ebx, HookExceptionNumber*08h+04h ZF = 0

            ? cli ;讀取修改系統數據時先禁止中斷

            ? mov ebp, [ebx]

            ? mov bp, [ebx-04h] ;取得原來的中斷入口地址

            ? lea esi, MyExceptionHook-@1[ecx] ;取得需要工作在Ring0的函數的偏移地址

            ? push esi

            ? mov [ebx-04h], si

            ? shr esi, 16

            ? mov [ebx+02h], si ;設置為新的中斷入口地址

            ? pop esi

            ? ; *************************************

            ? ; * 產生一個異常來進入Ring0 *

            ? ; *************************************

            ? int HookExceptionNumber ;產生一個異常

            ???????????????????????????????????????????????? ????????????????????????????????????????????????

            當然,后面還有恢復原來中斷入口地址和異常處理幀的代碼。

            剛才所討論的技術僅限于WIN9X,想在WINNT/2000下進入Ring0則沒有這么容易。主要的原因是WINNT/2000沒有上述的漏洞,它們的系統代碼頁面(2G--4G)有很好的頁保護。大于0x80000000的虛擬地址對于用戶程序是不可見的。如果你用SofticePAGE命令查看這些地址的頁屬性,你會發現S位,這說明這些地址僅可從核心態訪問。所以想在IDTGDT隨意構造描述符,運行時修改內核是根本做不到的。所能做的僅是通過加載一個驅動程序,使用它來做你在Ring3下做不到的事情。病毒可以在它們加載的驅動中修改內核代碼,或為病毒本身創建調用門(利用NTNtoskrnl.exe導出的未公開的系統服務KeI386AllocateGdtSelectorsKeI386SetGdtSelectorKeI386ReleaseGdtSelectors)。如Funlove病毒就利用驅動來修改系統文件(Ntoskrnl.exeNtldr)以繞過安全檢查。但這里面有兩個問題,其一是驅動程序從哪里來,現代病毒普遍使用一個稱為“Drop”的技術,即在病毒體本身包含驅動程序二進制碼(可以進行壓縮或動態構造文件頭),在病毒需要使用時,動態生成驅動程序并將它們扔到磁盤上,然后馬上通過在SCM(服務控制管理器)注冊并最終調用StartService來使驅動程序得以運行;其二是加載一個驅動程序需要管理員身份,普通帳號在調用上述的加載函數時會返回失敗(安全子系統要檢查用戶的訪問令牌(Token)中有無SeLoadDriverPrivilege特權),但多數用戶在大多時候登錄時會選擇管理員身份,否則連病毒實時監控驅動也同樣無法加載,所以留給病毒的機會還是很多的。

            1.2.2 駐留病毒

            駐留病毒是指那些在內存中尋找合適的頁面并將病毒自身拷貝到其中且在系統運行期間能夠始終保持病毒代碼的存在。駐留病毒比那些直接感染(Direct-action)型病毒更具隱蔽性,它通常要截獲某些系統操作來達到感染傳播的目的。進入了核心態的病毒可以利用系統服務來達到此目的,如CIH病毒通過調用一個由VMM導出的服務VMMCALL_PageAllocate在大于0xC0000000的地址上分配一塊頁面空間。而處于用戶態的程序要想在程序退出后仍駐留代碼的部分于內存中似乎是不可能的,因為無論用戶程序分配何種內存都將作為進程占用資源的一部分,一旦進程結束,所占資源將立即被釋放。所以我們要做的是分配一塊進程退出后仍可保持的內存。

            病毒寫作小組29A的成員GriYo 運用的一個技術很有創意:他通過CreateFileMappingA MapViewOfFile創建了一個區域對象并映射它的一個視口到自己的地址空間中去,并把病毒體搬到那里,由于文件映射所在的虛擬地址處于共享區域(能夠被所有進程看到,即所有進程用于映射共享區內虛擬地址的頁表項全都指向相同的物理頁面),所以下一步他通過向Explorer.exe中注入一段代碼(利用WriteProcessMemory來向其它進程的地址空間寫入數據),而這段代碼會從Explorer.exe的地址空間中再次申請打開這個文件映射。如此一來,即便病毒退出,但由于Explorer.exe還對映射頁面保持引用,所以一份病毒體代碼就一直保持在可以影響所有進程的內存頁面中直至Explorer.exe退出。

            另外還可以通過修改系統動態連接模塊(DLL)來進行駐留。WIN9X下系統DLL(如Kernel32.dll 映射至BFF70000)處于系統共享區域(2G-3G),如果在其代碼段空隙中寫入一小段病毒代碼則可以影響其它所有進程。但Kernel32.dll的代碼段在用戶態是只能讀不能寫的。所以必須先通過特殊手段修改其頁保護屬性;而在WINNT/2000下系統DLL所在頁面被映射到進程的私有空間(如Kernel32.dll 映射至77ED0000)中,并具有寫時拷貝屬性,即沒有進程試圖寫入該頁面時,所有進程共享這個頁面;而當一個進程試圖寫入該頁面時,系統的頁面錯誤處理代碼將收到處理器的異常,并檢查到該異常并非訪問違例,同時分配給引發異常的進程一個新頁面,并拷貝原頁面內容于其上且更新進程的頁表以指向新分配的頁。這種共享內存的優化給病毒的寫作帶來了一定的麻煩,病毒不能象在WIN9X下那樣僅修改Kernel32.dll一處代碼便可一勞永逸。它需要利用WriteProcessMemory來向每個進程映射Kernel32.dll的地址寫入病毒代碼,這樣每個進程都會得到病毒體的一個副本,這在病毒界被稱為多進程駐留或每進程駐留(Muti-Process Residence or Per-Process Residence )。

            1.2.3 截獲系統操作

            截獲系統操作是病毒慣用的伎倆。DOS時代如此,WINDOWS時代也不例外。在DOS下,病毒通過在中斷向量表中修改INT21H的入口地址來截獲DOS系統服務(DOS利用INT21H來提供系統調用,其中包括大量的文件操作)。而大部分引導區病毒會接掛INT13H(提供磁盤操作服務的BIOS中斷)從而取得對磁盤訪問的控制。WINDOWS下的病毒同樣找到了鉤掛系統服務的辦法。比較典型的如CIH病毒就是利用了IFSMGR.VXD(可安裝文件系統)提供的一個系統級文件鉤子來截獲系統中所有文件操作,我會在相關章節中詳細討論這個問題,因為WIN9X下的實時監控也主要利用這個服務。除此之外,還有別的方法。但效果沒有這個系統級文件鉤子好,主要是不夠底層,會丟失一些文件操作。

            其中一個方法是利用APIHOOK,鉤掛API函數。其實系統中并沒有現成的這種服務,有一個SetWindowsHookEx可以鉤住鼠標消息,但對截獲API函數則無能為力。我們能做的是自己構造這樣的HOOK。方法其實很簡單:比如你要截獲Kernel32.dll導出的函數CreateFile,只須在其函數代碼的開頭(BFF7XXXX)加入一個跳轉指令到你的鉤子函數的入口,在你的函數執行完后再跳回來。如下圖所示:

            ???????????????????????????????????????????????? ???????????????????????????????????????????????? ??????? ??????? ;; Target Function (要截獲的目標函數)

            ? ……

            ? TargetFunction: (要截獲的目標函數入口)

            ? jmp DetourFunction (跳到鉤子函數,5個字節長的跳轉指令)

            ? TargetFunction+5:

            ? push edi

            ? ……

            ? ;; Trampoline (你的鉤子函數)

            ? ……

            ? TrampolineFunction: (你的鉤子函數執行完后要返回原函數的地方)

            ? push ebp

            ? mov ebp,esp

            ? push ebx

            ? push esi (以上幾行是原函數入口處的幾條指令,共5個字節)

            ? jmp TargetFunction+5 (跳回原函數)

            ? ……

            ???????????????????????????????????????????????? ????????????????????????????????????????????????

            但這種方法截獲的僅僅是很小一部分文件打開操作。

            WIN9X下還有一個鮮為人知的截獲文件操作的辦法,說起來這應該算是WIN9X的一大后門。它就是Kernel32.dll中一個未公開的叫做VxdCall0API函數。反匯編這個函數的代碼如下:

            ???????????????????????????????????????????????? ???????????????????????????????????????????????? ??????? ??????? mov eax,dword ptr [esp+00000004h] ;取得服務代號

            pop dword ptr [esp] ;堆棧修正

            call fword ptr cs:[BFFC9004] ;通過一個調用門調用3B段某處的代碼

            ???????????????????????????????????????????????? ????????????????????????????????????????????????

            如果我們繼續跟蹤下去,則會看到:

            ???????????????????????????????????????????????? ???????????????????????????????????????????????? ??????? ??????? 003B:XXXXXXXX int 30h

            ???????????????????????????????????????????????? ????????????????????????????????????????????????

            這是個用以陷入VWIN32.VXD的保護模式回調

            有關VxdCall的詳細內容,請參看Matt Pietrek的《Windows 95 System Programming Secrets》。

            當服務代號為0X002A0010時,保護模式回調會陷入VWIN32.VXD中一個叫做VWIN32_Int21Dispatch的服務。這正說明了WIN9X還在依賴于MSDos,盡管微軟聲稱WIN9X不再依賴于MSDos。調用規范如下:

            ???????????????????????????????????????????????? ???????????????????????????????????????????????? ??????? ??????? my_int21h:push ecx

            ? push eax ;類似DOSINT21HAX中傳入的功能號

            ? push 002A0010h

            ? call dword ptr [ebp+a_VxDCall]

            ? ret

            ???????????????????????????????????????????????? ????????????????????????????????????????????????

            我們可以將上面VxdCall0函數的入口處第三條遠調用指令訪問的Kernel32.dll數據段中用戶態可寫地址BFFC9004Υ⒌?FWORD'六個字節改為指向我們自己鉤子函數的地址,并在鉤子中檢查傳入服務號和功能號來確定是否是請求VWIN32_Int21Dispatch中的某個文件服務。著名的HPS病毒就利用了這個技術在用戶態下直接截獲系統中的文件操作,但這種方法截獲的也僅僅是一小部分文件操作。

            1.2.4 加密變形病毒

            加密變形病毒是虛擬機一章的重點內容,將放到相關章節中介紹。

            1.2.5 反跟蹤/反虛擬執行病毒

            反跟蹤/反虛擬執行病毒和虛擬機聯系密切,所以也將放到相應的章節中介紹。

            1.2.6 直接API調用

            直接API調用是當今WIN32病毒常用的手段,它指的是病毒在運行時直接定位API函數在內存中的入口地址然后調用之的一種技術。普通程序進行API調用時,編譯器會將一個API調用語句編譯為幾個參數壓棧指令后跟一條間接調用語句(這是指Microsoft編譯器,Borland編譯器使用JMP

            ???????????????????????????????????????????????? ???????????????????????????????????????????????? ??????? ??????? DWORD PTR [XXXXXXXXh] )形式如下:

            ? push arg1

            ? push arg2

            ? ……

            ? call dword ptr[XXXXXXXXh]

            ???????????????????????????????????????????????? ????????????????????????????????????????????????

            地址XXXXXXXXh在程序映象的導入(Import Section)段中,當程序被加載運行時,由裝入器負責向里面添入API函數的地址,這就是所謂的動態鏈接機制。病毒由于為了避免感染一個可執行文件時在文件的導入段中構造病毒體代碼中用到的API的鏈接信息,它選擇運用自己在運行時直接定位API函數地址的代碼。其實這些函數地址對于操作系統的某個版本是相對固定的,但病毒不能依賴于此。現在較為流行的做法是先定位包含API函數的動態連接庫的裝入基址,然后在其導出段(Export Section)中尋找到需要的API地址。后面一步幾乎沒有難度,只要你熟悉導出段結構即可。關鍵在于第一步--確定DLL裝入地址。其實系統DLL裝入基址對于操作系統的某個版本也是固定的,但病毒為確保其穩定性仍不能依賴這一點。目前病毒大都利用一個叫做結構化異常處理的技術來捕獲病毒體引發的異常。這樣一來病毒就可以在一定內存范圍內搜索指定的DLLDLL使用PE格式,頭部有固定標志),而不必擔心會因引發頁面錯誤而被操作系統殺掉。

            由于異常處理和后面的反虛擬執行技術密切相關,所以特將結構化異常處理簡單解釋如下:

            共有兩類異常處理:最終異常處理和每線程異常處理。

            其一:最終異常處理

            當你的進程中無論哪個線程發生了異常,操作系統將調用你在主線程中調用SetUnhandledExceptionFilter建立的異常處理函數。你也無須在退出時拆去你安裝的處理代碼,系統會為你自動清除。

            ???????????????????????????????????????????????? ???????????????????????????????????????????????? ??????? ??????? PUSH OFFSET FINAL_HANDLER

            ? CALL SetUnhandledExceptionFilter

            ? ……

            ? CALL ExitProcess

            ? ************************************

            ? FINAL_HANDLER:

            ? ……

            ? ;(eax=-1 reload context and continue)

            ? MOV EAX,1

            ? RET program entry point

            ? ……

            ? code covered by final handler

            ? ……

            ? code to provide a polite exit

            ? ……

            ? eax=1 stops display of closure box

            ? eax=0 enables display of the box

            ???????????????????????????????????????????????? ?????????????? ?????????????????????????????????

            其二:每線程異常處理

            FS 中的值是一個十六位的選擇子,它指向包含線程重要信息的數據結構TIB,線程信息塊。其的首雙字節指向我們稱為ERR的結構:

            ???????????????????????????????????????????????? ???????????????????????????????????????????????? ??????? ??????? 1st dword +0 pointer to next err structure

            ( 下一個err結構的指針)

            2nd dword +4 pointer to own exception handler

            ( 當前一級的異常處理函數的地址)

            ???????????????????????????????????????????????? ????????????????????????????????????????????????

            所以異常處理是呈練狀的,如果你自己的處理函數捕捉并處理了這個異常,那么當你的程序發生了異常時,操作系統就不會調用它缺省的處理函數了,也就不會出現一個討厭的執行了非法操作的紅叉。

            下面是cih的異常段:

            ???????????????????????????????????????????????? ???????????????????????????????????????????????? ??????? ??????? MyVirusStart:

            ? push ebp

            ? lea eax, [esp-04h*2]

            ? xor ebx, ebx

            ? xchg eax, fs:[ebx] ;交換現在的err結構和前一個結構的地址

            ? eax=前一個結構的地址

            ? fs:[0]=現在的err結構指針(在堆棧上)

            ? call @0

            ? @0:

            ? pop ebx

            ? lea ecx, StopToRunVirusCode-@0[ebx] ;你的異常處理函數的偏移

            ? push ecx ;你的異常處理函數的偏移壓棧

            ? push eax ;前一個err結構的地址壓棧

            ? ;構造err結構,記這時候的esp(err結構指針)esp0

            ? ……

            ? StopToRunVirusCode:

            ? @1 = StopToRunVirusCode

            ? xor ebx, ebx ;發生異常時系統在你的練前又加了一個err結構,

            ?????????????????????? ;所以要先找到原來的結構地址

            ? mov eax, fs:[ebx] ; 取現在的err結構的地址eax

            ? mov esp, [eax] ; 取下個結構地址即eps0esp

            ? RestoreSE: ;沒有發生異常時順利的回到這里,你這時的esp為本esp0

            ? pop dword ptr fs:[ebx] ;彈出原來的前一個結構的地址到fs:0

            ? pop eax ;彈出你的異常處理地址,平棧而已

            ?????????????????????? ????????????????????????? ????????????????????????????????????????????????

            1.2.7 病毒隱藏

            實現進程或模塊隱藏應該是一個成功病毒所必須具備的特征。在WIN9XKernel32.dll有一個可以使進程從進程管理器進程列表中消失的導出函數RegisterServiceProcess ,但它不能使病毒逃離一些進程瀏覽工具的監視。但當你知道這些工具是如何來枚舉進程后,你也會找到對付這些工具相應的辦法。進程瀏覽工具在WIN9X下大都使用一個叫做ToolHelp32.dll的動態連接庫中的Process32FirstProcess32Next兩個函數來實現進程枚舉的;而在WINNT/2000里也有PSAPI.DLL導出的EnumProcess可用以實現同樣之功能。所以病毒就可以考慮修改這些公用函數的部分代碼,使之不能返回特定進程的信息從而實現病毒的隱藏。

            但事情遠沒有想象中那么簡單,俗話說道高一尺,魔高一丈,此理不謬。由于現在很多逆項工程師的努力,微軟力圖隱藏的許多秘密已經逐步被人們所挖掘出來。當然其中就包括WINDOWS內核使用的管理進程和模塊的內部數據結構和代碼。比如WINNT/2000用由ntoskrnl.exe導出的內核變量PsInitialSystemProcess所指向的進程Eprocess塊雙向鏈表來描述系統中所有活動的進程。如果進程瀏覽工具直接在驅動程序的幫助下從系統內核空間中讀出這些數據來枚舉進程,那么任何病毒也無法從中逃脫。

            有關Eprocess的具體結構和功能,請參看David A.SolomonMark E.Russinovich的《Inside Windows2000》第三版。

            1.2.8 病毒特殊感染法

            對病毒稍微有些常識的人都知道,普通病毒是通過將自身附加到宿主尾部(如此一來,宿主的大小就會增加),并修改程序入口點來使病毒得到擊活。但現在不少病毒通過使用特殊的感染技巧能夠使宿主大小及宿主文件頭上的入口點保持不變。

            附加了病毒代碼卻使被感染文件大小不變聽起來讓人不可思議,其實它是利用了PE文件格式的特點:PE文件的每個節之間留有按簇大小對齊后的空洞,病毒體如果足夠小則可以將自身分成幾份并分別插入到每個節最后的空隙中,這樣就不必額外增加一個節,因而文件大小保持不變。著名的CIH病毒正是運用這一技術的典型范例(它的大小只有1K左右)。

            病毒在不修改文件頭入口點的前提下要想獲得控制權并非易事:入口點不變意味著程序是從原程序的入口代碼處開始執行的,病毒必須要將原程序代碼中的一處修改為導向病毒入口的跳轉指令。原理就是這樣,但其中還存在很多可討論的地方,如在原程序代碼的何處插入這條跳轉指令。一些查毒工具掃描可執行文件頭部的入口點域,如果發現它指向的地方不正常,即不在代碼節而在資源節或重定位節中,則有理由懷疑文件感染了某種病毒。所以剛才討論那種病毒界稱之為EPO(入口點模糊)的技術可以很好的對付這樣的掃描,同時它還是反虛擬執行的重要手段。

            另外值得一提的是現在不少病毒已經支持對壓縮文件的感染。如Win32.crypto病毒就可以感染ZIPARJRARACECAB 等諸多類型的壓縮文件。這些病毒的代碼中含有對特定壓縮文件類型解壓并壓縮的代碼段,可以先把壓縮文件中的內容解壓出來,然后對合適的文件進行感染,最后再將感染后文件壓縮回去并同時修改壓縮文件頭部的校驗和。目前不少反病毒軟件都支持查多種格式的壓縮文件,但對有些染毒的壓縮文件無法殺除。原因我想可能是怕由于某種緣故,如解壓或壓縮有誤,校驗和計算不對等,使得清除后壓縮文件格式被破壞。病毒卻不用對用戶的文件損壞負責,所以不存在這種擔心。【未完待續】

            主要參考文獻

            David A. Solomon, Mark Russinovich Inside Microsoft Windows 2000September 2000

            David A. Solomon Inside Windows NT May 1998

            Prasad Dabak Sandeep PhadkeMilind Borate Undocumented Windows NTOctober 1999

            Matt Pietrek Windows 95 System Programming Secrets March 1996

            Walter Oney System Programming for Windows 95 March 1996

            Walter Oney Programming the Windows Driver Model 1999

            陸麟 《WINDOWS9X文件讀寫Internal2001

            ?

            ?

            posted on 2007-01-19 22:41 獨孤九劍 閱讀(398) 評論(0)  編輯 收藏 引用 所屬分類: Win32
            国产激情久久久久影院老熟女| 久久WWW免费人成一看片| 无码任你躁久久久久久老妇App| 久久婷婷五月综合97色| 久久天天躁夜夜躁狠狠| 99久久综合国产精品免费| 久久这里的只有是精品23| 免费一级欧美大片久久网| 久久夜色精品国产亚洲av| 久久久噜噜噜久久| 午夜视频久久久久一区 | 国产成人精品久久一区二区三区av| 久久久噜噜噜www成人网| 国产成年无码久久久久毛片| 精品久久久久久亚洲精品| 久久99国产综合精品| 久久亚洲精品中文字幕三区| 成人国内精品久久久久一区| 51久久夜色精品国产| 久久婷婷五月综合色99啪ak| 国产精品成人久久久| 久久99国产综合精品| 久久综合九色综合97_久久久| 久久婷婷久久一区二区三区| 久久精品国产一区二区| 四虎国产精品成人免费久久| 久久精品人人做人人爽97| 四虎国产精品免费久久久| 亚洲国产精品无码久久久久久曰| 久久久午夜精品| 久久er热视频在这里精品| 久久久午夜精品福利内容| 国产91色综合久久免费| 欧美性猛交xxxx免费看久久久| 久久人人爽人人爽人人片av麻烦| 国产综合久久久久| 久久久这里有精品| 久久se精品一区二区影院| 麻豆亚洲AV永久无码精品久久| 久久国产高清一区二区三区| 日韩久久久久久中文人妻 |