Windows2000 内核级进程隐藏、侦测技术[毕业论文]

本文探讨Windows 2000内核级进程隐藏与反隐藏技术,涉及驱动程序入门、Hook SSDT、线程调度链表隐藏检测等方面,提供核心代码示例,旨在揭示信息安全领域的攻防趋势。
摘要由CSDN通过智能技术生成

Windows2000 内核级进程隐藏、侦测技术

                                                                                       指导老师:龙老师

                                                                                       学生:LionDB        学号:0137506

摘要

       信息对抗是目前计算机发展的一个重要的方向,为了更好的防御,必须去深入的了解敌人进攻的招式。信息对抗促使信息技术飞速的发展。下面我选取了信息对抗技术的中一个很小一角关于windows内核级病毒隐藏技术和反病毒侦测技术作为议题详细讨论。

 

 

 
 
 

关键字:

内核, 拦截, 活动进程链表, 系统服务派遣表, 线程调度链

Abstract

       Nowadays, information opposability is a very important development aspect in computer techniqueIn order to defense better, we must to deeply know army intrusion system by various methodsInformation opposability technology cause Information technology development at very fast speedThen I choose process hiding and detection in windows kernel model as my topic for particular discussionIt is a very small part of information opposability technology only

 

 

 
 
 

KeyWord:

Kernel, Hook, Active Process Link, System Service Dispath Table, Dispatcher Thread Link

目录

1. 驱动程序简介

    1.1 为什么选驱动程序

    1.2 入口例程DriverEntry

    1.3 Unload例程

    1.4派遣例程

    1.5驱动程序的安装

2. 通过Hook SSDT (System Service Dispath Table) 隐藏进程

       2.1   原理介绍
       2.2   Hook
2.3   对NtQuerySystemInformation返回的数据进行删改
2.4   核心实现
3.    枚举和修改活动进程链表来检测和隐藏进程
       3.1   介绍EPROCESS块(进程执行块)
       3.2   查看EPROCESS结构
       3.3   什么是活动进程链表
       3.4   进程枚举检测Hook SSDT隐藏的进程
       3.5   解决硬编码问题
       3.6   删除活动进程链表实现进程隐藏
4.    基于线程调度链表的检测和隐藏技术
       4.1   什么是ETHREAD和KTHREAD块
       4.2   线程调度
       4.3   通过线程调度链表进行隐藏进程的检测
       4.4   绕过内核调度链表隐藏进程
       4.5   检测绕过内核调度链表隐藏进程
5.    Hook 内核函数(KiReadyThread)检测进程
       5.1   介绍通用Hook内核函数的方法
       5.2   检测隐藏进程
6.    结论

      

 

 

 
 
 

驱动程序简介

 

 

 
 
 

1.为什么选驱动程序

驱动程序是运行在系统信任的Ring0环境下在代码,她拥有对系统任何软件和硬件的访问权限。这意味着内核驱动可以访问所有的系统资源,可以读取所有的内存空间,而且也被允许执行CPU的特权指令,如,读取CPU控制寄存器的当前值等。而处于用户模式下的程序如果试图从内核空间中读取一个字节或者试图执行像MOV EAX,CR3这样的汇编指令都会被立即终止掉。不过,这种强大的底线是驱动程序的一个很小的错误就会让整个系统崩溃。所以对隐藏和反隐藏技术来说都提供了一个极好的环境。但是又对攻击者和反查杀者提出了更高的技术要求。

 

 

 
 
 

2.入口例程DriverEntry

       DriverEntry是内核模式驱动程序主入口点常用的名字,她的作用和main,WinMain,是一样的。

extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
  
 ...
}

DriverEntry的第一个参数是一个指针,指向一个刚被初始化的驱动程序对象,该对象就代表你的驱动程序,DriverEntry的第二个参数是设备服务键的键名。DriverEntry函数返回一个NTSTATUS值。NTSTATUS实际就是一个长整型,但你应该使用NTSTATUS定义该函数的返回值而不是LONG,这样代码的可读性会更好。大部分内核模式支持例程都返回NTSTATUS状态代码,你可以在DDK头文件NTSTATUS.H中找到NTSTATUS的代码列表。

DriverEntry的作用主要就是创建设备对象,建立设备对象的符号链接,设置好各个类型的回调函数等。

例如:

extern "C"

NTSTATUS

DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

{

 DriverObject->DriverUnload = DriverUnload;                                                             <--1

 DriverObject->DriverExtension->AddDevice = AddDevice;

 DriverObject->DriverStartIo = StartIo;

 DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;                                        <--2

 DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower;

 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DispatchWmi;

 ...

}

在WDM中通过设置AddDevice回调函数来创建设备对象。在NT驱动中在DriverEntry例程中创建设备对象和符号链接。

例如:

RtlInitUnicodeString (&deviceNameUnicodeString, deviceNameBuffer); //初始化设备名字
//创建设备

ntStatus = IoCreateDevice (DriverObject,     

                            0,

                            &deviceNameUnicodeString,

                            ##DeviceId,

                            0,

                            FALSE,

                            &deviceObject

                            );
if ( NT_SUCCESS ( ntStatus ) )  {

    RtlInitUnicodeString (&deviceLinkUnicodeString, deviceLinkBuffer); //初始化符号链接名字

//创建符号链接
    ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString, &deviceNameUnicodeString);
    if ( !NT_SUCCESS ( ntStatus ) ) {

        IoDeleteDevice (deviceObject); //如果创建符号链接失败,删除设备
             return ntStatus;

}

}

建立符号链接的作用就是暴露一个给应用程序的接口,应用程序可以通过CreateFile API打开链接符号,得到一个语柄,和我们的驱动程序进行交互操作。

 

 

 
 
 

3.Unload例程

虽然各个驱动程序的Unload例程不尽相同,但是它大致执行下列工作:

释放属于驱动程序的任何硬件。

从Win32的名字空间移除符号连接名。

这个动作可以调用IoDeleteSymbolicLink来实现。

使用IoDeleteDevice移除设备对象。

释放驱动程序持有的任何缓冲池等。

VOID DriverUnload ( IN PDRIVER_OBJECT pDriverObject )

{

PDEVICE_OBJECT pNextObj;

// 循环每一个驱动过程控制的设备

pNextObj = pDriverObject->DeviceObject;

while (pNextObj != NULL)

{

//从设备对象中取出设备Extension

PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)extObj->DeviceExtension;

// 取出符号连接名

UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;

IoDeleteSymbolicLink(&pLinkName); //删除符号连接名

IoDeleteDevice(pNextObj); // 删除设备

pNextObj = pNextObj->NextDevice;

}

}

 

 

 
 
 

4. 派遣例程

Win2000I/O请求是包驱动的,当一个I/O请求开始,I/O管理器先创建一个IRP去跟踪这个请求,另外,它存储一个功能代码在IRPI/O堆栈区的MajorField域中来唯一的标识请求的类型。MajorField域是被I/O管理器用来索引驱动程序对象的MajorFunction表,这个表包含一个指向一个特殊I/O请求的派遣例程的功能指针,如果驱动程序不支持这个请求,MajorFunction表就会指向I/O管理器函数_IopInvalidDeviceRequest,该函数返回一个错误给原始的调用者。驱动程序的作者有责任提供所有的驱动程序支持的派遣例程。所有的驱动程序必须支持IRP_MJ_CREATE功能代码,因为这个功能代码是用来响应Win32用户模式的CreateFile调用,如果不支持这功能代码,Win32程序就没有办法获得设备的句柄,类似的,驱动程序必须支持IRP_MJ_CLOSE功能代码,因为它用来响应Win32用户模式的CloseHandle调用。顺便提一下,系统自动调用CloseHandle函数,因为在程序退出的时候,所有的句柄都没有被关闭。

 

 

 
 
 

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{

    NTSTATUS status;

    PIO_STACK_LOCATION irpSp;

    //得到当前IRP (I/O请求包)

    irpSp = IoGetCurrentIrpStackLocation( Irp );

    switch (irpSp->MajorFunction)

    {

        case IRP_MJ_CREATE:

            DbgPrint("IRP_MJ_CREATE/n");

            Irp->IoStatus.Status = STATUS_SUCCESS;

            Irp->IoStatus.Information = 0L;

            break;

        case IRP_MJ_CLOSE:

            DbgPrint("IRP_MJ_CLOSE/n");

            Irp->IoStatus.Status = STATUS_SUCCESS;

            Irp->IoStatus.Information = 0L;

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值