2011-04-10, 15:43 下午 一鱼之歌 注册: 2009-02-10 发 贴: 36 硬件断点的疑惑 下硬件断点我们知道是对drx寄存器做修改。例如我要下一个执行断点,就简单来说就是把这个执行地址加载到drx寄存器中,并修改相关位。 但是细想实现,又别有一翻意思。。 我的问题:在调试r3程序中,想下一个这样的断点时,我的想法就是必须要对这个进程的所有线程修改寄存器,因为每个线程都有自己的一份寄存器。我这个想法对吗?一个佐证例子就是 修改相关寄存器时必须使用SetThreadContext函数,而这个函数是必须提供一个线程句柄的,说明是以线程为单位。 2。如果上述成立,那在内核中呢?我的一个同事,他在内核中下一个执行断点的时候,就只是简单的mov drx,xxxxx。并不牵扯到什么线程,这又是为何呢? IP 地址: 已记录 报告 2011-04-10, 17:38 下午 Raymond 注册: 2005-12-19 发 贴: 1,054 Re: 硬件断点的疑惑 具体实现是与调试器相关的,以WinDBG为例,用户态时,是针对所有线程的,没错。 内核代码可以直接访问DR寄存器,因此是可以直接用mov指令设置断点,不知道你的疑问在哪里? IP 地址: 已记录 报告 2011-04-11, 10:11 上午 wrong 注册: 2011-01-07 发 贴: 66 Re: 硬件断点的疑惑 他的问题就是为什么调试R3,是针对线程的,而R0的程序,就没有线程了。 这2个问题本质都是一样的,因为断点最终会放在DR中去,只不过前者是OS切换线程时做的,因此只对目标线程起作用。而后者可能是调试器直接做的,所以对所有线程起作用。 IP 地址: 已记录 报告 2011-04-11, 10:15 上午 一鱼之歌 注册: 2009-02-10 发 贴: 36 Re: 硬件断点的疑惑 就是楼上朋友的意思,我就是不明白这里。断点的时候CPU不是看寄存器吗?可是每切换一个线程都会重新加载寄存器(包括drx),难道在内核中就没了对应线程的概念? IP 地址: 已记录 报告 2011-04-11, 12:37 下午 wrong 注册: 2011-01-07 发 贴: 66 Re: 硬件断点的疑惑 其实我上面解释过了,你还没有明白。 每切换一个线程都会重新加载寄存器(包括drx),正是如此,这就是线程上下文的作用啊。 内核模式下,也有线程的概念。不过调试器可以直接写DR了,不一定非要写线程上下文了。这取决于调试器的实现。 IP 地址: 已记录 报告 2011-04-11, 14:25 下午 一鱼之歌 注册: 2009-02-10 发 贴: 36 Re: 硬件断点的疑惑 看来我脑子转不过来了。我的理解是硬件断点和调试器无关 这是CPU级实现的,而调试器只是在int的时候接收到消息并处理而已。 所以我就觉得当你在内核中mov修改drx的时候。当切换了线程后,为什么这个修改后的drx对后面的线程还有效呢?后面的线程不是已经使用它之前保存的drx覆盖了drx原来的值吗? IP 地址: 已记录 报告 2011-04-12, 09:31 上午 wrong 注册: 2011-01-07 发 贴: 66 Re: 硬件断点的疑惑 用户模式下你应该没有问题了吧。因为断点只对当前线程有效的。 关于内核模式,我是这么理解的,内核空间只有一个,不管线程怎么切换,切换的都是用户态代码,至于为什么 “切换了线程后,为什么这个修改后的drx对后面的线程还有效”,我也有点胡涂了。:) IP 地址: 已记录 报告 2011-04-12, 21:14 下午 一鱼之歌 注册: 2009-02-10 发 贴: 36 Re: 硬件断点的疑惑 呵呵,是啊,这玩意咋看,好像原理很容易懂,不过要深入实现又觉得奇怪了。 等张老师。。。。 IP 地址: 已记录 报告 2011-04-12, 22:27 下午 Thomson 注册: 2008-07-03 发 贴: 205 Re: 硬件断点的疑惑 能看到在kernel 里面直接改的register后,断点在kernel里面所有线程有都效吗? IP 地址: 已记录 报告 2011-04-14, 09:11 上午 一鱼之歌 注册: 2009-02-10 发 贴: 36 Re: 硬件断点的疑惑 可以啊。。 张老师怎么不来解释下。。求解。。。 IP 地址: 已记录 报告 2011-04-16, 11:00 上午 一鱼之歌 注册: 2009-02-10 发 贴: 36 Re: 硬件断点的疑惑 囧,,,张老师这么忙。。 IP 地址: 已记录 报告 2011-04-19, 22:52 下午 Raymond 注册: 2005-12-19 发 贴: 1,054 Re: 硬件断点的疑惑 抱歉各位,最近实在有点忙 内核断点的信息是保存在每个CPU的处理器控制区的,具体来说是_KPRCB结构的ProcessorState字段的SpecialRegisters字段: +0x2cc SpecialRegisters : _KSPECIAL_REGISTERS +0x000 Cr0 : Uint4B +0x004 Cr2 : Uint4B +0x008 Cr3 : Uint4B +0x00c Cr4 : Uint4B +0x010 KernelDr0 : Uint4B +0x014 KernelDr1 : Uint4B +0x018 KernelDr2 : Uint4B +0x01c KernelDr3 : Uint4B +0x020 KernelDr6 : Uint4B +0x024 KernelDr7 : Uint4B 每当CPU从用户模式切换到内核模式执行时,内核的代码会从上述字段中加载调试寄存器的值,放到物理CPU中,因为KPRCB是针对CPU的,所以无线程区别... IP 地址: 已记录 报告 2011-04-20, 00:15 上午 一鱼之歌 注册: 2009-02-10 发 贴: 36 Re: 硬件断点的疑惑 原来如此,谢谢张老师, 如果是内核回到用户模式的话,这几个寄存器就是从栈中读取的是吗? IP 地址: 已记录 报告 2011-04-21, 10:44 上午 wrong 注册: 2011-01-07 发 贴: 66 Re: 硬件断点的疑惑 总算明白了。内核模式下实际上还是有一份相当于全局的数据结构在起作用。 在用户态下,硬件断点是进程级别的,同时修改了所有线程的上下文。 IP 地址: 已记录 报告 高端调试 » 软件调试 » Windows内核调试 » Re: 硬件断点的疑惑请选择 论坛首页|- 论坛搜索 |- 热门主题|- 未回复的主题用户选项 |- 登录 |- 注册|- 找回密码软件调试 |- Windows内核调试|- C/C++本地代码调试 |- .Net程序调试|- 脚本程序调试 |- Java程序调试|- Linux内核调试 |- 《程序员》杂志调试专栏|- WinDbg |- GDB|- 远程调试|- 调试ACPI和BIOS |- 特殊的调试任务|- 转储分析内核探秘 |- Windows内核|- Linux内核系统架构|- CPU架构 |- PCI/PCI Express架构程序人生 |- 软件物语|- 社区活动|- 名人逸事 联盟论坛|- 欢迎使用CnForums没有银弹|- BUG也精彩 |- 豆腐工程|- 软件圈里十大怪Windows Vista|- 用调试利剑剖析VISTA内幕 |- 老专家如何破解新问题|- 我的电脑谁说了算? |- 资源 Office开发|- Visio驱动程序开发|- Windows驱动开发|- Linux驱动开发|- Windows CE驱动开发 用户态开发 |- Windows本地代码(native)高级开发|- Web应用开发 |- WinFX和.Net|- Office开发 本站建设|- 高端调试团队|- 版面布局|- 活动建议 |- 网站维护64位计算 |- 64-bit Windows|- 64-bit CPU 图书|- 《软件调试》的示例程序|- 《软件调试》的工具|- 《软件调试》书友|- 《软件调试》答疑|- 《软件调试》勘误和意见|- 《格蠹汇编》