|
|
|
|
|
|
|
Windows内核调试
帖子发起人: 一鱼之歌 发起时间: 2011-04-10 15:43 下午 回复: 13
|
帖子排序:
|
|
|
|
2011-04-10, 15:43 下午
|
一鱼之歌
注册: 2009-02-10
发 贴: 36
|
|
|
下硬件断点我们知道是对drx寄存器做修改。例如我要下一个执行断点,就简单来说就是把这个执行地址加载到drx寄存器中,并修改相关位。
但是细想实现,又别有一翻意思。。
我的问题:在调试r3程序中,想下一个这样的断点时,我的想法就是必须要对这个进程的所有线程修改寄存器,因为每个线程都有自己的一份寄存器。我这个想法对吗?一个佐证例子就是
修改相关寄存器时必须使用SetThreadContext函数,而这个函数是必须提供一个线程句柄的,说明是以线程为单位。
2。如果上述成立,那在内核中呢?我的一个同事,他在内核中下一个执行断点的时候,就只是简单的mov drx,xxxxx。并不牵扯到什么线程,这又是为何呢?
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-10, 17:38 下午
|
格蠹老雷
注册: 2005-12-19
发 贴: 1,303
|
|
|
具体实现是与调试器相关的,以WinDBG为例,用户态时,是针对所有线程的,没错。
内核代码可以直接访问DR寄存器,因此是可以直接用mov指令设置断点,不知道你的疑问在哪里?
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-11, 10:11 上午
|
wrong
注册: 2011-01-07
发 贴: 66
|
|
|
他的问题就是为什么调试R3,是针对线程的,而R0的程序,就没有线程了。
这2个问题本质都是一样的,因为断点最终会放在DR中去,只不过前者是OS切换线程时做的,因此只对目标线程起作用。而后者可能是调试器直接做的,所以对所有线程起作用。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-11, 10:15 上午
|
一鱼之歌
注册: 2009-02-10
发 贴: 36
|
|
|
就是楼上朋友的意思,我就是不明白这里。断点的时候CPU不是看寄存器吗?可是每切换一个线程都会重新加载寄存器(包括drx),难道在内核中就没了对应线程的概念?
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-11, 12:37 下午
|
wrong
注册: 2011-01-07
发 贴: 66
|
|
|
其实我上面解释过了,你还没有明白。
每切换一个线程都会重新加载寄存器(包括drx),正是如此,这就是线程上下文的作用啊。
内核模式下,也有线程的概念。不过调试器可以直接写DR了,不一定非要写线程上下文了。这取决于调试器的实现。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-11, 14:25 下午
|
一鱼之歌
注册: 2009-02-10
发 贴: 36
|
|
|
看来我脑子转不过来了。我的理解是硬件断点和调试器无关
这是CPU级实现的,而调试器只是在int的时候接收到消息并处理而已。
所以我就觉得当你在内核中mov修改drx的时候。当切换了线程后,为什么这个修改后的drx对后面的线程还有效呢?后面的线程不是已经使用它之前保存的drx覆盖了drx原来的值吗?
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-12, 09:31 上午
|
wrong
注册: 2011-01-07
发 贴: 66
|
|
|
用户模式下你应该没有问题了吧。因为断点只对当前线程有效的。
关于内核模式,我是这么理解的,内核空间只有一个,不管线程怎么切换,切换的都是用户态代码,至于为什么
“切换了线程后,为什么这个修改后的drx对后面的线程还有效”,我也有点胡涂了。:)
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-12, 21:14 下午
|
一鱼之歌
注册: 2009-02-10
发 贴: 36
|
|
|
呵呵,是啊,这玩意咋看,好像原理很容易懂,不过要深入实现又觉得奇怪了。
等张老师。。。。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-12, 22:27 下午
|
Thomson
注册: 2008-07-03
发 贴: 211
|
|
|
能看到在kernel 里面直接改的register后,断点在kernel里面所有线程有都效吗?
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-14, 09:11 上午
|
一鱼之歌
注册: 2009-02-10
发 贴: 36
|
|
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-16, 11:00 上午
|
一鱼之歌
注册: 2009-02-10
发 贴: 36
|
|
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
2011-04-19, 22:52 下午
|
格蠹老雷
注册: 2005-12-19
发 贴: 1,303
|
|
|
抱歉各位,最近实在有点忙
内核断点的信息是保存在每个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
|
|
|
总算明白了。内核模式下实际上还是有一份相当于全局的数据结构在起作用。
在用户态下,硬件断点是进程级别的,同时修改了所有线程的上下文。
|
|
|
IP 地址: 已记录
|
报告
|
|
|
|
高端调试 » 软件调试 » Windows内核调试 » Re: 硬件断点的疑惑
|
|
|
|
|
|