我试过在逆向工程堆栈交换中发布这个,但我想我会在这里交叉发布它以获得更多可见性。
我在pydbg中从调试一个线程切换到另一个线程时遇到问题。我对多线程没有多少经验,所以我希望我只是遗漏了一些明显的东西。
基本上,我想暂停所有线程,然后在一个线程中开始单步执行。在我的例子中,有两个线程。
首先,我暂停所有线程。然后,我在线程2恢复时EIP将在的位置设置断点。 (此位置通过使用IDA确认)。然后,我在任何其他上下文中启用单步执行,并恢复线程2。
然而,pydbg似乎没有抓住断点异常!线程2似乎恢复,即使它必须击中该地址,也没有迹象表明pydbg正在捕获断点异常。我在pydbg的内部断点处理程序中包含了一个“打印”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
对于“魔术数字”感到抱歉,但就我所知,它们是正确的。
答案 0 :(得分:1)
您的一个问题是,您尝试单步执行 Thread2 ,并且只在代码中引用 Thread1 :
dbg.enumerate_threads()[0] # <--- Return handle to the first thread.
此外,您发布的代码并不反映您的脚本的完整结构,这使得很难判断您是否有其他错误。你也试着在sub-brach中设置断点来反汇编你的指令,这在逻辑上对我来说没什么意义。让我试着解释我所知道的,并以有组织的方式进行解释。这样你就可以回顾你的代码,重新思考并纠正它。
让我们从使用pydbg调试应用程序的基本框架开始:
这就是它的样子:
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
披露:我不保证上面的代码在复制和粘贴时都能正常工作。我输入了它并没有测试过它。但是,如果获得基本的理解,可以很容易地修复小的语法错误。如果我有任何问题,我会提前道歉。我目前没有办法或时间来测试它。
我真的希望它可以帮助你。