-
-
Windows内核学习笔记二----双机内核调试时单步步入sysenter指令时不能跟进内核?
-
发表于:
2021-2-22 03:11
4742
-
Windows内核学习笔记二----双机内核调试时单步步入sysenter指令时不能跟进内核?
同样是转存笔记。
忘了是在哪一个技术群有人问为什么单步调试时执行sysenter指令不能单步步入到内核,即使是双机内核调试。今天看潘爱民老师的《windows内核原理与实现》时恰好看到有关系统调用的内容,不过我个人觉得p554 第二段内容描述有误,因此分享一下我的见解。以下内容结合wrk说明。如果x86在执行sysenter指令时EFLAGS.TF标志为1,则会产生single-step #DB异常,由于single-step #DB异常属于trap类型的异常,因此会把从IA32_SYSENTER_EIP获得的Eip(也即是KiFastCallEntry的第一条指令地址)压入栈作为KTRAP_FRAME.Eip,并且把从IA32_SYSENTER_CS获得的cs压入栈作为KTRAP_FRAME.SegCs,然后控制流程转移到signle-step #DB异常的处理例程KiTrap01,在KiTrap01中如果判断KTRAP_FRAME.Eip为KiFastCallEntry的第一条指令地址时会把KTRAP_FRAME.Eip改为KiFastCallEntry2,并清除KTRAP_FRAME.Eflags.TF,然后控制流程跳转到Kei386EoiHelper处,然后EXIT_ALL汇编宏代码得到执行,在EXIT_ALL汇编宏中会检测到KTRAP_FRAME.SegCs的bit0为0,然后直接跳转到KTRAP_FRAME.Eip也即KiFastCallEntry2处执行。KiFastCallEntry2重新构建一个新的KTRAP_FRAME,并且把KTRAP_FRAME.Eflags.TF置为1,把KTRAP_FRAME.Eip设置为KiFastSystemCallRet,然后控制流程转移到KiFastCallEntry和KiFastCallEntry2的公共代码部分,注意,此时还是处理single-step #DB异常的继续,在KiFastCallEntry2中模拟系统调用而构建KTRAP_FRAME,当控制流程来到KiSystemCallExit2处会判断到KTRAP_FRAME.Eflags.TF为1,然后控制流程会跳转到KiSystemCallExit处,执行iretd后控制流程来到KiFastSystemCallRet处,从而不能从r3单步步入到windows内核。从而阻止调试器从应用层单步步入到内核,试想如果允许一个应用程序能够单步调试内核多么吓人。另外我看的资料里面都描述x86的INT N指令会把EFLAGS.TF清零。因此我认为《Windows内核原理与实现》P554第二段描述有误。
[注意]APP应用上架合规检测服务,协助应用顺利上架!
最后于 2021-4-14 10:04
被fengyunabc编辑
,原因: