windbg-bp、 bm、 bu、 bl、 bc、 ba(断点、硬件断点)
bp
bp 命令是在某个地址下断点, 可以 bp 0x7783FEB 也可以 bp MyApp!SomeFunction 。
对于后者,WinDBG 会自动找到MyApp!SomeFunction 对应的地址并设置断点。 但是使用bp的问题在于:
1)当代码修改之后,函数地址改变,该断点仍然保持在相同位置,不一定继续有效;
2)WinDBG 不会把bp断点保存工作空间中
bp Address或bp 伪寄存器或bp符号名称:
0:000> x Simple1Demo!CSimple1DemoApp::InitInstance
00640080 Simple1Demo!CSimple1DemoApp::InitInstance (void)
:> bp
:> bl
e () :**** Simple1Demo!CSimple1DemoApp::InitInstance
:> x Kernel32!LoadLibraryW
7c80aeeb kernel32!LoadLibraryW = <no type information>
:> bp Kernel32!LoadLibraryW
:> bl
e () :**** Simple1Demo!CSimple1DemoApp::InitInstance
e 7c80aeeb () :**** kernel32!LoadLibraryW
:> bp $exentry
:> bl
e () :**** Simple1Demo!CSimple1DemoApp::InitInstance
e 7c80aeeb () :**** kernel32!LoadLibraryW
e 0061c895 () :**** Simple1Demo!ILT+(_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时激活该处断点
:> bc*
:> bl
:> bp 7c80aeeb
:> bl
e 7c80aeeb () :**** kernel32!LoadLibraryW
我们注意到这个断点显示的是0003 (0003) F5运行:
:> g
Breakpoint hit
eax= ebx=7ffdc000 ecx= edx=00a8660c esi=0263f76e edi=0263f6f2
eip=7c80aeeb esp=0012fd68 ebp=0012fdb0 iopl= nv up ei pl nz na po nc
cs=001b ss= ds= es= fs=003b gs= efl=
kernel32!LoadLibraryW:
7c80aeeb 8bff mov edi,edi
:> bl
e 7c80aeeb () :**** 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开头的函数都下断点:
:> bc*
:> bl
:> bm *!draw*
: @!"Simple1Demo!DrawState"
: 0175c790 @!"SkinLog!DrawState"
: 019f65d0 @!"SkinScroll!DrawState"
: 10119d10 @!"SkinHgy!DrawState"
:> bl
e () :**** Simple1Demo!DrawState
e 0175c790 () :**** SkinLog!DrawState
e 019f65d0 () :**** SkinScroll!DrawState
e 10119d10 () :**** 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 Access Size [地址]
Access 是访问的方式, 比如 e (执行), r (读/写), w (写)
Size 是监控访问的位置的大小,以字节为单位。 值为 1、2或4,还可以是 8(64位机)。
如果Access是e,Size必须是1
比如要对内存0x0483DFE进行写操作的时候下断点,可以用命令 ba w4 0x0483DFE
在Access 和Size 之间不能加入空格
:> bc*
:> ba r4 00a76748
:> bl
e 00a76748 r () :**** Simple1Demo!`string'
有时我们只想让程序断在某个线程上:
可以用:
:> ~ bp Simple1Demo!DrawState
:> bl
e 0134bfc0 () :~ Simple1Demo!DrawState
:> bp Simple1Demo!DrawState
:> bl
e 0134bfc0 () :~ Simple1Demo!DrawState
前面~1 表示只有当指定的线程ID为1执行到达断点的地址上时,调试器才会停止.
在X86下dr0-dr3记录了断点地址值,dr6是断点的状态寄存器,dr7是断点的控制寄存器。
另外,在初始断点命中时,尚不能设置硬件断点,如果设置,会得到如下错误:
:> ba r1 7c92120f
^ Unable to set breakpoint error
The system resets thread contexts after the process
breakpoint so hardware breakpoints cannot be set.
Go to the executable's entry point and set it then.
初始断点后系统会重设线程上下文,因此不能设置硬件断点,建议执行到程序的入口后再设置
:> ba e1 00bc1b3a
breakpoint redefined :> r dr0
dr0=00bc1b3a
windbg-bp、 bm、 bu、 bl、 bc、 ba(断点、硬件断点)的更多相关文章
- Windbg命令学习15(bp bm bu bl bc ba断点)
以下以skinhgy为例,windbg附加运行 1. bp 命令是在某个地址下断点, 可以 bp 0x7783FEB 也可以 bp MyApp!SomeFunction . 对于后者,WinDBG 会 ...
- Windbg 内核态调试用户态程序然后下断点正确触发方法(亲自实现发现有效)
先开启真机内核态kernel调试 !process 0 0 svchost.exe 找到进程cid的地址 然后进入 .process /p fffffa8032be2870 然后 .process ...
- 为什么NtReadVirtualMemory 硬件断点无法下断
win7 x64为例 nt!NtReadVirtualMemory ----- nt!MmCopyVirtualMemory NTSTATUS NTAPI MmCopyVirtualMemory(IN ...
- ring3硬件断点
4个断点寄存器DR0~DR3用来设置断点的线性地址. DR6为状态寄存器,DR7为控制寄存器. DR4和DR5保留.当CR4.DE==1时,访问DR4和DR5产生#UD异常:IF CR4.DE==0, ...
- 硬件断点 DrxHook
硬件断点 DrxHook 硬件断点的实现需要依赖于调试寄存器 DR0~DR7 调试寄存器 DR0~DR3-----调试地址寄存器DR4~DR5-----保留DR6 -----调试状态寄存器 指示哪个 ...
- Xcode中使用数据(硬件)断点调试
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在Xcode的GUI界面中只能添加软断点,而无法增加硬断点.但 ...
- Ollydbg中的内存断点和硬件断点的区别
转载自: https://www.zhihu.com/question/52625624 旅人的回复 作者:旅人链接:https://www.zhihu.com/question/52625624/a ...
- Jlink 软件断点和硬件断点
调试2440 RAM拷贝至SDRAM遇到的问题 汇编代码主要是初始化一些寄存器,关狗,初始化时钟,初始化存储管理器以便访问内存,然后将SoC上4k RAM数据拷贝至SDRAM,然后在SRAM里面运行, ...
- X86逆向10:学会使用硬件断点
本节课我们将学习硬件断点的使用技巧,硬件断点是由硬件提供给我们的一组寄存器,我们可以对这些硬件寄存器设置相应的值,然后让硬件帮我们断在需要下断点的地址上面,这就是硬件断点,硬件断点依赖于寄存器,这些寄 ...
随机推荐
- json jackson
1.引入依赖 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId&g ...
- 『TCP/IP详解——卷一:协议』读书笔记——07
2013-08-20 17:51:49 第三章 IP:网际协议 3.1 引言 IP是TCP/IP协议族中最为核心的协议.所有的TCP.UDP.ICMP和IGMP数据都以IP数据报格式传输.再来看一下图 ...
- 省市区县镇级联数据JS版
前言:网站开发经常会涉及到报名,报名通常就会有地区级联的要求.如下所示.做这个功能就必须要有数据支撑.昨天努力了一天,从网上鼓捣了一份数据.分享下.纯技术性分享,非盈利的.如果有侵权的地方请知会,马上 ...
- 安装SQL Server 2008 R2 Enterprise错误:'' is not a valid login or you do not have permission
今天安装SQL Server时遇到一个恶心的Bug. ------------------------------------------------------------------------- ...
- C#设计模式(8)——桥接模式(Bridge Pattern)
一.引言 这里以电视遥控器的一个例子来引出桥接模式解决的问题,首先,我们每个牌子的电视机都有一个遥控器,此时我们能想到的一个设计是——把遥控器做为一个抽象类,抽象类中提供遥控器的所有实现,其他具体电视 ...
- Windows Phone下的Socket编程
讨论下有关于Windows Phone下的Socket编程方面的知识. Socket就是通常所称的套接字,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过Socket向网络发出请求或者应答 ...
- Java和C#中的接口对比(有你不知道的东西)
1.与Java不同,C#中的接口不能包含字段(Field). 在java中,接口中可以包含字段,但是这些字段隐式地是static和final的.而C#不允许接口中有字段,编译器在编译时就会提示错误(如 ...
- [汇编] 从键盘输入一个一位数字,然后响铃n声
; multi-segment executable file template. data segment ends stack segment dw dup() ends code segment ...
- 不要过早退出循环 while(1){no break}
我们在尝试新的事物的时候,总是会遇到各种各样的困难,不同的人会在碰壁不同的次数之后退出.用程序员喜欢的话来说就是,我们都在for循环,区别在于你是什么情况下break的.有的人退出阈值高,这是能坚持的 ...
- ubuntu14.04中文楷体变默认字体
使用ubuntu以来,最让人头疼的事情就是在英文系统里面使用中文,一般中文字体都很难看,要么有锯齿,要么就是楷体.经过网上搜索找到一堆方法.一个个尝试之后觉得以下方式是最简单有效的. 1.安装font ...