PyDbg中的线程切换

2024-05-15 11:07:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着在反向工程堆栈交换中发布这个,但是我想我应该交叉发布在这里以获得更多的可见性。在

在pydbg中,我无法从一个线程调试到另一个线程。我对多线程没有太多的经验,所以我希望我只是错过了一些显而易见的东西。在

基本上,我想挂起所有线程,然后在一个线程中开始单步执行。在我的例子中,有两个线程。在

首先,我挂起所有线程。然后,我在线程2恢复时EIP所在的位置设置一个断点。(使用IDA确认该位置)。然后,像在其他上下文中一样启用单步执行,并继续执行线程2。在

但是,pydbg似乎没有捕捉到断点异常!线程2似乎继续运行,即使它必须命中该地址,也没有迹象表明pydbg正在捕获断点异常。我在pydbg的内部断点处理程序中包含了一个“print”命中断点,在恢复线程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

很抱歉“神奇的数字”,但据我所知,它们是正确的。在


Tags: context线程threadprintbphexdbgset
1条回答
网友
1楼 · 发布于 2024-05-15 11:07:58

您的一个问题是,您试图单步执行Thread2,而在代码中只引用Thread1

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

另外,你发布的代码并不能反映你的脚本的完整结构,这使得你很难判断你是否有其他错误。您还试图在分解指令的子分支中设置断点,这在逻辑上对我没有多大意义。让我试着解释一下我所知道的,并把它组织起来。这样你就可以回顾你的代码,重新思考并修正它。在

让我们从使用pydbg调试应用程序的基本框架开始:

  1. 创建调试器实例
  2. 附加程序
  3. 设置断点
  4. 快跑
  5. 断点被击中-处理它。在

这就是它的样子:

^{pr2}$

现在有了基本结构,让我们定义断点和单步执行的个性化处理程序。下面的代码片段定义了我们的“自定义”处理程序。当断点命中时,我们将遍历线程并将其设置为单步模式。它又会触发单步异常,我们将处理和反汇编最大指令数:

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

披露方:我不保证以上代码复制粘贴后能正常工作。我把它打印出来,还没有测试过。但是,如果有了基本的理解,小的句法错误就可以很容易地得到纠正。如果我有什么要道歉的话。我现在没有办法或时间来测试它。在

我真的希望它能帮到你。在

相关问题 更多 >