转载自: https://www.zhihu.com/question/52625624 旅人的回复

作者:旅人
链接:https://www.zhihu.com/question/52625624/answer/131557817
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

首先是关于内存断点的一些前置知识:
1.在windows系统上,内存是一页一页的,也就是说并不是0x00000000~0x7FFFFFFF(0xFFFFFFFF)中任何一个地址都是可以访问的,不然每个程序都有真正的2g内存太可怕了。实际情况是,你程序申请了一块0x2000的内存,这时候windows内核经过一系列处理,告诉你,我在某个地址上(比如说0x00500000)给你设置了0x2000的内存,你可以拿去用了。这时候0x00500000~0x00502000这块内存你才可以访问,你要是尝试访问0x00502001依然会出错,因为这个地址根本不存在。

2.每个内存页都是有属性的,比如你申请时可以要求当前页面里的内容不可作为代码执行,因为你只是拿来存数据的,如果不这样设置的话可能会遭到恶意利用。(比如说缓冲区溢出攻击)

3.调试器可以先于被调试程序拿到一些系统下发的消息,比如说被调试程序中出现了异常。

------------------------------------------------
现在可以说说内存断点都做了些什么了。

内存断点的实现方式是将你欲下断地址所在的内存页增加一个名为PAGE_NOACCESS的属性,这个属性会把当前内存页设为禁止任何形式的访问,如果进行访问会触发一个内存访问异常。在这同时,od开始捕获目标程序中出现的这个异常,并判断触发这个异常的位置是否跟你下断的地址相同,如果相同则内存断点触发,暂停被调试程序的运行,否则放行。

这就是内存断点的基本原理,补充一些相关的东西:
1.内存断点很消耗资源,因为PAGE_NOACCESS属性一设置就是一整个内存页无法访问,那么当程序访问该内存页中非断点地址的内容同样会触发异常,这时od收到异常后需要进行特殊处理,临时放行,非常消耗资源,甚至这使得内存断点在调试很多大型程序时慢到近乎不可用。
2.虽然内存断点的效率经常很不理想,但是因为仅仅是修改了一个内存属性,所以内存断点可以下数量非常多、单断点范围非常大。这是它的优势。
3.只在写入时断下的内存断点通常是将内存属性设为PAGE_EXECUTE_READ,也就是不可写来实现的。对这种属性的内存进行写操作将会触发异常。
4.关于内存属性相关的知识:https://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx
------------------------------------------------
------------------------------------------------
接下来是硬件断点的前置知识。

1.现代cpu为程序调试提供了8个寄存器,名为DRx.

2.调试器可以轻易读写被调试程序的这8个寄存器,而被调试程序不容易读写也通常不需要读写。

3.DR0~DR3四个寄存器用来存放欲下断的地址,DR4,DR5这两个保留, DR6和DR7用来控制断点的大小和触发断点的时机。(比如说大小一个byte,触发时机为写入时)
------------------------------------------------
硬件断点就不需要od做太多事情了,它只需要把用户的需求转换一下格式,写入被调试程序的DRx系列的寄存器中,并等待系统发来的消息就行了。(我不记得这个消息是不是也是一个异常消息了,年代久远太久不碰)
当od收到了消息就暂停目标程序,你就知道程序断下了。

关于硬件断点:
1.寄存器数量的限制导致硬件断点最多只能同时存在4个,并且od在特定设置或者插件的影响下可能内部还会占用一两个用来辅助程序调试,导致可用数量十分有限。
2.不仅硬件断点数量不多,在32位程序中,每个硬件断点最大范围是4个字节,这也经常不太够用。
3.由于cpu的直接支持,硬件断点的效率是非常高的,给一个程序设置了硬件断点,在不触发的情况下,不会有肉眼可见的效率影响,毕竟只是写了个寄存器而已。

--------------------------------------------------------------------------
总结,内存断点通过修改内存页的属性并捕获异常来间接暂停被调试的程序运行,而硬件断点是由cpu直接提供支持。因为这样,所以内存断点的效率大大低于硬件断点,但内存断点的自由性大于硬件断点,可以下很多很大不用担心硬件限制。通常在调试程序时,能用硬件断点就别用内存断点,太[bi--]卡了。而且内存断点经常下了找不着,而硬件断点od有单独的窗口显示。

Ollydbg中的内存断点和硬件断点的区别的更多相关文章

  1. windbg-bp、 bm、 bu、 bl、 bc、 ba(断点、硬件断点)

    bp bp 命令是在某个地址下断点, 可以 bp 0x7783FEB 也可以 bp MyApp!SomeFunction . 对于后者,WinDBG 会自动找到MyApp!SomeFunction 对 ...

  2. Jlink 软件断点和硬件断点

    调试2440 RAM拷贝至SDRAM遇到的问题 汇编代码主要是初始化一些寄存器,关狗,初始化时钟,初始化存储管理器以便访问内存,然后将SoC上4k RAM数据拷贝至SDRAM,然后在SRAM里面运行, ...

  3. 硬件断点 DrxHook

    硬件断点 DrxHook 硬件断点的实现需要依赖于调试寄存器 DR0~DR7  调试寄存器 DR0~DR3-----调试地址寄存器DR4~DR5-----保留DR6 -----调试状态寄存器 指示哪个 ...

  4. X86逆向10:学会使用硬件断点

    本节课我们将学习硬件断点的使用技巧,硬件断点是由硬件提供给我们的一组寄存器,我们可以对这些硬件寄存器设置相应的值,然后让硬件帮我们断在需要下断点的地址上面,这就是硬件断点,硬件断点依赖于寄存器,这些寄 ...

  5. 为什么NtReadVirtualMemory 硬件断点无法下断

    win7 x64为例 nt!NtReadVirtualMemory ----- nt!MmCopyVirtualMemory NTSTATUS NTAPI MmCopyVirtualMemory(IN ...

  6. 动态链接库中分配内存引起的问题-- windows已在XX.exe中触发一个断点

    动态链接库中分配内存引起的 本文主要是探讨关于在动态链接库分配的内存在主程序中释放所产生的问题,该问题是我在刚做的PJP工程中所遇到的,由于刚碰到之时感动比较诡异(这也是学识不够所致),所以将它写下来 ...

  7. Xcode中使用数据(硬件)断点调试

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在Xcode的GUI界面中只能添加软断点,而无法增加硬断点.但 ...

  8. ring3硬件断点

    4个断点寄存器DR0~DR3用来设置断点的线性地址. DR6为状态寄存器,DR7为控制寄存器. DR4和DR5保留.当CR4.DE==1时,访问DR4和DR5产生#UD异常:IF CR4.DE==0, ...

  9. Lua中如何实现类似gdb的断点调试--04优化钩子事件处理

    在第一篇的01最小实现中,我们实现了一个断点调试的最小实现,在设置钩子函数时只加了line事件,显然这会对性能有很大的影响.而后来两篇02通用变量打印和03通用变量修改及调用栈回溯则是提供了一些辅助的 ...

随机推荐

  1. HBase学习笔记2 - HBase shell常用命令

    转载请标注原链接:http://www.cnblogs.com/xczyd/p/6639397.html 扫表的时候限定行数 scan } 即为扫表的时候,限定只输出五条数据 ============ ...

  2. 推荐一个免费的在线IDE和终端

    墙裂推荐!支持众多语言,方便学习,测试,地址如下 https://www.tutorialspoint.com/codingground.htm

  3. NSTimer应用

    NSTimer应用 在参与项目开发中遇到了NSTimer的应用,虽然我负责的模块内只用到了一小部分,但我觉得还是有必要拿出来好好琢磨一下. 一.概念(来自官方描述) 官网上最新的定义是“A timer ...

  4. Homestead的安装配置

    laravel学院教程 : http://laravelacademy.org/post/7658.html 参考博文:https://blog.csdn.net/xyxjn/article/deta ...

  5. scrapy基本使用

    Scrapy笔记 安装scrapy框架 安装scrapy: 通过pip install scrapy 如果是在Windows上面,还需要安装pypiwin32,如果不安装,那么以后运行scrapy项目 ...

  6. PTA——字符串逆序

    PTA 7-59 字符串逆序 #include<stdio.h> #include<string.h> #define N 81 int main() { int i; cha ...

  7. javascript第一个作业之网页计算器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. ie8的input的placeholder不显示的解决bug

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  9. Python练习六

    1.写函数,计算传入字符串中[数字].[字母].[空格].以及[其他]的个数,并返回结果. def day06_1(s): dic = {'num': 0, 'alpha': 0, 'space': ...

  10. 经典问题----最短路径(Floyd弗洛伊德算法)(HDU2066)

    问题简介: 给定T条路,S个起点,D个终点,求最短的起点到终点的距离. 思路简介: 弗洛伊德算法即先以a作为中转点,再以a.b作为中转点,直到所有的点都做过中转点,求得所有点到其他点的最短路径,Flo ...