<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 功能強大 支持多語言、二開方便! 廣告
                ## 6.2 Hard Hooking 現在輪到有趣的地方了,hard hooking。這種 hook 很高級,對進程的影響也很小,因為 hook 代碼字節寫成了 x86 匯編代碼。在使用 soft hook 的時候在斷點觸發的時候有很多事件 發生,接著執行 hook 代碼,最后恢復進程。使用 hard hook 的時候,只要在進程內部擴展一 塊區域,存放 hook 代碼,跳轉到此區域執行完成后,返回正常的程序執行流程。優點就是, hard hook 目標進程的時候,進程沒有暫停,不像 soft hook。 Immunity 調試器提供了一個簡單的對象 FastLogHook 用來創建 hard hook。FastLogHook 在需要 hook 的函數里寫入跳轉代碼,跳到 FastLogHook 申請的一塊代碼區域,函數內被跳 轉代碼覆蓋的代碼就存放在這塊新創建的區域。當你構造 fast log hooks 的時候,需要先定 一個 hook 指針,然后定義想要記錄的數據指針。程序框架如下: ``` imm = immlib.Debugger() fast = immlib.FastLogHook( imm ) fast.logFunction( address, num_arguments ) fast.logRegister( register ) fast.logDirectMemory( address ) fast.logBaseDisplacement( register, offset ) ``` logFunction 接受兩個參數,address 就是在希望 hook 的函數內部的某個地址(這個地 址會被跳轉指令覆蓋)。如果在函數的頭部 hook,num_arguments 則設置成想要捕捉到的參 數 的 數 量 , 如 果 在 函 數 的 結 束 hook , 則 設 置 成 0 。 數 據 的 記 錄 由 logRegister(),logBaseDisplacement(), and logDirectMemory()三個方法完成。 ``` logRegister( register ) logBaseDisplacement( register, offset ) logDirectMemory( address ) ``` logRegister()方法用于跟蹤指定的寄存器,比如跟蹤函數的返回值(存儲在 EAX 中)。 logBaseDisplacement()方法接收 2 個參數,一個寄存器,和一個偏移量;用于從棧中提取參 數或者根據寄存器和偏移量獲取。最后一個 logDirectMemory()用于從指定的內存地址獲取 數據。 當 hook 觸發,log 函數執行之后,他們就將數據存儲在一個 FastLogHook 申請的地址。 為了檢索 hook 的結果,你必須使用 getAllLog()函數,它會返回一個 Python 列表: ``` [( hook_address, ( arg1, arg2, argN )), ... ] ``` 所以每次 hook 被觸發的時候,觸發地址就存在 hook_address 里,所有需要的信息包含 在 第 二 項 中 。 還 有 另 外 一 個 重 要 的 FastLogHook 就 是 STDCALLFastLogHook( 用 于 STDCALL 調用約定)。cdecl 調用約定使用 FastLogHook。 Nicolas Waisman(頂級堆溢出專家)開發了 hippie(利用 hard hook),可以在 Immunity 中通 過 PyCommand 進行調用。Nico 的解說: 創造 Hippie 的目的是為了創建一個好笑的 log hook,使得處理海量的堆函數調用變成可 能。舉個例子:如果你用 Notepad 打開一個文 件 對 話 框 , 它 需 要 調 用 大 約 4500 次 RtlAllocateHeap 和 RtlFreeHeap 。 如 果 是 Internet Explorer,堆相關的函數調用會有 10 倍甚至更多。 通過 hippie 學習堆的操作,對于將來寫基于堆利用的 exploit 相當重要。出于簡潔的原 因,我們只使用 hippie 的核心功能創建一個簡單的腳本 hippie_easy.py。 在我們開始前,先了解下 RtlAllocateHeap 和 RtlFreeHeap。 ``` BOOLEAN RtlFreeHeap( IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase ); PVOID RtlAllocateHeap( IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size ); ``` RtlFreeHeap 和 RtlAllocateHeap 的所有參數都是必須捕捉的,不過 RtlAllocateHeap 返回的新堆的地址也是需要捕捉的。 ``` #hippie_easy.py import immlib import immutils # This is Nico's function that looks for the correct # basic block that has our desired ret instruction # this is used to find the proper hook point for RtlAllocateHeap def getRet(imm, allocaddr, max_opcodes = 300): addr = allocaddr for a in range(0, max_opcodes): op = imm.disasmForward( addr ) if op.isRet(): if op.getImmConst() == 0xC: op = imm.disasmBackward( addr, 3 ) return op.getAddress() addr = op.getAddress() return 0x0 # A simple wrapper to just print out the hook # results in a friendly manner, it simply checks the hook # address against the stored addresses for RtlAllocateHeap, RtlFreeHeap def showresult(imm, a, rtlallocate): if a[0] == rtlallocate: imm.Log( "RtlAllocateHeap(0x%08x, 0x%08x, 0x%08x) <- 0x%08x %s" % (a[1][0], a[1][1], a[1][2], a[1][3], extra), address = a[1][3] ) return "done" else: imm.Log( "RtlFreeHeap(0x%08x, 0x%08x, 0x%08x)" % (a[1][0], a[1][1], a[1][2]) ) def main(args): imm = immlib.Debugger() Name = "hippie" fast = imm.getKnowledge( Name ) if fast: # We have previously set hooks, so we must want # to print the results hook_list = fast.getAllLog() rtlallocate, rtlfree = imm.getKnowledge("FuncNames") for a in hook_list: ret = showresult( imm, a, rtlallocate ) return "Logged: %d hook hits." % len(hook_list) # We want to stop the debugger before monkeying around imm.Pause() rtlfree = imm.getAddress("ntdll.RtlFreeHeap") rtlallocate = imm.getAddress("ntdll.RtlAllocateHeap") module = imm.getModule("ntdll.dll") if not module.isAnalysed(): imm.analyseCode( module.getCodebase() ) # We search for the correct function exit point rtlallocate = getRet( imm, rtlallocate, 1000 ) imm.Log("RtlAllocateHeap hook: 0x%08x" % rtlallocate) # Store the hook points imm.addKnowledge( "FuncNames", ( rtlallocate, rtlfree ) ) # Now we start building the hook fast = immlib.STDCALLFastLogHook( imm ) # We are trapping RtlAllocateHeap at the end of the function imm.Log("Logging on Alloc 0x%08x" % rtlallocate) fast.logFunction( rtlallocate ) fast.logBaseDisplacement( "EBP", 8 ) fast.logBaseDisplacement( "EBP", 0xC ) fast.logBaseDisplacement( "EBP", 0x10 ) fast.logRegister( "EAX" ) # We are trapping RtlFreeHeap at the head of the function imm.Log("Logging on RtlFreeHeap 0x%08x" % rtlfree) fast.logFunction( rtlfree, 3 ) # Set the hook fast.Hook() # Store the hook object so we can retrieve results later imm.addKnowledge(Name, fast, force_add = 1) return "Hooks set, press F9 to continue the process." ``` 第一個函數使用 Nico 內建的代碼塊找到可以在 RtlAllocateHeap 內部設置 hook 的地址。 讓我們反匯編 RtlAllocateHeap 函數看看最后幾行的指令是怎么樣的: ``` 0x7C9106D7 F605 F002FE7F TEST BYTE PTR DS:[7FFE02F0],2 0x7C9106DE 0F85 1FB20200 JNZ ntdll.7C93B903 0x7C9106E4 8BC6 MOV EAX,ESI 0x7C9106E6 E8 17E7FFFF CALL ntdll.7C90EE02 0x7C9106EB C2 0C00 RETN 0C ``` Python 代碼從函數的頭部看似反匯編,直到在 0x7C9106EB 找到 RET 指令然后確認整 行指令包含 0x0C。然后往后反匯編 3 行指令到達 0x7C9106D7。這樣做只不過是為了確保 有足夠的空間寫入 5 個字節的 JMP 指令。如果我們在 RET 這行寫入 5 個字節的 JMP 指令, 數據就會覆蓋出函數的代碼范圍。那接下來很可能發生恐怖的事情,破壞了代碼對齊,進程 會崩潰。這些小函數能幫你解決很多可怕的事情,在二進制面前,任何的差錯都會導致災難。 下一行代碼就是簡單的判斷 hook 是否設置了,如果設置了就從 knowledge base 中獲取 必要的目標,然后打印出 hook 信息。腳本第一次運行的時候設置 hook,第二次運行的時候 監視 hook 到的結果,每次運行都獲取新的 hook 數據。如果想查詢任何存儲在 knowledge base 里的目標,重要從調試器的 shell 里訪問就行了。 最后一塊代碼就是構造 hook 和監視點。對于 RtlAllocateHeap 調用獲取所有的三個參數 還有返回值,RtlFreeHeap 只要獲取三個參數就可以了。只用了不超過 100 行的代碼,我們 就成功使用了強大的 hard hook,沒用使用任何的編輯器和多余的工具。Very cool! 讓用 notepad.exe 做測試,看看是否如 Nico 所說打開一個對話框就會有將近 4500 個堆 調用。在 Immunity 下打開 C:\WINDOWS\System32\notepad.exe 運行!hippie_easy 命令(如果 不懂看 第五章)。恢復進程,在 Notepad 里選擇 File--&gt;Open。 現在確認結果。重復運行!hippie_easy,你將會看到調試器日志窗口(ALT-L)的輸出。 ``` RtlFreeHeap(0x000a0000, 0x00000000, 0x000ca0b0) RtlFreeHeap(0x000a0000, 0x00000000, 0x000ca058) RtlFreeHeap(0x000a0000, 0x00000000, 0x000ca020) RtlFreeHeap(0x001a0000, 0x00000000, 0x001a3ae8) RtlFreeHeap(0x00030000, 0x00000000, 0x00037798) RtlFreeHeap(0x000a0000, 0x00000000, 0x000c9fe8) ``` Listing 6-2 由!hippie_easy PyCommand 產生的輸出 非常好!我們有了一些結果,如果你看到 Immunity 調試器的狀態欄,會看到總共有 4674 次觸發。所以 Nico 是對的。你能在任何時候重新運行腳本以便看到新的觸發結果和統計數 值。最 cool 的地方是成千上萬次的調用都不會降低到進程的執行效率。 hook 將會在你的逆向調試中一次又一次的使用。在這里我們不僅學會了運用強大的 hook 技能,還讓這一切自動的進行,這是美好的,這是幸福的,這是偉大的。接下來讓我 們學習如何控制一個進程,那會更有趣。
                  <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>

                              哎呀哎呀视频在线观看