zoukankan      html  css  js  c++  java
  • 使用VS调试时,被调试进程如何被断下来的。

    不是什么新鲜的东西,很多书上写的非常详细了,不过有人问到,简要的扯下这个VS如何断下进程的。

    ++++++++++++++++++++++++++

    当用VS的时候,按下F10后,为什么能够停在程序的入口处呢?

    这个问题首先从windows API CreateProcess的Process Creation Flags说起。如果在创建进程的时候加了这个DEBUG_PROCESS这个flag. 那么进程环境块(Process environment block, 简称PEB)中的BeingDebugged设为1. 如果用Windbg的命令!peb来看的话
    0:000> !peb
    PEB at 7ffd8000
        InheritedAddressSpace:    No
        ReadImageFileExecOptions: No
        BeingDebugged:            Yes <== 这个是yes.

    下一步是LdrpInitializeProcess函数被调用来初始化进程的时候,这个函数会去检查BeingDebugged这个位,如果为1的话,就会调用函数ntdll!DbgBreakPoint这个函数。
    比如说用windbg来开始调试notepad.exe的话,首先断下来的地方在ntdll!DbgBreakPoint函数里
    0:000> kL
    ChildEBP RetAddr  
    0007fb1c 7c940442 ntdll!DbgBreakPoint
    0007fc94 7c9210af ntdll!LdrpInitializeProcess+0xffa
    0007fd1c 7c90e457 ntdll!_LdrpInitialize+0x183
    00000000 00000000 ntdll!KiUserApcDispatcher+0x7
    这个函数非常简单,只有一个int 3指令。
    ntdll!DbgBreakPoint:
    7c90120e cc              int     3
    7c90120f c3              ret
    这里是任何debuger第一次断下来进程的地方。无论是windbg还是VS.
    在这个时候notepad.exe的binary已经被load到内存里面了,但是还没有开始执行。这个时候VS就可以加载符号文件,并且知道用户写的代码的入口在什么地方。于是在入口处设下一个断点,然后直接恢复进程的执行,而用户并不会察觉到其实VS debuger已经中断过进程一次了,而是直接发现程序停在了main处。
    哪么调试器的attach功能,和break当前被调试的进程又是如何实现的呢?程序已经跑起来了,这个时候可能没有被设置任何一个断点。
    这个是利用Windows API CreateRemoteThread来实现的。调试器会调用这个函数在目标进程中创建一个线程,这个线程执行的代码如下:
    00adffc8 7c951e40 ntdll!DbgBreakPoint
    00adfff4 00000000 ntdll!DbgUiRemoteBreakin+0x2d
    还是ntdll!DbgBreakPoint这个函数,由于这个函数里面有个int 3指令。CPU执行到了int 3指令的时候就会触发异常处理,最终debuger会处理这个异常,并且把进程中的所有线程挂起。
    在windbg中可以看到notepad.exe被断下来以后有2个线程:
    0:001> ~*
       0  Id: 4b8c.3dd4 Suspend: 1 Teb: 7ffde000 Unfrozen
          Start: notepad!WinMainCRTStartup (0100739d) 
          Priority: 0  Priority class: 32  Affinity: 3
    .  1  Id: 4b8c.4c14 Suspend: 1 Teb: 7ffdd000 Unfrozen
          Start: ntdll!DbgUiRemoteBreakin (7c951e13) 
          Priority: 0  Priority class: 32  Affinity: 3
    线程0就是notepad本身的main thread.
    线程1就是远程创建的线程。
    当然在VS debuger里面不会看到ntdll!DbgBreakPoint这个函数,因为VS比较友好,会自动把当前处理了的线程切换到main thread上面。
  • 相关阅读:
    SQL Server 2005 System Views Map
    SQL语句实现移动数据库文件
    重写系统存储过程:sp_spaceused
    MSSQL2005中的架构与用户
    根据时间段计算有n年n月n天
    Linux中的环境变量 (转)
    计算工龄,格式为n年n月n天
    学习递归CTE
    分区表应用例子
    根据备份文件直接还原数据库
  • 原文地址:https://www.cnblogs.com/aoaoblogs/p/2115180.html
Copyright © 2011-2022 走看看