<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                這次所討論的三個問題,比如DLL以及HOOK,很容易被病毒木馬所利用,因此必須要比較全面地進行了解。而異常處理機制,則往往與漏洞相關聯。它們自身的概念并不難理解,只是由之引申而來的問題,在計算機安全領域則是比較高級的技術,也是需要掌握的。盡管面試的時候,往往是理論性比較強,但是實際上最重要的還是動手能力。作為一名反病毒工程師(盡管我目前還不是),不單單要掌握惡意程序的編寫技術,更需要清楚知道如何對付這些病毒木馬。從這里也能夠看出來,反病毒工程師的技術要求是比較高的,畢竟不單單要知道如何以正常手段使用計算機技術,更要知道如何以非正常手段編寫出惡意程序,知己知彼,才能更好地與病毒木馬作斗爭。 問題10——問題12如下: **10、請簡述你對動態鏈接庫(DLL)的理解。** 答:(以下內容選自**《VC++深入詳解》**第19.1節——動態鏈接庫概述) 自從微軟推出第一個版本的Windows操作系統以來,動態鏈接庫(DLL)一直就是Windows操作系統的基礎。動態鏈接庫通常都不能直接運行,也不能接收消息。它們是一些獨立的文件,其中包含能被可執行程序或其他DLL調用來完成某項工作的函數。只有在其他模塊調用動態鏈接庫中的函數時,它才發揮作用。在實際編程時,我們可以把完成某種功能的函數放在一個動態鏈接庫中,然后提供給其他程序調用。 WindowsAPI中所有的函數都包含在DLL,其中有3個最重要的DLL。 ?Kernel32.dll 它包含那些用于管理內存、進程和線程的函數,例如CreateThread函數; ?User32.dll 它包含那些用于執行用戶界面任務(如窗口創建和消息的傳送)的函數,例如CreateWindow函數; ?GDI32.dll 它包含那些用于畫圖和顯示文本的函數。 **知識擴展:** (以下內容選自**《C++黑客編程揭秘與防范》**第3.7.1節——DLL注入) 木馬或者病毒編寫質量的好壞取決于其隱藏程度,而不在于其功能多少。無論是病毒或是木馬,它們都是可執行程序,如果它們是EXE文件的話,那么就必將會產生一個進程,產生進程就很容易被發現。為了不被發現,可以選擇為DLL文件,DLL文件加載到進程的地址空間中,不會有進程名,因此其隱蔽性相對較好。DLL文件如果不被進程加載又如何在進程中呢?方法是強制讓某進程加載DLL文件,這個強制的手段就是下面要介紹的通過創建遠程線程將DLL注入到某個指定的進程中。 (以下內容選自**《Windows核心編程第5版》**第22.4節——使用遠程線程來注入DLL) …… 從根本上說,DLL注入技術要求目標進程中的一個線程調用LoadLibrary來載入我們想要的DLL。由于我們不能輕易地控制別人進程中的線程,因此這種方法要求我們在目標進程中創建一個新的線程。由于這個線程是我們自己創建的,因此我們可以對它執行的代碼加以控制。幸運的是,Windows提供了如下所示的CreateRemoteThread函數,它使得在另一個進程中創建線程變得非常容易: …… 現在我們已經理解了我們要做什么,讓我們來總結一下必須采取的步驟。 (1)用VirtualAllocEx函數在遠程進程的地址空間中分配一塊內存。 (2)用WriteProcessMemory函數把DLL的路徑名復制到第1步分配的內存中。 (3)用GetProcAddress函數來得到LoadLibraryW或LoadLibraryA函數(在Kernel32.dll中)的實際地址。 (4)用CreateRemoteThread函數在遠程進程中創建一個線程,讓新線程調用正確的LoadLibrary函數并在參數中傳入第1步分配的內存地址。這時,DLL已經被注入到遠程進程的地址空間中,DLL的DllMain函數會收到DLL_PROCESS_ATTACH通知并且可以執行我們想要執行的代碼。當DllMain返回的時候,遠程線程會從LoadLibraryW/A調用返回到BaseThreadStart函數(在第6章中介紹)。BaseThreadStart然后調用ExitThread,使遠程線程終止。 現在遠程進程中有一塊內存,它是我們在第1步分配的,DLL也還在遠程進程的地址空間中。為了對它們進行清理,我們需要在遠程線程退出之后執行后續步驟。 (5)用VirtualFreeEx來釋放第1步分配的內存。 (6)用GetProcAddress來得到FreeLibrary函數(在Kernel32.dll中)的實際地址。 (7)用CreateRemoteThread函數在遠程進程中創建一個線程,讓該線程調用FreeLibrary函數并在參數中傳入遠程DLL的HMODULE。 **11、請簡述你對HOOK的理解。** 答:(以下內容選自**《VC++深入詳解》**第20.1.1節) 首先回顧一下第一章中講述的Windows消息傳遞機制。當在應用程序窗口中按下鼠標左鍵時,操作系統會感知到這一事件,然后產生鼠標左鍵按鍵消息,接著把此消息放到應用程序的消息隊列中,應用程序通過調用GetMessage函數取出消息,然后調用DispatchMessage函數將這條消息調度給操作系統,操作系統會調用在設計窗口類時指定的應用程序窗口過程對這一消息進行處理。這一過程就是所有運行在Windows平臺下的窗口應用程序的消息傳遞過程,如圖20.1所示。 ![](https://box.kancloud.cn/2016-02-17_56c428a7561e8.jpg) 圖20.1 Windows應用程序的消息傳遞機制 在實際應用中,有時可能需要對某個特殊消息進行屏蔽,例如,我們開發了一個應用程序,不想讓它對鍵盤上的回車鍵和空格鍵做出響應,就需要截獲所有消息,然后進行判斷,如果是回車或空格按鍵消息,就將這兩種消息屏蔽掉,也就是說,不讓這樣的消息繼續傳遞下去。另一種情況,例如,我們開發了一個安裝程序,在安裝過程中希望安裝程序不能響應用戶的鼠標和鍵盤的按鍵消息,以免影響軟件的安裝過程,那么也需要截獲這兩類消息,然后讓它們不再繼續向下傳遞。 為了實現這一功能,可以安裝一個HOOK過程,稱為鉤子過程。操作系統在傳遞消息時,將我們感興趣的消息先傳遞給HOOK過程,在此函數中進行檢查,然后再決定是否放行該消息。這就好像逃犯在逃亡時可能會經過許多路段,為了抓住他,警察要在某些地方設置檢查站,以便檢查過往的車輛和行人。我們可以把車輛和行人看做是消息,檢查站就是HOOK過程。如果在某個檢查站發現了這個逃犯,就會把他抓起來。這樣就相當于阻止了逃犯的逃亡過程,讓他無法再繼續逃亡下去了。這個道理和鉤子過程是一樣的,操作系統將我們感興趣的消息都先交給鉤子過程,后者實際上就是一個函數,在此函數中進行判斷,如果是我們希望屏蔽掉的消息,那么就直接處理掉,不讓它再繼續向下傳遞。如果是其他我們不感興趣的消息,就直接放棄對它們的處理。這就好像對于那些不是逃犯的行人和車輛一樣,警察將會讓他們繼續前進。 (以下內容選自**《C++黑客編程揭秘與防范》**第5.1節——HOOK知識前奏) 在DOS時代進行編程,那時操作系統提供的編程接口不稱為API函數,而稱為中斷服務向量。也就是說,當時的操作系統提供的編程接口只有中斷,要進行寫文件要調用系統中斷,要進行讀文件也要調用系統中斷(當然,也不調用操作系統的中斷直接調用更底層的中斷)……中斷服務向量類似于Windows下的API函數,中斷服務向量在操作系統的某個地址保存著,它是以數組形式保存著的,我們也稱其為中斷向量表。DOS時代的HOOK技術也就是修改中斷向量表中的中斷地址。比如,要捕獲寫操作,那么就修改中斷向量表中關于寫文件的地址,將寫文件的中斷地址保存好,然后替換為我們的地址,這樣當程序調用寫文件中斷時,我們的函數就被執行了;當程序執行完可以繼續調用原來的中斷地址,從而完成寫文件的操作。 在Windows下HOOK技術的方法比較多,使用比較靈活,常見的應用層的HOOK方法有Inline Hook、IAT HOOK、Windows鉤子……HOOK技術涉及到了DLL相關的知識。因為HOOK其他進程的時候需要訪問其他進程的地址空間,使用DLL是必然的。HOOK技術也涉及到了注入的知識,想要把完成HOOK功能的DLL加載到目標進程空間中就要使用注入的知識了。讓我們來學習常用的HOOK技術吧。 **知識擴展:** **(以下內容選自**《**C++黑客編程揭秘與防范》**第5.2節——內聯鉤子:InlineHook) API函數都保存在操作系統提供的DLL文件中,當在程序中使用某個API函數時,在運行程序后,程序會隱式地將API所在的DLL加載入進程中。這樣,程序就會像調用自己的函數一樣調用API …… 假設要對某進程的kernel32.dll的CreateFile()函數進行HOOK,首先需要在指定進程中的內存中找到CreateFile()函數的地址,然后修改CreateFile()函數的首地址的代碼為jmp MyProc的指令。這樣,當指定的進程調用CreateFile()函數時,就會首先跳轉到我們的函數當中去執行,這樣就完成了我們的HOOK了。 …… 下面來梳理一下InlineHook的流程吧。流程如下。 (1)構造跳轉指令。 (2)在內存中找到欲HOOK函數地址,并保存欲HOOK位置處的前5個字節。 (3)將構造的跳轉指令寫入需HOOK的位置處。 (4)當被HOOK位置被執行時會轉到我們的流程執行。 (5)如果要執行原來的流程,那么取消HOOK,也就是還原被修改的字節。 (6)執行原來的流程。 (7)繼續HOOK住原來的位置。 這就是Inline Hook的大概的流程。 (以下內容選自**《C++黑客編程揭秘與防范》**第5.3.5節——IAT HOOK介紹) 在前面的內容中提到這樣一個問題,在IMAGE_IMPORT_DESCRIPTOR中,有兩個IMAGE_THUNK_DATA結構體,第一個為導入名字表,第二個為導入地址表(IAT)。兩個結構體在文件當中是沒有差別的,但是當PE文件被裝載內存后,第二個IMAGE_THUNK_DATA的值會被修正,該值為一個RVA,該RVA加上映像基址后,虛擬地址就保存了真正的導入函數的入口地址。 在這個描述當中我們知道,要對IAT進行HOOK大概分為3個步驟,首先是獲得要HOOK函數的地址,第二步是找到該函數所保存的IAT中的地址,最后一步是把IAT中的地址修改為HOOK函數的地址。這樣就完成了IAT HOOK。也許這樣的描述不是很清楚,那么下面就來舉例說明一下。 比如要在IAT中HOOK系統模塊kernel32.dll中的ReadFile()函數,那么首先是獲得ReadFile()函數的地址,第二步是找到ReadFile()所保存的IAT地址,最后一步是把IAT中的ReadFile()函數的地址修改為HOOK函數的地址。 (以下內容選自**《C++黑客編程揭秘與防范》**第5.4.1節——鉤子原理) Windows下的應用程序大部分是基于消息模式機制的,一些CUI的程序不是基于消息的。Windows下的應用程序都有一個消息函數,根據不同的消息來完成不同的功能。Windows操作系統提供的鉤子機制的作用是用來截獲、監視系統中的消息的。Windows操作系統提供了很多不同種類的鉤子,不同的鉤子可以處理不同的消息。 鉤子分為局部鉤子和全局鉤子。局部鉤子是針對一個線程的,而全局鉤子則是針對整個操作系統內基于消息機制的應用程序的。全局鉤子需要使用DLL文件,DLL文件里存放了鉤子函數的代碼。 在操作系統中安裝了全局鉤子以后,只要進程接收到可以發出鉤子的消息后,全局鉤子的DLL文件會被操作系統自動或強行地加載到該進程中。由此可見,設置消息鉤子也是一種可以進行DLL注入的方法。 **12、請簡述你對異常處理機制的理解。** 答:(以下內容選自**《Windows環境下32位匯編語言程序設計 典藏版》**第14.1節——異常處理的用途) Windows操作系統對異常的處理流程相對比較復雜,與DOS操作系統相比,最大的區別在于DOS的異常處理是被動的,一般僅用來處理操作系統內部的異常,對于其他層次的異常是無法處理的,比如,使用INT 21h去讀盤的時候發生錯誤會激發INT 24h中斷,但在BIOS服務程序級別用INT 13h去讀盤時發生錯誤就不會激發INT 24h中斷,對應用程序胡作非為引發的異常更是束手無策;而Windows的異常處理機制是依靠80x86處理器的保護機制來主動捕獲異常,所以Win32下異常處理程序的用途不僅僅局限于防止程序被Windows野蠻地終止,合理利用它們可以讓有些功能的實現方式變得更加簡單,一般來說,可以在下面這些情況下使用異常處理程序。 ●用來處理非致命的錯誤 程序執行中發生某些異常時只需要終止發生異常的模塊(或子程序),并沒有必要終止整個程序的運行,這時可以在異常處理程序中指定讓程序轉移到一個“安全”的地方去執行,并在這里完成資源釋放、刪除臨時文件、顯示錯誤提示等掃尾工作后從出錯模塊返回。 ●處理“計劃內”的異常 程序中的有些功能本來就是設計在異常處理模塊中實現的。Windows系統中虛擬內存的實現就是一個絕好的例子,第10章中介紹的內存映射文件也是以同樣的方法實現的。在這些情況下,“異常”是作為一個觸發條件使用的。 另外,在WindowsAPI中使用異常處理程序進行參數的合法性檢測也是很常見的。一般來說,大部分子程序都需要對輸入的參數進行合法性檢測,特別是對于指針類型的參數,但是當參數涉及的數據結構太復雜的時候,合法性檢測會大大降低程序的效率,這時可以假定參數全部合法并嘗試直接使用這些參數,如果異常處理程序沒有捕獲到錯誤,那么表示參數是合法的,這樣要比在每個步驟中檢測參數(或操作結果)的合法性要簡潔得多。 ●處理致命錯誤 雖然捕獲到致命錯誤的時候終止程序是最好的選擇,但是程序在退出之前,可以在異常處理程序中進行釋放資源、刪除臨時文件等操作,甚至可以詳細記錄產生異常的指令位置和環境,以便用來分析產生異常的原因。 (以下內容選自**《加密與解密 第三版》**第11.1節——基本概念) 所謂異常就是在應用程序的正常執行過程中發生的不正常事件。CPU引發的異常稱為硬件異常,例如訪問一個無效的內存地址。操作系統或應用程序引發的異常稱為軟件異常。 …… 除了CPU捕獲一個事件并引發一個硬件異常外,在代碼中也可以強制引發一個軟件異常。只需調用RaiseException函數: ~~~ VOID RaiseException( DWORD dwExceptionCode, //標識所引發異常的代碼 DWORD dwExceptionFlags, //異常繼續是否執行的標識 DWORD nNumberOfArguments, //附加信息 CONST DWORD *lpArguments //附加信息 ); ~~~ 程序捕獲軟件異常的方法與捕獲硬件異常的完全相同。 …… 首先來看看一個應用程序發生錯誤后,Windows是如何結合SEH機制進行處理的。 (1)因為有多種異常,系統首先判斷異常是否應發送給目標程序,如果應該發送,并且目標程序正處于被調試狀態,則系統掛起程序,填寫如下結構: ~~~ typedef _EXCEPTION_DEBUG_INFO{ EXCEPTION_RECORD ExceptionRecord; DWORD dwFirstchance; }EXCEPTION_DEBUG_INFO; ~~~ 將成員dwFirstchance置為1,并向調試器發送EXCEPTION_DEBUG_EVENT消息。剩下的事情就由調試器全權負責了,調試器可能處理這個異常,也可能無法處理。 (2)如果調試器未能處理異常或程序根本沒有被調試,系統就會查找是否存在與線程相關的異常處理過程,如果目標程序中存在與線程相關的異常處理程序,系統就調用程序的線程相關的SEH異常處理例程,交由其處理。 (3)與線程相關的異常處理過程可以有一個或多個,每個可以選擇處理或者不處理異常,如果它不處理并且存在多個線程相關的異常處理過程,可交由鏈起來的其他異常處理過程進行處理,依此類推。 (4)如果程序線程的異常處理均選擇不處理異常,如果程序處于被調試狀態,操作系統仍會再次掛起程序通知調試器,這次EXCEPTION_DEBUG_INFO結構的dwFirstchance成員置為0。 (5)如果程序未處于被調試狀態或者調試器仍然未能夠處理,并且程序調用了API函數SetUnhandledExceptionFilter設置了與進程相關的異常處理過程的話,系統轉向對它的調用。 (6)如果程序沒有設置相關的異常處理過程或者進程相關的異常處理過程也未能處理這個異常,系統會調用默認的系統異常處理程序,通常顯示一個對話框,可以選擇“確定”或者最后將其附加到調試器上的“取消”按鈕。如果沒有調試器能被附加于其上或調試器還是處理不了異常,系統就調用ExitProcess終結程序。 (7)不過在終結之前,系統再次調用發生異常的線程中所有的異常處理過程,這是線程異常處理過程獲得的最后清理未釋放資源的機會,其后程序就終結了。 學習SEH要樹立一個最基本的概念:SEH是系統發現異常或錯誤時,在終結應用程序之前給應用程序的一個最后改正錯誤的機會,從程序設計的角度來說,就是系統在終結程序之前給程序的一個執行其預設定的回調函數的機會。 …… 一般地,按作用域(即其監視范圍)分,SHE可分為兩類:一類是監視某線程中某段代碼是否發生異常的異常處理過程,一般稱為線程相關的異常處理過程,或稱為Per_Thread類型的異常處理過程,有時也簡稱為線程異常處理。另一類是監視整個進程中所有線程是否發生異常的異常處理過程,稱為進程相關的異常處理過程,或稱為“Final”型異常處理過程。有人也稱之為篩選器,源于其對應于設置其的API函數SetUnhandledExceptionFilter中的Filter一詞,在Win32 API文檔中,稱之為頂層(top-level)異常處理。 **本篇文章參考資料:** 1、孫鑫、余安萍,**《VC++深入詳解》**,電子工業出版社。 2、冀云,**《C++黑客編程揭秘與防范》**,人民郵電出版社。 3、[美]Jeffrey Richter、[法]Christophe Nasarre(著),葛子昂、周靖、廖敏(譯),**《Windows核心編程(第5版)》**,清華大學出版社。 4、段鋼(主編),Blowfish、沈曉斌、丁益青、單海波、王勇、趙勇、唐植明、softworm、afanty、李江濤、林子深、印豪、馮典、羅翼、林小華、郭春楊(編委),**《加密與解密(第三版)》**,電子工業出版社。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看