线程同步互斥
异常(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