別動系統的奶酪——違法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技術的商業運用,甚至技術體驗也都變得毫無價值。

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