刺激战场
  • 1423阅读
  • 1回复

内核调试学习笔记 [复制链接]

上一主题 下一主题
离线啊冲
 

只看楼主 倒序阅读 使用道具 楼主  发表于: 2016-02-04


内核调试学习笔记


第一次调用KdInitSystem会初始化一下全局变量:

1.KdPitchDebugger:布尔类型,用来表示是否显式抑制内核调试。当启动选项中包含/DEBUG选项时,这个变量会被设置为真。
2.KdDeBuggerEnable:布尔类型,用来表示内核调试是否被启用。当启动选项中包含/DEBUG或者/DEBUGPORT 而且不包含/NODEBUG时,这个变量会被设置为真。
3.KiDebugRoutine:函数指针类型,用来记录内核调试引擎的异常处理回调函数,当内核调试引擎活动时,只想KdpTrap函数,否则指向KdpStub函数。
4.KdpBreakpointTable:结构数组类型,用来记录代码断点,每一个元素为BREAKPOINT_ENTRY结构,用来描述一个断点,包括断点地址。

说明:1.只有当0CPU执行KiSystemStartup函数时才会调用KdInitSystem,所以他不会被KiSystemStartup多次调用。
2.不管系统是否启用内核调试,调用都会发生。








中断到调试器:


在调试引擎向调试器报告状态变化信息之前,他会调用KdEnterDebugger函数来冻结内核。直到收到调试器的恢复继续执行命令(DbgContinueApi DbgContinueApi2 )后,在调用KdExitDebugger恢复内核运行

KdEnterDebugger调用过程:




执行KeFreezeExecutiong会调用KdDisableInterrupts禁止系统中断,如果是多核CPU,则会将当前CPU IRQL提高到HIGH_LEVEL,并且冻结所有其他CPU


退出调试器:


在调试引擎收到调试器的恢复继续执行命令(DbgContinueApi DbgContinueApi2 )后,会调用KdExitDebugger回复内核运行。
KdExitDebugger





调试引擎如何检测到调试器发送的中断包的?


当每次按下Ctrl+BreakWinDbg),栈信息如下:


系统的KeUpdateSystemTime函数在每次更新系统时间时(时钟中断 0号中断)会检查全局变量 KdDebuggerEnable来判断内核调试引擎是否被启用,如果为真,调用KdPollBreakIn函数来查看调试器是否发送了中断命令,如果是,便调用DbgBreakPointWithStatus触发断点异常。



接收和报告异常事件


与用户态调试类似,系统的异常分发函数通过内核调试引擎发送给内核调试器。KiDispatchException函数会调用全局变量KiDebugRoutine所指向的函数,当调试引擎被启用时,KiDebugRoutine指向KdpTrap的地址,如果调试引擎未被启用,iDebugRoutine指向KdpStub的地址。
调试引擎就是通过KdpTrap函数从系统内核接收异常事件的。



调试服务


通过异常分发函数和KdpTrap/KdpReport函数想内核调试器发送信息的方法,也被复用来实现以下调试功能:
1.打印调试信息
2.征求用户输入(Prompt)
3.报告模块加载事件
4.报告模块卸载事件

当需要执行以上任务时,系统触发一个软件异常(编号0x2D),称为调试服务异常。


可以发现这个异常处理函数是KiDebugService



KiDebugService 做了一些处理工作后,跳转到KiTrap03(断点异常处理函数)。

ExceptionRecord结构的ExceptionInformation[0] 字段标示了这个异常结构,记录的是一个真正的断点异常,还是调试服务请求。


为了方便的调用调试服务(INT 2D),内核设计了两个简单的函数DebugServiceDebugService2,这两个函数的实现是先把参数传递给寄存器,然后执行INT 2D指令。
善者 慈悲心常在 无怨无恨 以苦为乐
默认压缩密码www.hifyl.com
文件分享密码问题:http://www.hifyl.com/read-htm-tid-4444.html
离线v2680267313

只看该作者 沙发  发表于: 2016-04-30
用户被禁言,该主题自动屏蔽!
快速回复
限100 字节
批量上传需要先选择文件,再选择上传
 
上一个 下一个