别动系统的奶酪——违法Windows内核保护的错误(CRITICAL_STRUCTURE_CORRUPTION)

欢迎转载:作者:张佩】【原文:http://www.yiiyee.cn/Blog/0x109-1/

引子

下班的时候准备关掉调试机,却遇到蓝屏。本想直接拔电源,但蓝屏总是让我好奇,于是决定多待十分钟,看看这个蓝屏是怎么回事。主机的windbg调试器已经用DML标记出了自动分析命令!analyze –v。于是点进去:

1: kd> !analyze -v
ERROR: FindPlugIns 8007007b
ERROR: Some plugins may not be available [8007007b]
*******************************************************************
*                                                                 *
*                        Bugcheck Analysis                        *
*                                                                 *
*******************************************************************

CRITICAL_STRUCTURE_CORRUPTION (109)
This bugcheck is generated when the kernel detects that critical kernel code or
data have been corrupted. There are generally three causes for a corruption:
1) A driver has inadvertently or deliberately modified critical kernel code
 or data. See http://www.microsoft.com/whdc/driver/kernel/64bitPatching.mspx
2) A developer attempted to set a normal kernel breakpoint using a kernel
 debugger that was not attached when the system was booted. Normal breakpoints,
 "bp", can only be set if the debugger is attached at boot time. Hardware
 breakpoints, "ba", can be set at any time.
3) A hardware corruption occurred, e.g. failing RAM holding kernel code or data.
Arguments:
Arg1: a3a039d89bef061c, Reserved
Arg2: b3b7465eee6c05cb, Reserved
Arg3: fffff80053b0b910, Failure type dependent information
Arg4: 0000000000000001, Type of corrupted region, can be
	0 : A generic data region
	1 : Modification of a function or .pdata
	2 : A processor IDT
	3 : A processor GDT
	4 : Type 1 process list corruption
	5 : Type 2 process list corruption
	6 : Debug routine modification
	7 : Critical MSR modification

这一段内容很丰富,原来是系统发现关键结构体被破坏了。在XP时代,我们有一个很热门的技术话题,就是各种内核Hook。比如注明的SSDT Hook。SSDT是操作系统保存各种内核服务的一张表,里面保存的是各种内核函数指针。骇客只要把这张表给偷梁换柱,换成自己写的函数地址,就可以实现其狂妄的目的了。这个技术是这么地流行,不仅Rootkit和Virus爱它,Anti-Rootkit和Anti-Virus也爱它。搜索引擎查关键字“SSDT HOOK”,能找到一大堆经典文章和讨论。

这好比操作系统有一块奶酪放在办公桌上,路过的人把它里面的东西换成了橙汁。味道也许不错, 甚至更好,但操作系统很不喜欢!万一换的是放射性有毒物质呢?

这个技术现在还能在x86平台上使用,但微软决定在64位系统上,把这个漏洞或多或少地堵住。微软在它的第一版x64系统(XP x64)上引入了一项新技术。新增了一个内核检查措施,称为Kernel Patch Protection又名PatchGuard,简称KPP,对内核本身和重要的数据结构进行保护。似乎可以把KPP用中文直译成:内核补丁保护(这个翻译其实有点不妥,需要注意,不可以理解成保护内核补丁,而应该理解成保护内核不被补丁侵害)。

KPP的保护对象有很多,比如内核文件(NT、Hal.dll、Ndis.sys、Tcpip.sys等),内核结构体(如SSDT、内核堆栈、ObjectTypes),CPU结构体或寄存器(GDT、IDT、MSR)等等。一旦发现这些被保护的对象受到不当修改,就立刻蓝屏,蓝屏号恰恰就是CRITICAL_STRUCTURE_CORRUPTION (0x109)。

KPP和反KPP技术,现在和以后,都是一个很流行的讨论话题。

分析

从自动分析的提示中可知,KPP检测到有一个系统函数被修改了。为了找出KPP引发蓝屏的那个原因,必须使用!chkimg命令:

1> CHKIMG_EXTENSION: !chkimg -lo 50 -d !nt
2>     fffff80053b0b910 - nt!DbgBreakPoint
3> [cc:90 ]
4> 1 error : !nt (fffff80053b0b910)

运行之后,它列举了一个错误,是在nt!DbgBreakPoint函数中地址0x fffff80053b0b910处发现的。第三行的[cc:90]意思是说,这个地址处的指令应该是cc,但现在是90。指明了错误原因。

我到底做过什么了,就动了系统的奶酪了?还是来看看这个函数吧:

1: kd> uf nt!DbgBreakPoint
nt!DbgBreakPoint [d:\w8rtm\minkernel\ntos\rtl\amd64\debugstb.asm]:
   51 fffff800`53b0b910 90              nop
   54 fffff800`53b0b911 c3              ret

再看看未修改的代码:

2: kd> uf nt!DbgBreakPoint
nt!DbgBreakPoint [d:\w8rtm\minkernel\ntos\rtl\amd64\debugstb.asm]:
   51 fffff801`e4d06910 cc              int     3
   54 fffff801`e4d06911 c3              ret

哈哈,原来是公司的代码中滥用了太多的DbgBreak函数,调试的时候必须不断地按F5过滤掉这些int 3断点。于是大家都忍不住把这个本是断点指令的cc改成了无操作指令90。这就是原因所在了。

后来,我把这个patch改在了公司自己的驱动文件中,只要不影响系统文件,就避免了KPP检查的问题。

到这里真相大白了。系统的KPP一直在系统中运行着,它不保证当问题发生的时候,马上就抓到它。但它保证,只要问题存在足够长的时间(可能要经过几个小时,也可能只需几分钟),KPP就一定能够抓到它。这一点很重要,足以制止Patch技术的商业运用,甚至技术体验也都变得毫无价值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章