• windbg调试命令8(bp、bu、bm、bl、bc、ba、be、bd)


    以下以skinhgy为例,windbg附加运行

    1.

    bp 命令是在某个地址下断点, 可以 bp 0x7783FEB 也可以 bp MyApp!SomeFunction

    对于后者,WinDBG 会自动找到MyApp!SomeFunction 对应的地址并设置断点。 但是使用bp的问题在于:

    1)当代码修改之后,函数地址改变,该断点仍然保持在相同位置,不一定继续有效;

     2)WinDBG 不会把bp断点保存工作空间中

    bp  Address或bp 伪寄存器或bp符号名称:

    0:000> x Simple1Demo!CSimple1DemoApp::InitInstance  
    1. 00640080 Simple1Demo!CSimple1DemoApp::InitInstance (void)  
    2. 0:000> bp 00640080   
    3. 0:000> bl  
    4.  0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance  
    5. 0:000> x Kernel32!LoadLibraryW  
    6. 7c80aeeb kernel32!LoadLibraryW = <no type information>  
    7. 0:000> bp Kernel32!LoadLibraryW  
    8. 0:000> bl  
    9.  0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance  
    10.  1 e 7c80aeeb     0001 (0001)  0:**** kernel32!LoadLibraryW  
    11. 0:000> bp $exentry  
    12. 0:000> bl  
    13.  0 e 00640080     0001 (0001)  0:**** Simple1Demo!CSimple1DemoApp::InitInstance  
    14.  1 e 7c80aeeb     0001 (0001)  0:**** kernel32!LoadLibraryW  
    15.  2 e 0061c895     0001 (0001)  0:**** Simple1Demo!ILT+14480(_wWinMainCRTStartup)  
    上例说明三种用法作用是一样的,都是bp Address(windbg内部会换成符号文件对应的地址,或伪寄存器的地址)

    bp /1 Address表示该断点为一次性断点,有点类似于F4作用于OD,一旦激活就自动删除了:

    如bp /1 00640080

    bp Address Passes表示指定断点激活之前要忽略的次数

    默认情况下,断点在第一次执行断点位置的代码时被激活。这种默认情况和把Passes 设置为1是一样的。要使得断点在程序至少执行该代码一次之后才激活,可以将这个值设置为2或更大。例如,值为2时,使得断点在第二次执行到该代码时被激活。该参数创建一个在每次执行断点处的代码时被减少1的计数器。要查看Passes 计数器的初始值和当前值,使用bl (Breakpoint List)Passes 仅当程序响应g (Go)命令并执行通过断点时才减少。单步或跟踪(tracing)通过它是不会减少的。当Passes 到达1时,可以通过清除并重设断点来重置它。

    我们来试试,用bc把以前断点都删除,再设置在第三次运行LoadLibraryW时激活该处断点

    0:000> bc*  
    1. 0:000> bl  
    2. 0:000> bp 7c80aeeb 3  
    3. 0:000> bl  
    4.  0 e 7c80aeeb     0003 (0003)  0:**** kernel32!LoadLibraryW  

    我们注意到这个断点显示的是0003 (0003) F5运行:

    0:000> g  
    1. Breakpoint 0 hit  
    2. eax=00000002 ebx=7ffdc000 ecx=00000000 edx=00a8660c esi=0263f76e edi=0263f6f2  
    3. eip=7c80aeeb esp=0012fd68 ebp=0012fdb0 iopl=0         nv up ei pl nz na po nc  
    4. cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202  
    5. kernel32!LoadLibraryW:  
    6. 7c80aeeb 8bff            mov     edi,edi  
    7. 0:000> bl  
    8.  0 e 7c80aeeb     0001 (0003)  0:**** kernel32!LoadLibraryW  

    我们注意到这个断点现在显示的是0001 (0003),表示前面忽略了两次,

    bu 命令是针对某个符号下断点。 比如 bu MyApp!SomeFunction 。 在代码被修改之后, 该断点可以随着函数地址改变而自动更新到最新位置。  而且bu 断点会保存在WinDbg工作空间中, 下次启动 Windbg 的时候该断点会自动设置上去。另外,在模块没有被加载的时候,bp 断点会失败(因为函数地址不存在),而bu 断点则可以成功。 新版的WinDBG中 bp失败后会自动被转成bu

    bm 命令也是针对符号下断点。 但是它支持匹配表达式。 很多时候你下好几个断点。 比如,把MyClass 所有的成员函数都下断点:bu MyApp!MyClass::* , 或者把所有以CreateWindow开头的函数都下断点:bu user32!CreateWindow*

    这个函数比较有用,比如我想对Draw开头的函数都下断点:

    0:000> bc*  
    1. 0:000> bl  
    2. 0:000> bm *!draw*  
    3.   1: 00695930 @!"Simple1Demo!DrawState"  
    4.   2: 0175c790 @!"SkinLog!DrawState"  
    5.   3: 019f65d0 @!"SkinScroll!DrawState"  
    6.   4: 10119d10 @!"SkinHgy!DrawState"  
    7. 0:000> bl  
    8.  1 e 00695930     0001 (0001)  0:**** Simple1Demo!DrawState  
    9.  2 e 0175c790     0001 (0001)  0:**** SkinLog!DrawState  
    10.  3 e 019f65d0     0001 (0001)  0:**** SkinScroll!DrawState  
    11.  4 e 10119d10     0001 (0001)  0:**** SkinHgy!DrawState  
     

    bl(breakpoint list)命令列出已存在的断点的信息

    对于每个断点,该命令显示以下信息:

    • 断点ID。该ID是一个可以在其他命令中引用这个断点的十进制数字。
    • 断点状态。它可以是e (启用) 或d (禁用)。
    • 如果出现字母"u",说明断点是未定的。即,该断点中的符号引用还没有和任何当前已加载的模块匹配。
    • 断点位置的虚拟地址或符号表达式。如果启用了源码行号加载,bl 命令显示文件和行号信息而不是地址偏移。如果该断点未定,则它的地址会被省略并出现在列表末尾。
    • (仅数据断点) 数据断点的类型和大小信息会显示出来。类型可以是e (执行)、 r (读/写)、w (写)或 i (输入/输出)。类型后面是以字节为单位的大小。关于这种类型断点的更多信息,查看ba (Break on Access)
    • 断点被激活前需要忽略的剩余次数,后面是在圆括号中的初始次数。(这种断点的更多信息,查看bp, bu, bm (Set Breakpoint)中对Passes参数的说明。)
    • 关联的进程和线程。如果线程是用三个星号("***")表示的,说明这不是一个指定线程的断点。
    • 符合断点地址的模块和函数以及偏移。如果是未定断点,这里会用括号括起来的断点地址替代。如果断点设置在合法地址,但是没有符号信息,这个域为空。
    • 该断点触发时要自动执行的命令。这个命令以引号括起来。

    bc(breakpoint clear) 命令在系统中移除先前设置的断点。

    使用星号(*)来指定所有断点

    最后介绍下ba断点

    ba 命令就是针对数据下断点的命令, 该断点在指定内存被访问时触发。 命令格式为

    ba Access Size [地址]

    Access 是访问的方式, 比如 e (执行), r (读/写), w (写)

    Size 是监控访问的位置的大小,以字节为单位。 值为 1、2或4,还可以是 8(64位机)。

    比如要对内存0x0483DFE进行写操作的时候下断点,可以用命令 ba w4 0x0483DFE

    AccessSize 之间不能加入空格

    0:000> bc*  

    1. 0:000> ba r4 00a76748    
    2. 0:000> bl  
    3.  0 e 00a76748 r 4 0001 (0001)  0:**** Simple1Demo!`string'  


    be 打开断点

    bd 关闭断点

  • 相关阅读:
    UE4 Abc 批量导入
    UE4源码摘录(424)
    JZ10 矩形覆盖
    JZ27 字符串的排列
    JZ66 机器人的运动范围
    JZ65 矩阵中的路径
    JZ12 数值的整数次方
    JZ37 数字在升序数组中出现的次数
    JZ6 旋转数组的最小数字
    JZ67 剪绳子
  • 原文地址:https://www.cnblogs.com/guanlaiy/p/2827391.html
Copyright © 2020-2023  润新知