首页 > 其他 > 详细

关于调试系统调用引发的一些思考

时间:2020-04-26 14:44:08      阅读:96      评论:0      收藏:0      [点我收藏+]

Debug SystemCall by Windbg

前言

? 昨天在给系统调用入口下硬件断点时发现了两种不同的情况,结合IDA,Windbg,Intel文档思考了许久,记录一下自己的想法,并不保证一定正确,测试环境Win10 1903 x64

第一种情况

  1. 硬件断点下到swapgs之后和mov rsp, qword ptr gs:[7008h]之前,这时的环境应该是gs已经切换但内核栈还未切换
    • 这里面其实还包含了一种情况,就是在swapgs之后和切换内核页表之前,但是这并不影响IDT处理例程读取内核空间,因为IDT handler会根据KiKvaShadow切换CR3

技术分享图片

  1. 在按下g之后,Windbg接收到异常,堆栈如下

技术分享图片

  • 可以看到当调试异常KiDebugTrapOrFaultShadow触发时,已经进行了堆栈切换,但是按照我们对x86异常处理的理解,这里由于是从nt!KiSystemCall64Shadow触发的硬件断点,所以应该不存在权限切换,所以CPU应该不会自动切换堆栈,如下图

技术分享图片

  • 在Intel文档中查询了x64异常相关的文档后发现在x64上面处理机制有了一些变化,在x64的IDT结构中多了一个3 bits的IST索引,这个索引指向tr指向的x64 TSS结构中的IST。当IST索引为0时,采用x86的传统栈切换机制,如果IST不为0,则栈切换将会无条件进行

技术分享图片
技术分享图片
技术分享图片
技术分享图片

  1. 因此在调用KiDebugTrapOrFault时堆栈是正常可靠的0环堆栈,但是在Windbg中可以看到在nt!KiDebugTrapOrFault+0x65发生了异常,经过分析,在这段代码中用到了异常前的堆栈进行数据存储,也就是说内核调试例程需要内核栈的支持,而我们触发硬件断点时堆栈还没有进行切换,因此在KiDebugTrapOrFault异常处理例程中又发生了异常,从而引起了nt!KiDoubleFaultAbort双重异常

技术分享图片

第二种情况

  1. 硬件断点下在swapgs这里,也就是gs还有没切换时触发KiDebugTrapOrFaultShadow,然后Windbg按下g之后虚拟机和调试器皆会无法响应

技术分享图片

  1. 经过在IDA中分析,以下想法皆为猜测,无法调试验证

    • 触发硬件断点后,CPU流程进入KiDebugTrapOrFaultShadow,但是由于此时的gs并未指向内核数据kpcr,因此在KiDebugTrapOrFaultShadow中读取gs寄存器时触发了SMAP(此时gs指向应用层的TEB),从而引发双重异常KiDoubleFaultAbortShadow,但是由于双重异常处理例程中也使用了gs,再次发生异常,不断重入KiDoubleFaultAbortShadow导致进入死循环

技术分享图片

技术分享图片

总结

  • 经过以上的分析,我们只需要在gs内核栈设置完成后下硬件断点,Windbg就可以正常断下

技术分享图片

  • 记录一下64位下各种描述符大小的变化

技术分享图片

关于调试系统调用引发的一些思考

原文:https://www.cnblogs.com/DreamoneOnly/p/12779106.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!