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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 4.3 進程快照 PyDbg 提供了一個非常酷的功能,進程快照。使用進程快照的時候,我們就能夠冰凍進 程,獲取進程的內存數據。以后我們想要讓進程回到這個時刻的狀態,只要使用這個時刻的 快照就行了。 ### 4.3.1 獲得進程快照 第一步,在一個準確的時間獲得一份目標進程的精確快照。為了使得快照足夠精確,需 要得到所有線程以及 CPU 上下文,還有進程的整個內存。將這些數據存儲起來,下次我們 需要恢復快照的時候就能用的到。 為了防止在獲取快照的時候,進程的數據或者狀態被修改,需要將進程掛起來,這個任 務由 suspend_all_threads()完成。掛起進程之后,可以用 process_snapshot()獲取快照。快照完 成之后,用 resume_all_threads()恢復掛起的進程,讓程序繼續執行。當某個時刻我們需要將 進程恢復到從前的狀態,簡單的 process_restore()就行了。這看起來是不是太簡單了? 現在新建個 snapshot.py 試驗下,代碼的功能就是我們輸入"snap"的時候創建一個快照, 輸入"restore"的時候將進程恢復到快照時的狀態。 ``` #snapshot.py from pydbg import * from pydbg.defines import * import threading import time import sys class snapshotter(object): def init (self,exe_path): self.exe_path = exe_path self.pid = None self.dbg = None self.running = True # Start the debugger thread, and loop until it sets the PID # of our target process pydbg_thread = threading.Thread(target=self.start_debugger) pydbg_thread.setDaemon(0) pydbg_thread.start() while self.pid == None: time.sleep(1) # We now have a PID and the target is running; let's get a # second thread running to do the snapshots monitor_thread = threading.Thread(target=self.monitor_debugger) monitor_thread.setDaemon(0) monitor_thread.start() def monitor_debugger(self): while self.running == True: input = raw_input("Enter: 'snap','restore' or 'quit'") input = input.lower().strip() if input == "quit": print "[*] Exiting the snapshotter." self.running = False self.dbg.terminate_process() elif input == "snap": print "[*] Suspending all threads." self.dbg.suspend_all_threads() print "[*] Obtaining snapshot." self.dbg.process_snapshot() print "[*] Resuming operation." self.dbg.resume_all_threads() elif input == "restore": print "[*] Suspending all threads." self.dbg.suspend_all_threads() print "[*] Restoring snapshot." self.dbg.process_restore() print "[*] Resuming operation." self.dbg.resume_all_threads() def start_debugger(self): self.dbg = pydbg() pid = self.dbg.load(self.exe_path) self.pid = self.dbg.pid self.dbg.run() exe_path = "C:\\WINDOWS\\System32\\calc.exe" snapshotter(exe_path) ``` 那么第一步就是在調試器內部創建一個新線程,并用此啟動目標進程。通過使用分開的線程,就能將被調試的進程和調試器的操作分開,這樣我們輸入不同的快照命令進行操作的 時候,就不用強迫被調試進程暫停。當創建新線程的代碼返回了有效的 PID,我們就創建另 一個線程,接受我們輸入的調試命令。之后這個線程根據我們輸入的命令決定不同的操作(快 照,恢復快照,結束程序)。 我們之所以選擇計算器作為例子,是因為通過操作圖形界面 ,可以更清晰的看到,快 照的作用。先在計算器里輸入一些數據,然后在終端里輸入"snap"進行快照,之后再在計算器 里進行別的操作。最后就當的輸入"restore",你將看到,計算器回到了最初時快照的狀態。 使用這種方法我們能夠將進程恢復到任意我們希望的狀態。 現在讓我們將所有的新學的 PyDbg 知識,創建一個 fuzz 輔助工具,幫助我們找到軟件 的漏洞,并自動處理奔潰事件。 ### 4.3.2 組合代碼 我們已經介紹了一些 PyDbg 非常有用的功能,接下來要構建一個工具用來根除應用程 序中出現的可利用的漏洞。在我們平常的開發過程中,有些函數是非常危險的,很容易造成 緩沖區溢出,字符串問題,以及內存出錯,對這些函數需要重點關注。 工具將定位于危險函數,并跟蹤它們的調用。當我們認為函數被危險調用了,就將 4 堆棧中的 4 個參數接觸引用,彈出棧,并且在函數產生溢出之前對進程快照。如果這次訪問 違例了,我們的腳本將把進程恢復到,函數被調用之前的快照。并從這開始,單步執行,同 時 反 匯 編 每 個 執 行 的 代 碼 , 直 到 我 們 也 拋 出 了 訪 問 違 例 , 或 者 執 行 完 了 MAX_INSTRUCTIONS(我們要監視的代碼數量)。無論什么時候當你看到一個危險的函數 在處理你輸入的數據的時候,嘗試操作數據 crash 數據都似乎值得。這是創造出我們的漏洞 利用程序的第一步。 開動代碼,建立 danger_track.py,輸入下面的代碼。 ``` #danger_track.py from pydbg import * from pydbg.defines import * import utils # This is the maximum number of instructions we will log # after an access violation MAX_INSTRUCTIONS = 10 # This is far from an exhaustive list; add more for bonus points dangerous_functions = { "strcpy" : "msvcrt.dll", "strncpy" : "msvcrt.dll", "sprintf" : "msvcrt.dll", "vsprintf": "msvcrt.dll" } dangerous_functions_resolved = {} crash_encountered = False instruction_count = 0 def danger_handler(dbg): # We want to print out the contents of the stack; that's about it # Generally there are only going to be a few parameters, so we will # take everything from ESP to ESP+20, which should give us enough # information to determine if we own any of the data esp_offset = 0 print "[*] Hit %s" % dangerous_functions_resolved[dbg.context.Eip] print "=================================================================" while esp_offset <= 20: parameter = dbg.smart_dereference(dbg.context.Esp + esp_offset) print "[ESP + %d] => %s" % (esp_offset, parameter) esp_offset += 4 print "=================================================================\n dbg.suspend_all_threads() dbg.process_snapshot() dbg.resume_all_threads() return DBG_CONTINUE def access_violation_handler(dbg): global crash_encountered # Something bad happened, which means something good happened :) # Let's handle the access violation and then restore the process # back to the last dangerous function that was called if dbg.dbg.u.Exception.dwFirstChance: return DBG_EXCEPTION_NOT_HANDLED crash_bin = utils.crash_binning.crash_binning() crash_bin.record_crash(dbg) print crash_bin.crash_synopsis() if crash_encountered == False: dbg.suspend_all_threads() dbg.process_restore() crash_encountered = True # We flag each thread to single step for thread_id in dbg.enumerate_threads(): print "[*] Setting single step for thread: 0x%08x" % thread_id h_thread = dbg.open_thread(thread_id) dbg.single_step(True, h_thread) dbg.close_handle(h_thread) # Now resume execution, which will pass control to our # single step handler dbg.resume_all_threads() return DBG_CONTINUE else: dbg.terminate_process() return DBG_EXCEPTION_NOT_HANDLED def single_step_handler(dbg): global instruction_count global crash_encountered if crash_encountered: if instruction_count == MAX_INSTRUCTIONS: dbg.single_step(False) return DBG_CONTINUE else: # Disassemble this instruction instruction = dbg.disasm(dbg.context.Eip) print "#%d\t0x%08x : %s" % (instruction_count,dbg.context.Eip, instruction) instruction_count += 1 dbg.single_step(True) return DBG_CONTINUE dbg = pydbg() pid = int(raw_input("Enter the PID you wish to monitor: ")) dbg.attach(pid) # Track down all of the dangerous functions and set breakpoints for func in dangerous_functions.keys(): func_address = dbg.func_resolve( dangerous_functions[func],func ) print "[*] Resolved breakpoint: %s -> 0x%08x" % ( func, func_address ) dbg.bp_set( func_address, handler = danger_handler ) dangerous_functions_resolved[func_address] = func dbg.set_callback( EXCEPTION_ACCESS_VIOLATION, access_violation_handler ) dbg.set_callback( EXCEPTION_SINGLE_STEP, single_step_handler ) dbg.run() ``` 通過之前對 PyDbg 的諸多講解,這段代碼應該看起來不那么難了吧。測試這個腳本的 最好方法,就是運行一個有漏洞價格的程序,然后讓腳本附加到進程,和程序交互,嘗試 crash 程序。 我們已經對 PyDbg 有了一定的了解,不過這只是它強大功能的一部分,還有更多的東 西,需要你自己去挖掘。再好的東西也滿足不了那些"懶惰"的 hacker。PyDbg 固然強大,方 便的擴展,自動化調試。不過每次要完成任務的時候,都要自己動手編寫代碼。接下來介紹 的 Immunity Debugger 彌補了這點,完美的結合了圖形化調試和腳本調試。它能讓你更懶, 哈。讓我們繼續。
                  <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>

                              哎呀哎呀视频在线观看