<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 12.2 PyEmu 一覽 PyEmu 被劃分成三個重要的系統:PyCPU,PyMemory 和 PyEmu。與我們交互最多的 就是 PyEmu 類,它再和 PyCPU 和 PyMemoey 交互完成底層的仿真工作。當我們測試驅動 PyEmu 執行一個指令的時候,它就調用 PyCPU 完成真正的指令操作。PyCPU 在進行指令操 作的時候,把需要的內存操作告訴 PyEmu,由 PyEmu 繼續調用 PyMemory 輔助完成整個指 令的操作,最后由 PyEmu 將指令的結果返回給調用者。 接下來,讓我們簡短的了解下各個子系統和他們的使用方法,以便更好的明白偉大的 PyEmu 替我們完成了什么,同時大家也能對實際應用有個初略的了解。 ### 12.2.1 PyCPU PyCPU 類是 PyEmu 的核心,它模擬成和真實的 CPU 一樣。在仿真的過程中,它負責 執行指令。當 PyCPU 處理一個指令的時候,會先檢索指令指針 ( 由負責靜態分析的 IDA Pro/PEPyEmu 或者負責動態調試的 PyDbg 獲取),然后將指令傳遞給 pydasm,由后者解碼成 操作碼和操作對象。PyCPU 提供的獨立解碼指令的能力使得 PyEmu 的跨平臺變成了可能。 每個 PyEmu 接收到的指令,都有一個相對應內部函數。舉個例子,如果將指令 CMP EAX ,1 傳給 PyCPU,接著 PyCPU 就會調用 PyCPU CMP()函數執行真正的操作,并從內存中 檢索必要的值,之后設置 CPU 的標志位,告訴程序這次比較的結果。有興趣的各位都可以 看看 PyCPU.py,所有的 PyEmu 支持的指令處理函數都在這里,通過研究它們可以明白 CPU 是如何完成那些神秘的底層操作的。別擔心代碼的可讀性, Cody 在這上面可沒少花功夫。 ### 12.2.2 PyMemory PyMemor 負責加載和儲存執行指令的必要數據。同時也可以對可執行程序的代碼和數 據塊進行映射,以便在仿真器中訪問。在將借完兩個主要類之后,讓我們看看核心類 PyEmu,以及相關的類方法。 ### 12.2.3 PyEmu PyEmu 負責驅動整個仿真器的運作。PyEmu 類本身被設計的非常輕便和靈活,使得開 發者能夠很塊的開發出強大的仿真器腳本,而不用關心底層操作。這一切都由 PyEmu 提供的幫助函數實現,使用它們能讓我們的這個逆向工作變得更簡單,無論是操作執行流程,改變寄存器值還是更新內存等等。下面就來卓一介紹它們。 ### 12.2.4 執行操作 PyEmu 的執行過程由一個函數控制,execute()。原型如下: ``` execute( steps=1, start=0x0, end=0x0 ) ``` 總共三個參數,如果一個都沒有提供,就從 PyEmu 當前的地址開始執行。這個地址也 許是 PyDbg 的 EIP 寄存器指向的位置,也許是 PEPyEmu 加載的可執行程序的入口地址,也 許是 IDA Pro 光標所處的位置。start 為開始執行的地址,steps 為執行的指令數量,end 為結 束的地址。 ### 12.2.5 內存和寄存器操作 修改和檢索寄存器與內存的值在逆向的過程中特別重要。 PyEmu 將它們分成了 4 類: 內存,棧變量(stack variables),棧參數(stack arguments),寄存器。內存操作由 get_memory() 和 set_memory()完成。 ``` get_memory( address, size ) set_memory( address, value, size=0 ) ``` get_memory()函數接收 2 個參數:address 為要查詢的地址,size 為要獲得數據的大小。 set_memoey()負責寫入數據,address 為寫入的地址,value 為寫入的值,size 為寫入數據的 大小。 另外兩類基于棧操作的函數也差不多,主要負責棧框架中函數參數和本地變量的檢索和 修改。 ``` set_stack_argument( offset, value, name="" ) get_stack_argument( offset=0x0, name="" ) set_stack_variable( offset, value, name="" ) get_stack_variable( offset=0x0, name="" ) ``` set_stack_argument()的 offset 相對與 ESP,用于對傳入函數的參數進行改變。在操作的過程中可以提供可以可選的名字。get_stack_argument()通過 offset 指定的相對于 ESP 的位移 獲得參數值,或者通過指定的 name(前提是在 set_stack_argument 中提供了)獲得。使用方式 如下: ``` set_stack_argument( 0x8, 0x12345678, name="arg_0" ) get_stack_argument( 0x8 ) get_stack_argument( "arg_0" ) ``` set_stack_variable()和 get_stack_variable()的操作也類似除了 offset 是相對于 EBP(如果允 許的話)以外,因為它們負責操作函數的局部變量。 ### 12.2.6 處理函數 處理函數提供了一種非常強大且靈活的回調結構,用于 觀察,設置或者修改程序的特定部分。PyEmu 中有 8 個主要處理函數: register 處理函數, library 處理函數, exception 處理函數, instruction 處理函數, opcode 處理函數, memory 處理 函數, high-level memory 處理函數還有 program counter 處理函數。讓我們快速的了解下每一 個函數,之后我們馬上要在用到它們。 12.2.6.1 Register 處理函數 Register Handlers 寄存器處理函數,用于監視任何寄存器的改變。只要有寄存器的遭到 修改就將觸發 Register Handlers。安裝方式如下: ``` set_register_handler( register, register_handler_function ) set_register_handler( "eax ", eax_register_handler ) ``` 安裝好之后,就需要定義處理函數了,原型如下: ``` def register_handler_function( emu, register, value, type ): ``` 當處理函數被調用的時候,所有的參數都又 PyEmu 傳入,第一個參數就是 PyEmu 實例 首,接著是寄存器名,以及寄存器的值,type 告訴我們這次操作是讀還是寫。時間久了你就 會發現用這種方式觀察寄存器是有多么強大且方便,如果需要你還能在處理函數里改變它 們。 12.2.6.2 ### Library 處理函數 Library handle 庫處理函數,能讓我們捕捉所有的外部庫調用,在它們被調用進程序之前就截獲它們,這樣就能很方便的修改外部庫函數的調用方式以及返回值。安裝方式如下: ``` set_library_handler( function, library_handler_function ) set_library_handler( "CreateProcessA", create_process_handler ) set_library_handler("LoadLibraryA", loadlibrary) ``` 庫處理函數的原型如下: ``` def library_handler_function( emu, library, address ): ``` 第一個參數就是 PyEmu 的實例。library 為我們想要監視的函數,或者庫,第三個是函 數被映射在內存中的地址。 12.2.6.3 Exception 處理函數 Exception Handlers 異常處理函數和第二章介紹的"處理函數相似"。PyEmu 仿真器中的 異常會觸發 Exception Handlers 的調用。當前 PyEmu 支持通用保護錯誤,也就是說我們能夠 處理在模擬器中的任何內存訪問違例。安裝方式如下: ``` set_exception_handler( "GP", gp_exception_handler ) ``` Exception 處理函數原型如下: ``` def gp_exception_handler( emu, exception, address ): ``` 同樣,第一個參數是 PyEmu 實例,exception 為異常代碼,address 為異常發生的地址。 12.2.6.4 Instruction 處理函數 Instruction Handlers 指令處理函數,很強大,因為它能捕捉任何特定的指令。就像 Cody 在 BlackHat 說展示的那樣,你能夠通過安裝一個 CMP 指令的處理函數,來監視整個程序流 程的分支判斷,并控制它們。 ``` set_instruction_handler( instruction, instruction_handler ) set_instruction_handler( "cmp", cmp_instruction_handler ) ``` Instruction 處理函數原型如下: ``` def cmp_instruction_handler( emu, instruction, op1, op2, op3 ): ``` 第一個參數照舊是 PyEmu 實例,instruction 則為被執行的指令,另外三個都是可能的運 算對象。 12.2.6.5 Opcode 處理函數 Opcode handlers 操作碼處理函數和指令處理函數非常相似,任何一個特定的操作碼被執 行的時候,都會調用 Opcode handlers。這樣我們對代碼的控制就變得更精確了。每一個指令 都有可能有不同的操作碼這依賴于它們的運算對象,例如,PUSH EAX 時操作碼是 0x50, 而 PUSH 0x70 時操作碼是 0x6A,合起來整個指令的操作碼就是 0x6A70,如下所示: ``` 50 PUSH EAX 6A 70 PUSH 0x70 ``` 它們的安裝方法很簡單: ``` set_opcode_handler( opcode, opcode_handler ) set_opcode_handler( 0x50, my_push_eax_handler ) set_opcode_handler( 0x6A70, my_push_70_handler ) ``` 第一個參數只要簡單的設置成我們需要捕捉的操作碼,第二個參數就是處理函數了。捕捉的范圍不限于單個字節,而可以是多這個字節,就想第二個例子一樣。處理函數原型如下: ``` def opcode_handler( emu, opcode, op1, op2, op3 ): ``` 第一個 PyEmu 實例,后面不再累贅。opcode 是捕捉到的操作碼,剩下的三個就是指令 可能使用到的計算對象。 12.2.6.6 Memory 處理函數 Memory handlers 內存處理函數用于跟蹤特定地址的數據訪問。它能讓我們很方便的跟 蹤緩沖區中感興趣的數據以及全局變量的改變過程。安裝過程如下: ``` set_memory_handler( address, memory_handler ) set_memory_handler( 0x12345678, my_memory_handler ) ``` address 簡單傳入我們想要觀察的內存地址, my_memory_handler 就是我們的處理函 數。函數原型如下: ``` def memory_handler( emu, address, value, size, type ) ``` 第二個參數 address 為發生內存訪問的地址,value 是被讀取或者寫入的數據,size 是數 據的大小,type 告訴我們這次操作讀還是寫。 12.2.6.7 High-Level Memory 處理函數 High-Level Memory Handlers 高級內存處理函數,很高級很強大。通過安裝它們,我們 就能監視這個內存快(包括棧和堆)的讀寫。這樣就能全面的控制內存的訪問,是不是很邪惡。安裝方式如下: ``` set_memory_write_handler( memory_write_handler ) set_memory_read_handler( memory_read_handler ) set_memory_access_handler( memory_access_handler ) set_stack_write_handler( stack_write_handler ) set_stack_read_handler( stack_read_handler ) set_stack_access_handler( stack_access_handler ) set_heap_write_handler( heap_write_handler ) set_heap_read_handler( heap_read_handler ) set_heap_access_handler( heap_access_handler ) ``` 所有的這些安裝函數只要簡單的提供一個處理函數就可以了,任何內存的變動都會通知 我們。處理函數的原型如下: ``` def memory_write_handler( emu, address ): def memory_read_handler( emu, address ): def memory_access_handler( emu, address, type ): ``` memory_write_handler 和 memory_read_handler 只是簡單的接收 PyEmu 實例和發生讀寫 的地址。第三個 access handler 多了一個 type 用于說明這次不做到的是讀數據還是些數據。 棧和堆的處理函數和上面的一樣,不做解說。 12.2.6.8 Program Counter 處理函數 The program counter handler 程序計數器處理函數,將在程序執行到特定地址的時候觸 發。安裝過程如下: ``` set_pc_handler( address, pc_handler ) set_pc_handler( 0x12345678, 12345678_pc_handler ) ``` address 為我們將要監視的地址,一旦 CPU 執行到這就會觸發我們的處理函數。處理 函數的原型如下: ``` def pc_handler( emu, address ): ``` 第二個參數 address 為被捕捉到的地址。 現在我們已經講解完了,PyEmu 的基礎知識。是時候將它們用于實際工作中了。接下 來會進行兩個實驗。第一個使用 IDAPyEmu 在 IDA Pro 模擬一個簡單的函數調用。第二個 實驗使用 PEPyEmu 解壓一個被 UPX 壓縮過的(偉大的開源壓縮程序)二進制文件。
                  <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>

                              哎呀哎呀视频在线观看