【问题标题】:Thread-Switching in PyDbgPyDbg 中的线程切换
【发布时间】:2013-10-26 01:21:07
【问题描述】:

我已尝试在逆向工程堆栈交换中发布此内容,但我想我会在此处交叉发布以提高知名度。

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

对“幻数”感到抱歉,但据我所知,它们是正确的。

【问题讨论】:

    标签: python windows multithreading reverse-engineering pydbg


    【解决方案1】:

    您的一个问题是您尝试单步执行 Thread2 并且您只在代码中引用 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() 
    

    现在有了基本结构,让我们为断点和单步定义我们的个性化处理程序。下面的代码 sn-p 定义了我们的“自定义”处理程序。当断点命中时会发生什么,我们将遍历线程并将它们设置为单步模式。它会反过来触发单步异常,我们将处理和反汇编 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
    

    Discloser:我不保证上面的代码在复制和粘贴后会起作用。我打出来了,没有测试。但是,如果获得了基本的理解,那么小的语法错误可以很容易地修复。如果我有任何问题,我会提前道歉。我目前没有办法或时间来测试它。

    希望对你有所帮助。

    【讨论】:

      猜你喜欢
      • 2016-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 2016-02-06
      相关资源
      最近更新 更多