2013-10-17 59 views
0

我已經嘗試在反向工程堆棧交換中發佈此內容,但我認爲我會在此處交叉發佈以獲取更多可見性。PyDbg中的線程切換

我無法在pydbg中從一個線程切換到另一個線程。我沒有太多的多線程經驗,所以我希望我只是錯過了一些明顯的東西。

基本上,我想暫停所有線程,然後在一個線程中啓動單步執行。在我的情況下,有兩個線程。

首先,我暫停所有線程。然後,當線程2恢復時,我會在EIP所在的位置設置一個斷點。 (此位置通過使用IDA進行確認)。然後,我在任何其他情況下啓用單步執行,並恢復線程2.

但是,pydbg似乎沒有捕獲到斷點異常!線程2似乎恢復,即使它必須命中該地址,沒有跡象表明pydbg捕捉到斷點異常。我收錄了「打印‘HIT斷點’pydbg內部的斷點處理程序中,而且似乎永遠不會恢復線索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 

很抱歉的「幻數」,但他們是正確的,據我可以告訴。

回答

1

你的一個問題是,你可以通過線程2嘗試單步,你僅指Thread1在您的代碼:

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 

披露:我不保證,如果複製和粘貼上面的代碼將工作。我輸入並沒有測試過。但是,如果獲得了基本的理解,則可以很容易地修復小的語法錯誤。如果我有任何問題,我很抱歉。我目前沒有辦法或時間去測試它。

我真的希望它能幫助你。