簡體   English   中英

PyDbg中的線程切換

[英]Thread-Switching in PyDbg

我曾嘗試將其發布在反向工程堆棧交換中,但我認為我會在此處交叉發布以提高可見性。

我在從調試一個線程切換到pydbg中的另一個線程時遇到麻煩。 我在多線程方面沒有太多經驗,所以我希望我只是缺少一些明顯的東西。

基本上,我想暫停所有線程,然后在一個線程中開始單步執行。 就我而言,有兩個線程。

首先,我暫停所有線程。 然后,我在恢復線程2時在EIP所在的位置設置一個斷點。 (通過使用IDA確認此位置)。 然后,像在任何其他上下文中一樣啟用單步執行,然后恢復線程2。

但是,pydbg似乎沒有捕獲斷點異常! 線程2似乎恢復了,即使必須到達該地址,也沒有跡象表明pydbg正在捕獲斷點異常。 我在pydbg的內部斷點處理程序中包含了“ print“ HIT BREAKPOINT”,並且在恢復線程2之后似乎從未調用過該命令。

我不太清楚下一步該怎么做,所以任何建議都值得贊賞!

    dbg.suspend_all_threads()
    print dbg.enumerate_threads()[0]
    oldcontext = dbg.get_thread_context(thread_id=dbg.enumerate_threads()[0])
    if (dbg.disasm(oldcontext.Eip) == "ret"):
        print disasm_at(dbg,oldcontext.Eip)
        print "Thread EIP at a ret"
        addrstr = int("0x"+(dbg.read(oldcontext.Esp + 4,4))[::-1].encode("hex"),16)
        print hex(addrstr)
        dbg.bp_set(0x7C90D21A,handler=Thread_Start_bp_Handler)
        print dbg.read(0x7C90D21A,1).encode("hex")
    dbg.bp_set(oldcontext.Eip + dbg.instruction.length,handler=Thread_Start_bp_Handler)
    dbg.set_thread_context(oldcontext,thread_id=dbg.enumerate_threads()[0])
    dbg.context = oldcontext
    dbg.resume_thread(dbg.enumerate_threads()[0])
    dbg.single_step(enable=True)
    return DBG_CONTINUE

對不起,“魔術數字”,但據我所知它們是正確的。

你的一個問題是,你通過線程2嘗試單步,你僅指線程1中的代碼:

dbg.enumerate_threads()[0] # <--- Return handle to the first thread.

此外,您發布的代碼無法反映腳本的完整結構,因此很難判斷您是否有其他錯誤。 您還嘗試在可分解指令的子分支中設置斷點,這在邏輯上對我來說沒有多大意義。 讓我嘗試解釋我所知道的,並有組織地進行布置。 這樣,您可以回顧一下代碼,重新考慮並更正它。

讓我們從使用pydbg調試應用程序的基本框架開始:

  1. 創建調試器實例
  2. 附加到過程
  3. 設置斷點
  4. 運行
  5. 斷點被擊中-處理它。

它看起來像這樣:

from pydbg import *
from pydbg.defines import *

# This is maximum number of instructions we will log
MAX_INSTRUCTIONS = 20

# Address of the breakpoint
func_address = "0x7C90D21A"

# Create debugger instance
dbg = pydbg()

# PID to attach to
pid = int(raw_input("Enter PID: "))

# Attach to the process with debugger instance created earlier.
# Attaching the debugger will pause the process.
dbg.attach(pid)

# Let's set the breakpoint and handler as thread_step_setter,
# which we will define a little later...
dbg.bp_set(func_address, handler=thread_step_setter)

# Let's set our "personalized" handler for Single Step Exception
# It will get triggered if execution of a thread goes into single step mode.
dbg.set_callback(EXCEPTION_SINGLE_STEP, single_step_handler)

# Setup is done. Let's run it...
dbg.run() 

現在有了基本結構,讓我們為斷點和單步定義我們的個性化處理程序。 下面的代碼段定義了我們的“自定義”處理程序。 當斷點命中時,我們將遍歷線程並將它們設置為單步模式。 反過來,它將觸發單步異常,我們將處理並反匯編MAX_INSTRUCTIONS條指令:

def thread_step_setter(dbg):
    dbg.suspend_all_threads()
    for thread_id in dbg.enumerate_threads():
        print "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)

    # Resume execution, which will pass control to step handler
    dbg.resume_all_threads()

    return DBG_CONTINUE

def single_step_handler(dbg):
    global total_instructions
    if instructions == MAX_INSTRUCTION:
        dbg.single_step(False)
        return DBG_CONTINUE
    else:
        # Disassemble the instruction
        current_instruction = dbg.disasm(dbg.context,Eip)
        print "#%d\t0x%08x : %s" % (total_instructions, dbg.context.Eip, current_instruction)
        total_instructions += 1
        dbg.single_step(True)

    return DBG_CONTINUE

披露者:我不保證上面的代碼在復制粘貼后也能正常工作。 我打了出來,還沒有測試。 但是,如果掌握了基本知識,則可以輕松地修復小的語法錯誤。 如果有的話,我深表歉意。 我目前沒有能力或時間對其進行測試。

我真的希望它能對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM