0、引言
做过Windows内核开发或者驱动开发的朋友,必然常常会遇到BSoD,其全称为Blue Screen of Death;of作为介词,其缩写o则需要小写了;然而Windows NT内核当时推出时,想必微软也大势宣传其是进程安全的,不像DOS那样,一个进程挂了,整个系统就挂了;当然,如果对于系统启动过程非常熟悉的话,应该听说过一些系统的关键进程如csrss.exe挂了的话,则整个系统必然挂;这篇文章的目的就是揭露这后边的秘密,看看系统是如何选择性死亡了,这也牵扯到另一桩生意——一些恶意代码就喜欢鱼死网破。特别是一些服务万千用户的服务器,公司是承受不起这种损失的。
涉及到的知识点:
1、调用为公开的API实现Ring3的BSoD行为;
2、蓝屏dmp的分析与相关技巧的应用;
3、通过分析dmp来加快关键算法的定位,找关键逻辑;
4、借助IDA来逆向分析OS对Critical Process,Thread触发BSoD的实现原理;
5、安全厂商比较通用的解决方案;
1、背景
当关键进程诸如csrss.exe挂掉时,系统是根据什么来判断是否要触发BSoD的呢?一个最直观的想法就是根据进程名来识别,但很快这个想法就被否决了,因为进程名很容易伪造,随便写个程序命名为csrss.exe,然后手动杀掉,系统依旧如初;另一个想法便是OS做了签名检测,如果是微软的签名且EXE的名字还要满足,这个想法有点接近,但很快也被排除了,微软自带了那么多进程,随便找一个带有微软签名的,把进程名改一下,杀掉他,系统依旧运行的妥妥的。当然,这些想法有很多,最核心的方法不是去猜测这些,而是去逆向分析下TerminateProcess ()的内核实现,这个我们再下边会涉及到;接下来我们先用代码实现一下BSoD;
2、代码实现
2.1 关键的API介绍
NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle,IN THREADINFOCLASS ThreadInformationClass,IN PVOID ThreadInformation,IN ULONG ThreadInformationLength);
NTSTATUS NTAPI NtSetInformationProcess(IN HANDLE ProcessHandle,IN PROCESSINFOCLASS ProcessInformationClass,IN PVOID ProcessInformation,IN ULONG ProcessInformationLength);
NTSTATUS NTAPI RtlSetThreadIsCritical(IN BOOLEAN NewValue,OUT PBOOLEAN OldValue OPTIONAL,IN BOOLEAN NeedBreaks)
NTSTATUS NTAPI RtlSetProcessIsCritical (IN BOOLEAN NewValue,OUT PBOOLEAN OldValue OPTIONAL,IN BOOLEAN NeedBreaks);
上边这几个API便是实现此目的的核心API,当然除了这些,还有其他的API,原理都是大同小异;简单介绍下,NtSetInformationThread和NtSetInformationProcess这两个API就是针对给定的进程或者线程做一些属性更新操作,大部分操作都是直接操作的进程或者线程对应的内核对象即EPROCESS、ETHREAD中相关的字段;与这两个API对应的则是NtQueryInformationThread()和NtQueryInformationProcess()这两个API,大家可自行查阅学习;
THREADINFOCLASS和PROCESSINFOCLASS这两个枚举常量,官方头文件公布出来的如下:
确实很小气,THREADINFOCLASS中几乎没给出有用的,PROCESSINFOCLASS中的ProcessBreakOnTermination倒是很显眼;根据网上公开的数据,整理如下:
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation, //0
ProcessQuotaLimits, //1
ProcessIoCounters, //2
ProcessVmCounters, //3
ProcessTimes, //4
ProcessBasePriority, //5
ProcessRaisePriority, //6
ProcessDebugPort, //7
ProcessExceptionPort, //8
ProcessAccessToken, //9
ProcessLdtInformation, //10
ProcessLdtSize, //11
ProcessDefaultHardErrorMode, //12
ProcessIoPortHandlers, //13
ProcessPooledUsageAndLimits, //14
ProcessWorkingSetWatch, //15
ProcessUserModeIOPL, //16
ProcessEnableAlignmentFaultFixup, //17
ProcessPriorityClass, //18
ProcessWx86Information, //19
ProcessHandleCount, //20
ProcessAffinityMask, //21
ProcessPriorityBoost,