windows内核安全(七)

线程与进程

Posted by volcanohatred on July 30, 2018

线程同步互斥

异常(cpu内部的中断,IF位保持不变,不关中断)
故障(FALT)除零,越界,缺页,堆栈故障。
陷阱(TRAP)int3,溢出等。
中断(IF位清零,关中断)
可屏蔽中断(maskable interrupt)。硬件中断的一类,可通过在中断屏蔽寄存器中设定位掩码来关闭。
非可屏蔽中断(non-maskable interrupt,NMI)。硬件中断的一类,无法通过在中断屏蔽寄存器中设定位掩码来关闭。典型例子是时钟中断(一个硬件时钟以恒定频率—如50Hz—发出的中断)。
线程的IRQL级别:
PASSIVE_LEVEL
IRQL最低级别,没有被屏蔽的中断,在这个级别上,线程执行用户模式,可以访问分页内存。
APC_LEVEL
在这个级别上,只有APC级别的中断被屏蔽,可以访问分页内存。当有APC发生时,处理器提升到APC级别,这样,就屏蔽掉其它APC,为了和APC执行一些同步,驱动程序可以手动提升到这个级别。比如,如果提升到这个级别,APC就不能调用。在这个级别,APC被禁止了,导致禁止一些I/O完成APC,所以有一些API不能调用。
DISPATCH_LEVEL(内核中最高级别)
这个级别,DPC 和更低的中断被屏蔽,不能访问分页内存,所有的被访问的内存不能分页。因为只能处理非分页内存,所以在这个级别,能够访问的API大大减少。
DIRQL(Device IRQL)
一般的,更高级的驱动在这个级别上不处理IRQL,但是几乎所有的中断被屏蔽,这实际上是IRQL的一个范围,这是一个决定某个驱动有更高的优先级的方法。
进程与线程
内核中各个函数的运行环境:
进程与线程
注:多线程必须加锁。

内核中创建线程:

PsCreateSystemThread
# include <ntddk.h>

ULONG
g_ulTotal = 0;
// InterlockedIncrement(g_ulTotal);
FAST_MUTEX
g_fmLock;

VOID
DriverUnload(PDRIVER_OBJECT
pDriverObject)
{
    DbgPrint("Goodbye, driver\n");
}

VOID
ThreadProc1(IN
PVOID
pContext)
{
    ULONG
i = 0;
ExAcquireFastMutex( & g_fmLock);

g_ulTotal + +;
DbgPrint("ThreadProc1:%x\n", g_ulTotal);

ExReleaseFastMutex( & g_fmLock);

}

VOID
ThreadProc2(IN
PVOID
pContext)
{
    ULONG
i = 0;
ExAcquireFastMutex( & g_fmLock);

g_ulTotal + +;
DbgPrint("ThreadProc2:%x\n", g_ulTotal);

ExReleaseFastMutex( & g_fmLock);
}
void
StartThreads()
{
    HANDLE
hThread1 = NULL;
HANDLE
hThread2 = NULL;

PVOID
objtowait[2] = {NULL};
NTSTATUS
ntStatus =
PsCreateSystemThread( // 创建线程
& hThread1,
0,
NULL,
(HANDLE)
0,
NULL,
ThreadProc1,
NULL
);
if (!NT_SUCCESS(ntStatus))
{
return;
}

ntStatus =
PsCreateSystemThread(
& hThread2,
0,
NULL,
(HANDLE)
0,
NULL,
ThreadProc2,
NULL
);
if (!NT_SUCCESS(ntStatus))
{
return;
}

if ((KeGetCurrentIrql()) != PASSIVE_LEVEL)
{
ntStatus = KfRaiseIrql(PASSIVE_LEVEL);
}
if ((KeGetCurrentIrql()) != PASSIVE_LEVEL)
{
return;
}
ntStatus = ObReferenceObjectByHandle(
hThread1,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
& objtowait[0],
NULL
);
if (!NT_SUCCESS(ntStatus))
{
return;
}

ntStatus = ObReferenceObjectByHandle(
hThread1,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
& objtowait[1],
NULL
);
if (!NT_SUCCESS(ntStatus))
{
ObDereferenceObject(objtowait[0]);
return;
}

KeWaitForMultipleObjects(
2,
objtowait,
WaitAll,
Executive,
KernelMode,
FALSE,
NULL,
NULL);

ObDereferenceObject(objtowait[0]);
ObDereferenceObject(objtowait[1]);

// KeWaitForSingleObject(objtowait, Executive, KernelMode, FALSE, NULL);
return;
}



NTSTATUS
DriverEntry(PDRIVER_OBJECT
pDriverObject, PUNICODE_STRING
pRegPath)
{
pDriverObject->DriverUnload = DriverUnload;

ExInitializeFastMutex( & g_fmLock);

StartThreads();

return STATUS_SUCCESS;
}

同步:

用于内核态同步对象:
KEVENT,KMUTEX,KSEMAPHORE(带DISPATCHER头)
KEVENT:
两个状态:singaled,Non-singaled
两个类别:Notification,sunchronization
KSEMAPHORE(信号量):用于同步与多个资源共享访问
函数:

KeWaitForSingleObject
KeWaitForMultipleObjects
NTSTATUS KeWaitForSingleObject(
     PVOID  Object,//对象(event,mutex,semaphore,thread or timer)
     KWAIT_REASON  WaitReason,
     KPROCESSOR_MODE  WaitMode,
     BOOLEAN  Alertable,
     PLARGE_INTEGER  Timeout OPTIONAL  //0不等待,NULL无限等待
    );

基于EVENT:


#include "ntddk.h"
#include "windef.h"

#define EVENT_NAME    L"\\BaseNamedObjects\\ProcEvent"
#define DEVICE_NAME      L"\\Device\\ProcWatch"
#define LINK_NAME    L"\\DosDevices\\ProcWatch"

#define       CTRLCODE_BASE 0x800
#define       MYCTRL_CODE(i) \
   CTL_CODE(FILE_DEVICE_UNKNOWN,CTRLCODE_BASE + i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define       IOCTL_PROCWATCH       MYCTRL_CODE(0)

typedef struct _ProcMonData
{
   HANDLE  hParentId;
   HANDLE  hProcessId;
   BOOLEAN bCreate;
}ProcMonData, *PProcMonData;


VOID DriverUnload(IN PDRIVER_OBJECT DriverObject);

NTSTATUS CommonDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS IoctrlDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

VOID ProcessCreateMon(IN HANDLE hParentId, IN HANDLE PId, IN BOOLEAN bCreate);


typedef struct _DEVICE_EXTENSION  //设备扩展,记录要保存的数据
{
   HANDLE             hProcessHandle;      // 事件对象句柄
   PKEVENT            ProcessEvent;         // 用户和内核通信的事件对象指针
   HANDLE             hParentId;           // 在回调函数中保存进程信息
   HANDLE             hProcessId;
   BOOLEAN            bCreate;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

PDEVICE_OBJECT g_pDeviceObject = NULL;

// 驱动入口
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)

{
   UNICODE_STRING ustrDeviceName = { 0 };
   UNICODE_STRING ustrLinkName = { 0 };
   PDEVICE_OBJECT deviceObject = NULL;
   NTSTATUS      status = STATUS_SUCCESS;
   int             i = 0;
   UNICODE_STRING ustrEventStr = { 0 };
   PDEVICE_EXTENSION pDeviceExtension = NULL;
   //建立设备

   RtlInitUnicodeString(&ustrDeviceName, DEVICE_NAME);
   status = IoCreateDevice(DriverObject,
      sizeof(DEVICE_EXTENSION),  //设备扩展的空间长度
      &ustrDeviceName,     
      FILE_DEVICE_UNKNOWN,
      0,
      FALSE,
      &deviceObject
   );

   if (!NT_SUCCESS(status))
   {
      return status;
   }

   deviceObject->Flags |= DO_BUFFERED_IO;

   g_pDeviceObject = deviceObject;

   // 创建事件对象与应用层通信
   RtlInitUnicodeString(&ustrEventStr, EVENT_NAME);
   pDeviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;

   pDeviceExtension->ProcessEvent =
      IoCreateNotificationEvent(&ustrEventStr,
         &pDeviceExtension->hProcessHandle);
   KeClearEvent(pDeviceExtension->ProcessEvent);            // 设置为无信号状态

   RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
   status = IoCreateSymbolicLink(&ustrLinkName, &ustrDeviceName);

   if (!NT_SUCCESS(status))
   {
      IoDeleteDevice(DriverObject->DeviceObject);
      return status;
   }

   status = PsSetCreateProcessNotifyRoutine(ProcessCreateMon, FALSE);
   if (!NT_SUCCESS(status))
   {
      IoDeleteDevice(DriverObject->DeviceObject);
      DbgPrint("PsSetCreateProcessNotifyRoutine()\n");
      return status;
   }

   for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
   {
      DriverObject->MajorFunction[i] = CommonDispatch;
   }

   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoctrlDispatch;

   DriverObject->DriverUnload = DriverUnload;

   return STATUS_SUCCESS;
}

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
   UNICODE_STRING ustrLinkName;
   PsSetCreateProcessNotifyRoutine(ProcessCreateMon, TRUE);
   RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
   IoDeleteSymbolicLink(&ustrLinkName);
   IoDeleteDevice(DriverObject->DeviceObject);
}

//处理设备对象操作
NTSTATUS CommonDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{
   Irp->IoStatus.Status = STATUS_SUCCESS;
   Irp->IoStatus.Information = 0L;
   IoCompleteRequest(Irp, 0);
   return Irp->IoStatus.Status;
}

NTSTATUS IoctrlDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
{
   NTSTATUS         ntStatus = STATUS_SUCCESS;
   PVOID           pUserBuffer = NULL;
   ULONG           ulInputSize = 0;
   ULONG           ulOutputSize = 0;
   PIO_STACK_LOCATION pIrpStack = NULL;
   ULONG           ulIoCtrlCode = 0;
   PProcMonData      pProcMonData = NULL;
   PDEVICE_EXTENSION  pDeviceExtension = NULL;

   pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

   pUserBuffer = pIrp->AssociatedIrp.SystemBuffer;

   pProcMonData = (PProcMonData)pUserBuffer;   //pUserBuffer强转

   ulIoCtrlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
   ulInputSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
   ulOutputSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

   switch (ulIoCtrlCode)
   {
   case IOCTL_PROCWATCH:

      pDeviceExtension = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;

      pProcMonData->bCreate = pDeviceExtension->bCreate;
      pProcMonData->hParentId = pDeviceExtension->hParentId;
      pProcMonData->hProcessId = pDeviceExtension->hProcessId;

      break;
   default:
      ntStatus = STATUS_INVALID_PARAMETER;
      ulOutputSize = 0;
      break;
   }

   pIrp->IoStatus.Status = ntStatus;
   pIrp->IoStatus.Information = ulOutputSize;

   IoCompleteRequest(pIrp, IO_NO_INCREMENT);

   return ntStatus;
}

VOID ProcessCreateMon(IN HANDLE hParentId, IN HANDLE PId, IN BOOLEAN bCreate)
{
   // 获得DEVICE_EXTENSION结构
   PDEVICE_EXTENSION deviceExtension =
      (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
   // 保存信息
   deviceExtension->hParentId = hParentId;
   deviceExtension->hProcessId = PId;
   deviceExtension->bCreate = bCreate;
   // 触发事件,通知应用程序
   KeSetEvent(deviceExtension->ProcessEvent, 0, FALSE);    //变为有信号
   KeClearEvent(deviceExtension->ProcessEvent);
}

安装代码:

// ProcWatchClientConsole.cpp
#include "stdafx.h"
#include "windows.h"
#include "winioctl.h"
#include "stdio.h"

BOOL LoadDriver(const char* lpszDriverName, const char* lpszDriverPath);
BOOL UnloadDriver(const char * szSvrName);


#define EVENT_NAME    L"Global\\ProcEvent"
#define DRIVER_NAME  "ProcWatch"
#define DRIVER_PATH      ".\\ProcWatch.sys"

#define       CTRLCODE_BASE 0x8000
#define       MYCTRL_CODE(i) \
CTL_CODE(FILE_DEVICE_UNKNOWN,CTRLCODE_BASE + i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define       IOCTL_PROCWATCH       MYCTRL_CODE(0)

typedef struct _ProcMonData
{
   HANDLE  hParentId;
   HANDLE  hProcessId;
   BOOLEAN bCreate;
}ProcMonData, *PProcMonData;


int main(int argc, char* argv[])
{

   ProcMonData pmdInfoNow = { 0 };
   ProcMonData pmdInfoBefore = { 0 };

   if (!LoadDriver(DRIVER_NAME, DRIVER_PATH))   //加载驱动
   {
      printf("LoadDriver Failed:%x\n", GetLastError());
      return -1;
   }
   // 打开驱动设备对象
   HANDLE hDriver = ::CreateFile(
      "\\\\.\\ProcWatch",
      GENERIC_READ | GENERIC_WRITE,
      0,
      NULL,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      NULL);
   if (hDriver == INVALID_HANDLE_VALUE)
   {
      printf("Open device failed:%x\n", GetLastError());
      UnloadDriver(DRIVER_NAME);
      return -1;
   }
   // 打开内核事件对象
   HANDLE hProcessEvent = ::OpenEventW(SYNCHRONIZE, FALSE, EVENT_NAME);

   //while (TRUE)
   //{
   //DWORD    dwRet   = 0;
   //BOOL     bRet    = FALSE;

   //::WaitForSingleObject(hProcessEvent, INFINITE);

   while (::WaitForSingleObject(hProcessEvent, INFINITE))
   {
      DWORD    dwRet = 0;
      BOOL     bRet = FALSE;

      bRet = ::DeviceIoControl(
         hDriver,
         IOCTL_PROCWATCH,
         NULL,
         0,
         &pmdInfoNow,
         sizeof(pmdInfoNow),
         &dwRet,
         NULL);
      if (bRet)
      {
         if (pmdInfoNow.hParentId != pmdInfoBefore.hParentId || \
            pmdInfoNow.hProcessId != pmdInfoBefore.hProcessId || \
            pmdInfoNow.bCreate != pmdInfoBefore.bCreate)
         {
            if (pmdInfoNow.bCreate)
            {
               printf("ProcCreated,PID = %d\n", pmdInfoNow.hProcessId);
            }
            else
            {
               printf("ProcTeminated,PID = %d\n", pmdInfoNow.hProcessId);
            }
            pmdInfoBefore = pmdInfoNow;
         }
      }
      else
      {
         printf("Get Proc Info Failed!\n");
         break;
      }
   }

   ::CloseHandle(hDriver);
   UnloadDriver(DRIVER_NAME);

   return 0;
}

//装载NT驱动程序
BOOL LoadDriver(const char* lpszDriverName, const char* lpszDriverPath)
{
   char szDriverImagePath[256] = { 0 };
   //得到完整的驱动路径
   GetFullPathName(lpszDriverPath, 256, szDriverImagePath, NULL);

   BOOL bRet = FALSE;

   SC_HANDLE hServiceMgr = NULL;//SCM管理器的句柄
   SC_HANDLE hServiceDDK = NULL;//NT驱动程序的服务句柄

                         //打开服务控制管理器
   hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

   if (hServiceMgr == NULL)
   {
      //OpenSCManager失败
      printf("OpenSCManager() Faild %d ! \n", GetLastError());
      bRet = FALSE;
      goto BeforeLeave;
   }
   else
   {
      ////OpenSCManager成功
      printf("OpenSCManager() ok ! \n");
   }

   //创建驱动所对应的服务
   hServiceDDK = CreateService(hServiceMgr,
      lpszDriverName, //驱动程序的在注册表中的名字  
      lpszDriverName, // 注册表驱动程序的 DisplayName 值  
      SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限  
      SERVICE_KERNEL_DRIVER,// 表示加载的服务是驱动程序  
      SERVICE_DEMAND_START, // 注册表驱动程序的 Start 值  
      SERVICE_ERROR_IGNORE, // 注册表驱动程序的 ErrorControl 值  
      szDriverImagePath, // 注册表驱动程序的 ImagePath 值  
      NULL,  //GroupOrder HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GroupOrderList
      NULL,
      NULL,
      NULL,
      NULL);

   DWORD dwRtn;
   //判断服务是否失败
   if (hServiceDDK == NULL)
   {
      dwRtn = GetLastError();
      if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_EXISTS)
      {
         //由于其他原因创建服务失败
         printf("CrateService() Faild %d ! \n", dwRtn);
         bRet = FALSE;
         goto BeforeLeave;
      }
      else
      {
         //服务创建失败,是由于服务已经创立过
         printf("CrateService() Faild Service is ERROR_IO_PENDING or ERROR_SERVICE_EXISTS! \n");
      }

      // 驱动程序已经加载,只需要打开  
      hServiceDDK = OpenService(hServiceMgr, lpszDriverName, SERVICE_ALL_ACCESS);
      if (hServiceDDK == NULL)
      {
         //如果打开服务也失败,则意味错误
         dwRtn = GetLastError();
         printf("OpenService() Faild %d ! \n", dwRtn);
         bRet = FALSE;
         goto BeforeLeave;
      }
      else
      {
         printf("OpenService() ok ! \n");
      }
   }
   else
   {
      printf("CrateService() ok ! \n");
   }

   //开启此项服务
   bRet = StartService(hServiceDDK, NULL, NULL);
   if (!bRet)
   {
      DWORD dwRtn = GetLastError();
      if (dwRtn != ERROR_IO_PENDING && dwRtn != ERROR_SERVICE_ALREADY_RUNNING)
      {
         printf("StartService() Faild %d ! \n", dwRtn);
         bRet = FALSE;
         goto BeforeLeave;
      }
      else
      {
         if (dwRtn == ERROR_IO_PENDING)
         {
            //设备被挂住
            printf("StartService() Faild ERROR_IO_PENDING ! \n");
            bRet = FALSE;
            goto BeforeLeave;
         }
         else
         {
            //服务已经开启
            printf("StartService() Faild ERROR_SERVICE_ALREADY_RUNNING ! \n");
            bRet = TRUE;
            goto BeforeLeave;
         }
      }
   }
   bRet = TRUE;
   //离开前关闭句柄
BeforeLeave:
   if (hServiceDDK)
   {
      CloseServiceHandle(hServiceDDK);
   }
   if (hServiceMgr)
   {
      CloseServiceHandle(hServiceMgr);
   }
   return bRet;
}

//卸载驱动程序  
BOOL UnloadDriver(const char * szSvrName)
{
   BOOL bRet = FALSE;
   SC_HANDLE hServiceMgr = NULL;//SCM管理器的句柄
   SC_HANDLE hServiceDDK = NULL;//NT驱动程序的服务句柄
   SERVICE_STATUS SvrSta;
   //打开SCM管理器
   hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
   if (hServiceMgr == NULL)
   {
      //带开SCM管理器失败
      printf("OpenSCManager() Faild %d ! \n", GetLastError());
      bRet = FALSE;
      goto BeforeLeave;
   }
   else
   {
      //带开SCM管理器失败成功
      printf("OpenSCManager() ok ! \n");
   }
   //打开驱动所对应的服务
   hServiceDDK = OpenService(hServiceMgr, szSvrName, SERVICE_ALL_ACCESS);

   if (hServiceDDK == NULL)
   {
      //打开驱动所对应的服务失败
      printf("OpenService() Faild %d ! \n", GetLastError());
      bRet = FALSE;
      goto BeforeLeave;
   }
   else
   {
      printf("OpenService() ok ! \n");
   }
   //停止驱动程序,如果停止失败,只有重新启动才能,再动态加载。  
   if (!ControlService(hServiceDDK, SERVICE_CONTROL_STOP, &SvrSta))
   {
      printf("ControlService() Faild %d !\n", GetLastError());
   }
   else
   {
      //打开驱动所对应的失败
      printf("ControlService() ok !\n");
   }
   //动态卸载驱动程序。  
   if (!DeleteService(hServiceDDK))
   {
      //卸载失败
      printf("DeleteSrevice() Faild %d !\n", GetLastError());
   }
   else
   {
      //卸载成功
      printf("DelServer:deleteSrevice() ok !\n");
   }
   bRet = TRUE;
BeforeLeave:
   //离开前关闭打开的句柄
   if (hServiceDDK)
   {
      CloseServiceHandle(hServiceDDK);
   }
   if (hServiceMgr)
   {
      CloseServiceHandle(hServiceMgr);
   }
   return bRet;
}
安装代码头文件:
// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__70A2ABB0_BAFE_4353_9DC3_B5231B3D2AEE__INCLUDED_)
#define AFX_STDAFX_H__70A2ABB0_BAFE_4353_9DC3_B5231B3D2AEE__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


// TODO: reference additional headers your program requires here

//
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__70A2ABB0_BAFE_4353_9DC3_B5231B3D2AEE__INCLUDED_)

互斥:

用于内核态同步对象: KSPIN_LOCK,ERESOURCE,FAST_MUTEX KSPIN_LOCK(自旋锁): 用于多CPU共享安全 提升IRQL到DISPACHER_LEVEL 进制访问分页内存 获得时间越短越好 ERESOURCE(共享锁) FAST_MUTEX(互斥体): APC_LEVEL之下级别

强杀进程

杀进程过程:
PsTerminateProcess->PspTerminateProcess->PspTerminateThreadByPointer->PspExitThread 杀进程最底层的函数:
PspTerminateProcess(XP) 暴力搜索这种方法在内核中很重要。
暴力搜索获取特征值:
windbg:dd 函数名 L4 获取前16字节特征码。
内核地址空间:
(NtQueryXXX()/AuxKlibQueryModuleInformation()版本高)知道内核空间的起始地址和内核大小以便于暴力搜索。
C代码:

#include <ntddk.h>
#include <ntimage.h>
#include <ntdef.h>
#include "Ioctlcmd.h"

const WCHAR deviceLinkBuffer[] = L"\\DosDevices\\KillProc";
const WCHAR deviceNameBuffer[] = L"\\Device\\KillProc";

typedef NTSTATUS(*NTQUERYSYSTEMINFORMATION)(

   IN     ULONG                         SystemInformationClass,
   OUT PVOID                           SystemInformation,
   IN     ULONG                         SystemInformationLength,
   OUT PULONG                        ReturnLength OPTIONAL);
typedef unsigned long DWORD;
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
#define    SystemModuleInformation    11 
typedef struct _SYSTEM_MODULE_INFORMATION
{
   ULONG  Reserved[2];
   PVOID  Base;
   ULONG  Size;
   ULONG  Flags;
   USHORT Index;
   USHORT Unknown;
   USHORT LoadCount;
   USHORT ModuleNameOffset;
   CHAR   ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;

PDEVICE_OBJECT g_HookDevice;
NTSTATUS  PsLookupProcessByProcessId(ULONG ProcessId, PEPROCESS *Process);

typedef  NTSTATUS(*PSPTERPROC) (PEPROCESS Process, NTSTATUS ExitStatus);
PSPTERPROC MyPspTerminateProcess = NULL;


NTSTATUS OnUnload(IN PDRIVER_OBJECT DriverObject)
{
   UNICODE_STRING          deviceLinkUnicodeString;
   PDEVICE_OBJECT    p_NextObj;


   DbgPrint("OnUnload called\n");

   p_NextObj = DriverObject->DeviceObject;

   if (p_NextObj != NULL)
   {

      RtlInitUnicodeString(&deviceLinkUnicodeString, deviceLinkBuffer);
      IoDeleteSymbolicLink(&deviceLinkUnicodeString);

      IoDeleteDevice(DriverObject->DeviceObject);
   }
   return STATUS_SUCCESS;
}

NTSTATUS
DispatchControl(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
{
   PIO_STACK_LOCATION      irpStack;
   PVOID                   inputBuffer;
   PVOID                   outputBuffer;
   PVOID             userBuffer;
   ULONG                   inputBufferLength;
   ULONG                   outputBufferLength;
   ULONG                   ioControlCode;
   NTSTATUS           ntstatus;

   unsigned int i;

   unsigned total = 0;
   ULONG count = 0;

   HANDLE handle;


   ULONG cnt;

   PEPROCESS Eprocess = NULL;
   DWORD pid;


   ntstatus = Irp->IoStatus.Status = STATUS_SUCCESS;
   Irp->IoStatus.Information = 0;

   irpStack = IoGetCurrentIrpStackLocation(Irp);

   inputBuffer = Irp->AssociatedIrp.SystemBuffer;
   inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
   outputBuffer = Irp->AssociatedIrp.SystemBuffer;
   outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
   ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;



   switch (irpStack->MajorFunction)
   {
   case IRP_MJ_CREATE:
      break;

   case IRP_MJ_SHUTDOWN:
      break;

   case IRP_MJ_CLOSE:
      break;

   case IRP_MJ_DEVICE_CONTROL:

      if (IOCTL_TRANSFER_TYPE(ioControlCode) == METHOD_NEITHER)
      {
         outputBuffer = Irp->UserBuffer;
      }


      switch (ioControlCode)
      {

      case IOCTL_PROC_KILL:
         if (MyPspTerminateProcess == NULL)
         {
            *(DWORD*)outputBuffer = -1;
            Irp->IoStatus.Information = sizeof(DWORD);
         }
         else
         {
            pid = *(DWORD*)inputBuffer;  //拿到进程pid,指针解引用
            {

               ntstatus = PsLookupProcessByProcessId(pid, &Eprocess);//拿到eprocess结构
               if (!NT_SUCCESS(ntstatus))
               {
                  DbgPrint("Failed to lookup process 0x%x, status %8.8x\n", pid, ntstatus);
                  *(DWORD*)outputBuffer = 1;
                  Irp->IoStatus.Information = sizeof(DWORD);
                  break;
               }
               DbgPrint("Lookup of process 0x%x, PEPROCESS at %8.8x\n", pid, Eprocess);
               ntstatus = MyPspTerminateProcess(Eprocess, 0);  //杀进程
               if (!NT_SUCCESS(ntstatus))
               {
                  DbgPrint("Failed to terminate process 0x%x, status %8.8x\n", pid, ntstatus);
                  *(DWORD*)outputBuffer = 2;
                  Irp->IoStatus.Information = sizeof(DWORD);
                  break;
               }
               *(DWORD*)outputBuffer = 0;
               Irp->IoStatus.Information = sizeof(DWORD);
               DbgPrint("Process 0x%x terminated\n", pid);
            }
         }
         break;


      default:
         break;
      }
      IoCompleteRequest(Irp, IO_NO_INCREMENT);

   }
   return ntstatus;
}

NTSTATUS DispatchCreate(
   IN PDEVICE_OBJECT  pDevObj,
   IN PIRP       pIrp)
{

   pIrp->IoStatus.Status = STATUS_SUCCESS;
   pIrp->IoStatus.Information = 0;
   IoCompleteRequest(pIrp, IO_NO_INCREMENT);
   return STATUS_SUCCESS;
}

ULONG GetFunctionAddr(IN PCWSTR FunctionName)
{
   UNICODE_STRING UniCodeFunctionName;

   RtlInitUnicodeString(&UniCodeFunctionName, FunctionName);
   return (ULONG)MmGetSystemRoutineAddress(&UniCodeFunctionName);

}

VOID DoFind(IN PVOID pContext)  //首地址在此完成
{
   NTSTATUS ret;
   PSYSTEM_MODULE_INFORMATION  module = NULL;
   ULONG n = 0;
   void  *buf = NULL;
   ULONG ntosknlBase;
   ULONG ntosknlEndAddr;
   ULONG curAddr;  
   ULONG i;

   NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetFunctionAddr(L"NtQuerySystemInformation");  //拿到nt函数的地址
   if (!NtQuerySystemInformation)
   {
      DbgPrint("Find NtQuerySystemInformation faild!");
      goto Ret;
   }
   ret = NtQuerySystemInformation(SystemModuleInformation, &n, 0, &n);  //查内核模块信息
   if (NULL == (buf = ExAllocatePoolWithTag(NonPagedPool, n, 'DFSP')))  //拿到大小
   {
      DbgPrint("ExAllocatePool() failed\n");
      goto Ret;
   }
   ret = NtQuerySystemInformation(SystemModuleInformation, buf, n, NULL);
   if (!NT_SUCCESS(ret)) {
      DbgPrint("NtQuerySystemInformation faild!");
      goto Ret;
   }

   module = (PSYSTEM_MODULE_INFORMATION)((PULONG)buf + 1);  //buf前一个整数存储的是模块的大小,后一个才存储的是模块的信息
   ntosknlEndAddr = (ULONG)module->Base + (ULONG)module->Size;  //拿到内核模块的基地址和大小
   ntosknlBase = (ULONG)module->Base;                      
   curAddr = ntosknlBase;
   ExFreePool(buf);
   //MmIsAddressValid(i)
   for (i = curAddr; i <= ntosknlEndAddr; i++)  //暴力搜索特征值
   {
      if (*((ULONG *)i) == (ULONG)code1)
      {
         if (*((ULONG *)(i + 4)) == (ULONG)code2)
         {
            if (*((ULONG *)(i + 8)) == (ULONG)code3)
            {
               if (*((ULONG *)(i + 12)) == (ULONG)code4)
               {
                  MyPspTerminateProcess = (PSPTERPROC)i;  //保存指针首地址
                  break;
               }
            }
         }
      }
   }
Ret:
   PsTerminateSystemThread(STATUS_SUCCESS);
}

VOID GetPspAddr()   //暴力搜索PspTerminateProcess函数的地址
{
   HANDLE hThread;
   PVOID objtowait = 0;
   NTSTATUS dwStatus =
      PsCreateSystemThread(
         &hThread,
         0,
         NULL,
         (HANDLE)0,
         NULL,
         DoFind,  
         NULL
      );
   NTSTATUS st;
   if ((KeGetCurrentIrql()) != PASSIVE_LEVEL)
   {
      st = KfRaiseIrql(PASSIVE_LEVEL);//KeLowerIrql()?

   }
   if ((KeGetCurrentIrql()) != PASSIVE_LEVEL)
   {

      return;
   }

   ObReferenceObjectByHandle(
      hThread,
      THREAD_ALL_ACCESS,
      NULL,
      KernelMode,
      &objtowait,
      NULL
   );

   st = KeWaitForSingleObject(objtowait, Executive, KernelMode, FALSE, NULL); //NULL表示无限期等待.
   return;


}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
   NTSTATUS rc;

   RTL_OSVERSIONINFOW osvi;
   NTSTATUS                ntStatus;
   UNICODE_STRING          deviceNameUnicodeString;
   UNICODE_STRING          deviceLinkUnicodeString;

   RtlInitUnicodeString(&deviceNameUnicodeString,
      deviceNameBuffer);
   RtlInitUnicodeString(&deviceLinkUnicodeString,
      deviceLinkBuffer);

   ntStatus = IoCreateDevice(DriverObject,
      0,
      &deviceNameUnicodeString,
      FILE_DEVICE_SWAP,
      0,
      TRUE,
      &g_HookDevice);

   if (!NT_SUCCESS(ntStatus))
   {
      DbgPrint(("Failed to create device!\n"));
      return ntStatus;
   }
   ntStatus = IoCreateSymbolicLink(&deviceLinkUnicodeString,
      &deviceNameUnicodeString);
   if (!NT_SUCCESS(ntStatus))
   {
      IoDeleteDevice(DriverObject->DeviceObject);
      DbgPrint("Failed to create symbolic link!\n");
      return ntStatus;
   }
   DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =
   DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;//R0和R3通讯必须提供Create函数
   DriverObject->MajorFunction[IRP_MJ_CLOSE] =
   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchControl;

   DriverObject->DriverUnload = OnUnload;

   GetPspAddr();   
   if (MyPspTerminateProcess == NULL)
   {
      DbgPrint("PspFunc Not Find!\n");
   }
   return STATUS_SUCCESS;
}
头文件:

#define FILE_DEVICE_SWAP     0x0000800a

//IOCTL_CODE

#define IOCTL_PROC_KILL   (ULONG) CTL_CODE(FILE_DEVICE_SWAP, 0x8009, METHOD_BUFFERED, FILE_WRITE_ACCESS)

#define IOCTL_TRANSFER_TYPE( _iocontrol)   (_iocontrol & 0x3)

//函数的前16个字节的特征值
#define code1  0x8b55ff8b
#define code2  0xf8e483ec
#define code3  0x530cec83
#define code4  0x56085d8b

>