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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 11.3 腳本例子 我們先創建一些在逆向時候會經常用到的腳本。之后,大家可以在此基礎上擴展它們,進一步完成功能更強大,針對性更強的腳步。接下來的腳本將展示如何收集危險函數的調用 信息,以及用 IDA 的 debugger hook 監視函數的代碼覆蓋率,還有所有函數的棧的大小。 ### 11.3.1 收集危險函數的調用信息 當一個開發者在尋找軟件漏洞 bug 的時候,首先會找一些常用的而且容易被錯誤使用的 函數。比如危險的字符串拷貝函數 (strcpy, sprintf),內存拷貝函數(memcpy)等。在我們審核 程序的時候,需要很簡單的就找出這些函數。下面的腳本,將跟蹤這些危險的函數,找出調 用它們的地方,之后在這些地方的背景色設置成不同的顏色,我們在 IDA 窗口中就能很方 便的看出來。 ``` #cross_ref.py from idaapi import * danger_funcs = ["strcpy","sprintf","strncpy"] for func in danger_funcs: addr = LocByName( func ) if addr != BADADDR: # Grab the cross-references to this address cross_refs = CodeRefsTo( addr, 0 ) print "Cross References to %s" % func print "-------------------------------" for ref in cross_refs: print "%08x" % ref # Color the call RED SetColor( ref, CIC_ITEM, 0x0000ff) ``` 我們先獲得危險函數的地址,然后測試這些地址的有效性。接著獲得這些函數的交叉引用信息,確認什么地方調用了它們,最后把它們打印出來,并在 IDA 中給它們上色。用之 前編譯好的 war-ftpd.exe 做測試目標,將看到如下的輸出: ``` Cross References to sprintf ------------------------------- 004043df 00404408 004044f9 00404810 00404851 00404896 004052cc 0040560d 0040565e 004057bd 004058d7 ... ``` Listing 11-1: cross_ref.py 的輸出 上面這些被列出來的地址都是 sprintf 被調用的地方,如果在 IDA 中瀏覽這些地方 會看到它們都被上了色,如圖 11-3。 ![image](https://box.kancloud.cn/2016-03-11_56e2361b21742.gif) Figure 11-3: sprintf 調用通過 cross_ref.py 上色之后 ### 11.3.2 函數覆蓋率 在執行動態分析的時候,明白我們真正進行的操作是由什么代碼執行的,非常重要。無論是測試網絡程序發送一個數據包,還是使用文檔閱讀器代開一份文檔,代碼覆蓋率都能幫 我們很好的了解,程序做了什么。下面,我們將用 IDAPython 獲取目標程序的所有函數, 并且在再每個函數的開始處都設置好斷點。之后運行 IDA 調試器,debugger hook 會把每一 次斷點觸發的情況通知我們。 ``` #func_coverage.py from idaapi import * class FuncCoverage(DBG_Hooks): # Our breakpoint handler def dbg_bpt(self, tid, ea): print "[*] Hit: 0x%08x" % ea return # Add our function coverage debugger hook debugger = FuncCoverage() debugger.hook() current_addr = ScreenEA() # Find all functions and add breakpoints for function in Functions(SegStart( current_addr ), SegEnd( current_addr )): AddBpt( function ) SetBptAttr( function, BPTATTR_FLAGS, 0x0 ) num_breakpoints = GetBptQty() print "[*] Set %d breakpoints." % num_breakpoints ``` 第一步安裝 debugger hook ,調試事件發生的時候就會調用它。接著循環獲取所有函數 的地址,在每個地址上設置斷點。SetBptAttr 告訴調試器,遇到斷點后,不用停下來,繼續 執行;如果沒有這樣做,那我們就得手工恢復調試器了,不累死也得煩死。最后一部就是打 印出所有斷點的數量。當一個斷點被觸發的時候, debugger hook 里的斷點處理函數就會打 印出當前的地址,這個地址由變量 ea 提供,它引用當前 EIP 寄存器的值。現在運行調試器(熱鍵 F9),你將清楚的看到什么函數被執行了,以及它們執行的順序。 ### 11.3.3 計算棧大小 有時當我們對一個程序進行漏洞評估的時候,了解函數調用的棧的大小是很重要的。我們必須明確的知道,傳遞給函數的是一個指針還是申請好的棧緩沖區,如果是后者,我們就 會很感興趣,能傳遞多少數據給它,要知道溢出可是個精活,空間太小了盡管有漏洞也很難利 用。下面我們用一段簡短的代碼完成這項任務:枚舉程序中所有的函數,然后收集這些函數的棧信息,如果棧緩沖區大小符合我們的要求,就打印出來。將這些和前面的腳本合并起來, 我們就能在調試程序的時候,很好的跟蹤調試感興趣的函數 。 ``` #stack_calc.py from idaapi import * var_size_threshold = 16 current_address = ScreenEA() for function in Functions(SegStart(current_address), SegEnd(current_address) ): stack_frame = GetFrame( function ) frame_counter = 0 prev_count = -1 frame_size = GetStrucSize( stack_frame ) while frame_counter < frame_size: stack_var = GetMemberName( stack_frame, frame_counter ) if stack_var != "": if prev_count != -1: distance = frame_counter - prev_distance if distance >= var_size_threshold: print "[*] Function: %s -> Stack Variable: %s (%d bytes)" % ( GetFunctionName(function), prev_member, distance ) else: prev_count = frame_counter prev_member = stack_var try: frame_counter = frame_counter + GetMemberSize(stack_frame, frame_counter) except: frame_counter += 1 else: frame_counter += 1 ``` 我們設置了一個閾值,用來衡量一個棧變量的大小是不適合我們的需求;這里設置成 16 個字節,不過大家也可以實驗下各種不同的大小看看得出的結果。首先,循環獲取所有 的函數,得到每個函數的棧框架對象。調用 GetStrucSize 計算出棧框架的大小。接著循環 獲取棧中的變量。如果找到變量,就將當前變量的位置減去前一個變量的位置。然后通過之 間的差值計算出變量占據的空間大小。如果大小夠大,就打印出來,如果不夠大,就嘗試計 算當前變量的大小,然后加上當前的位置,得到下一個變量的位置。如果無法確認變量的大 小,就在當前的位置簡單的加一個字節,移動到下一個位置,然后繼續循環。在腳本運行后, 我們就能看看難道類似如下的輸出。 ``` [*] Function: sub_1245 -> Stack Variable: var_C(1024 bytes) [*] Function: sub_149c -> Stack Variable: Mdl (24 bytes) [*] Function: sub_a9aa -> Stack Variable: var_14 (36 bytes) ``` Listing 11-2: stack_calc.py 的輸出 現在我們有了 IDAPython 的基礎知識,同時也動手實現了幾個很容易擴展的腳本。這 些小小的腳本,將幫我們節省非常多的時間,在逆向工程中,最事件就是一切。下一章讓我 們看一看 IDAPython 的實際應用:PyEmu,一個基于 Python 的 x86 仿真器。
                  <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>

                              哎呀哎呀视频在线观看