Windows内核安全
15、阶段合集
1、课程目标
- 综合运用内核安全技术
- 构建完整的进程保护系统
- 实现内核级安全监控框架
- 掌握驱动开发最佳实践
2、名词解释
| 术语 | 解释 |
|---|---|
| EDR | Endpoint Detection and Response终端检测与响应 |
| 内核回调 | 内核事件通知机制 |
| 对象监控 | 句柄访问控制 |
| 防护驱动 | 提供系统保护功能的内核驱动 |
3、使用工具
| 工具 | 用途 |
|---|---|
| Visual Studio + WDK | 驱动开发 |
| WinDbg | 内核调试 |
| Driver Verifier | 驱动验证 |
| OSR Driver Loader | 驱动加载 |
4、技术原理
4.1、综合防护架构
┌─────────────────────────────────────────────────────────────┐
│ 内核安全防护架构 │
│ │
│ 用户模式 (Ring3) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 用户界面 │ 配置管理 │ 日志查看 │ 策略引擎 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ DeviceIoControl │
│ ↓ │
│ ─────────────────── Ring0/Ring3边界 ─────────────────── │
│ ↓ │
│ 内核模式 (Ring0) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 主驱动程序 │ │
│ │ ┌──────────┬──────────┬──────────┬──────────┐ │ │
│ │ │进程监控 │线程监控 │模块监控 │注册表监控│ │ │
│ │ └──────────┴──────────┴──────────┴──────────┘ │ │
│ │ ┌──────────┬──────────┬──────────┬──────────┐ │ │
│ │ │对象监控 │文件监控 │网络监控 │内存监控 │ │ │
│ │ └──────────┴──────────┴──────────┴──────────┘ │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ 策略执行引擎 │ │ │
│ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │
│ │ │ │白名单 │ │黑名单 │ │规则匹配 │ │ │ │
│ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
5、代码实现
5.1、项目1:综合安全驱动框架
// SecurityDriver.h - 安全驱动头文件
#ifndef SECURITY_DRIVER_H
#define SECURITY_DRIVER_H
#include <ntddk.h>
#include <wdm.h>
// 设备名称
#define DEVICE_NAME L"\\Device\\SecurityDriver"
#define SYMBOLIC_NAME L"\\DosDevices\\SecurityDriver"
// IOCTL定义
#define IOCTL_ADD_PROTECTED_PID CTL_CODE(0x8000, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_REMOVE_PROTECTED_PID CTL_CODE(0x8000, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_ADD_BLOCKED_IMAGE CTL_CODE(0x8000, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_GET_EVENT_LOG CTL_CODE(0x8000, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SET_PROTECTION_MODE CTL_CODE(0x8000, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
// 保护模式
typedef enum _PROTECTION_MODE {
MODE_MONITOR_ONLY = 0, // 仅监控
MODE_ALERT, // 监控+告警
MODE_BLOCK // 监控+阻止
} PROTECTION_MODE;
// 事件类型
typedef enum _SECURITY_EVENT_TYPE {
EVENT_PROCESS_CREATE = 1,
EVENT_PROCESS_TERMINATE,
EVENT_THREAD_CREATE_REMOTE,
EVENT_MODULE_LOAD,
EVENT_REGISTRY_MODIFY,
EVENT_HANDLE_OPEN_BLOCKED,
EVENT_IMAGE_BLOCKED
} SECURITY_EVENT_TYPE;
// 安全事件
typedef struct _SECURITY_EVENT {
LARGE_INTEGER Timestamp;
SECURITY_EVENT_TYPE EventType;
HANDLE ProcessId;
HANDLE TargetId;
WCHAR Details[256];
} SECURITY_EVENT, *PSECURITY_EVENT;
// 驱动上下文
typedef struct _DRIVER_CONTEXT {
PDEVICE_OBJECT DeviceObject;
PVOID ProcessCallback;
PVOID ThreadCallback;
PVOID ImageCallback;
PVOID ObjectCallback;
LARGE_INTEGER RegistryCallback;
PROTECTION_MODE Mode;
ULONG ProtectedPids[64];
ULONG ProtectedCount;
WCHAR BlockedImages[32][260];
ULONG BlockedImageCount;
LIST_ENTRY EventList;
KSPIN_LOCK EventLock;
ULONG EventCount;
FAST_MUTEX ConfigMutex;
} DRIVER_CONTEXT, *PDRIVER_CONTEXT;
// 全局上下文
extern DRIVER_CONTEXT g_Context;
// 函数声明
NTSTATUS InitializeCallbacks();
VOID CleanupCallbacks();
BOOLEAN IsProcessProtected(HANDLE ProcessId);
BOOLEAN IsImageBlocked(PUNICODE_STRING ImagePath);
VOID LogSecurityEvent(SECURITY_EVENT_TYPE Type, HANDLE ProcessId,
HANDLE TargetId, PCWSTR Details);
#endif
// SecurityDriver.c - 主驱动文件
#include "SecurityDriver.h"
#include <ntstrsafe.h>
DRIVER_CONTEXT g_Context = {0};
// 检查进程是否受保护
BOOLEAN IsProcessProtected(HANDLE ProcessId) {
ExAcquireFastMutex(&g_Context.ConfigMutex);
for (ULONG i = 0; i < g_Context.ProtectedCount; i++) {
if (g_Context.ProtectedPids[i] == (ULONG)(ULONG_PTR)ProcessId) {
ExReleaseFastMutex(&g_Context.ConfigMutex);
return TRUE;
}
}
ExReleaseFastMutex(&g_Context.ConfigMutex);
return FALSE;
}
// 检查镜像是否被阻止
BOOLEAN IsImageBlocked(PUNICODE_STRING ImagePath) {
if (!ImagePath || !ImagePath->Buffer) return FALSE;
ExAcquireFastMutex(&g_Context.ConfigMutex);
for (ULONG i = 0; i < g_Context.BlockedImageCount; i++) {
UNICODE_STRING blocked;
RtlInitUnicodeString(&blocked, g_Context.BlockedImages[i]);
// 后缀匹配
if (ImagePath->Length >= blocked.Length) {
UNICODE_STRING suffix;
suffix.Buffer = ImagePath->Buffer +
(ImagePath->Length - blocked.Length) / sizeof(WCHAR);
suffix.Length = blocked.Length;
suffix.MaximumLength = blocked.Length;
if (RtlEqualUnicodeString(&suffix, &blocked, TRUE)) {
ExReleaseFastMutex(&g_Context.ConfigMutex);
return TRUE;
}
}
}
ExReleaseFastMutex(&g_Context.ConfigMutex);
return FALSE;
}
// 记录安全事件
VOID LogSecurityEvent(
SECURITY_EVENT_TYPE Type,
HANDLE ProcessId,
HANDLE TargetId,
PCWSTR Details
) {
KIRQL oldIrql;
PSECURITY_EVENT event = (PSECURITY_EVENT)ExAllocatePoolWithTag(
NonPagedPool, sizeof(SECURITY_EVENT), 'tnvE');
if (!event) return;
KeQuerySystemTime(&event->Timestamp);
event->EventType = Type;
event->ProcessId = ProcessId;
event->TargetId = TargetId;
if (Details) {
RtlStringCbCopyW(event->Details, sizeof(event->Details), Details);
}
KeAcquireSpinLock(&g_Context.EventLock, &oldIrql);
// 限制事件数量
if (g_Context.EventCount >= 10000) {
PLIST_ENTRY oldest = RemoveHeadList(&g_Context.EventList);
PSECURITY_EVENT oldEvent = CONTAINING_RECORD(oldest, SECURITY_EVENT,
*(PLIST_ENTRY)((PUCHAR)oldest - sizeof(LIST_ENTRY)));
ExFreePoolWithTag(oldEvent, 'tnvE');
g_Context.EventCount--;
}
InsertTailList(&g_Context.EventList, (PLIST_ENTRY)event);
g_Context.EventCount++;
KeReleaseSpinLock(&g_Context.EventLock, oldIrql);
DbgPrint("[Security] Event: Type=%d, PID=%d, Target=%d, %ws\n",
Type, (ULONG)(ULONG_PTR)ProcessId,
(ULONG)(ULONG_PTR)TargetId, Details ? Details : L"");
}
// 进程创建回调
VOID ProcessNotifyCallback(
PEPROCESS Process,
HANDLE ProcessId,
PPS_CREATE_NOTIFY_INFO CreateInfo
) {
UNREFERENCED_PARAMETER(Process);
if (CreateInfo) {
// 进程创建
WCHAR details[256];
if (CreateInfo->ImageFileName) {
RtlStringCbPrintfW(details, sizeof(details),
L"Image: %wZ", CreateInfo->ImageFileName);
// 检查是否需要阻止
if (g_Context.Mode == MODE_BLOCK &&
IsImageBlocked(CreateInfo->ImageFileName)) {
LogSecurityEvent(EVENT_IMAGE_BLOCKED,
CreateInfo->ParentProcessId, ProcessId, details);
CreateInfo->CreationStatus = STATUS_ACCESS_DENIED;
return;
}
}
LogSecurityEvent(EVENT_PROCESS_CREATE,
CreateInfo->ParentProcessId, ProcessId, details);
} else {
// 进程退出
LogSecurityEvent(EVENT_PROCESS_TERMINATE, ProcessId, NULL, NULL);
// 从保护列表移除
ExAcquireFastMutex(&g_Context.ConfigMutex);
for (ULONG i = 0; i < g_Context.ProtectedCount; i++) {
if (g_Context.ProtectedPids[i] == (ULONG)(ULONG_PTR)ProcessId) {
g_Context.ProtectedPids[i] =
g_Context.ProtectedPids[--g_Context.ProtectedCount];
break;
}
}
ExReleaseFastMutex(&g_Context.ConfigMutex);
}
}
// 线程创建回调
VOID ThreadNotifyCallback(
HANDLE ProcessId,
HANDLE ThreadId,
BOOLEAN Create
) {
if (!Create) return;
HANDLE currentPid = PsGetCurrentProcessId();
// 检测远程线程
if (currentPid != ProcessId && ProcessId != (HANDLE)4) {
WCHAR details[256];
RtlStringCbPrintfW(details, sizeof(details),
L"Remote thread from PID %d", (ULONG)(ULONG_PTR)currentPid);
LogSecurityEvent(EVENT_THREAD_CREATE_REMOTE, currentPid, ProcessId, details);
}
}
// 模块加载回调
VOID ImageLoadCallback(
PUNICODE_STRING FullImageName,
HANDLE ProcessId,
PIMAGE_INFO ImageInfo
) {
if (ImageInfo->SystemModeImage) return; // 忽略内核模块
WCHAR details[256];
RtlStringCbPrintfW(details, sizeof(details), L"%wZ", FullImageName);
LogSecurityEvent(EVENT_MODULE_LOAD, ProcessId, NULL, details);
}
// 对象回调
OB_PREOP_CALLBACK_STATUS ObjectPreCallback(
PVOID RegistrationContext,
POB_PRE_OPERATION_INFORMATION OperationInfo
) {
UNREFERENCED_PARAMETER(RegistrationContext);
if (OperationInfo->ObjectType != *PsProcessType &&
OperationInfo->ObjectType != *PsThreadType) {
return OB_PREOP_SUCCESS;
}
HANDLE targetPid;
if (OperationInfo->ObjectType == *PsProcessType) {
targetPid = PsGetProcessId((PEPROCESS)OperationInfo->Object);
} else {
targetPid = PsGetThreadProcessId((PETHREAD)OperationInfo->Object);
}
HANDLE currentPid = PsGetCurrentProcessId();
// 检查是否访问受保护进程
if (targetPid != currentPid && IsProcessProtected(targetPid)) {
// 不限制受保护进程自己
if (!IsProcessProtected(currentPid)) {
if (OperationInfo->Operation == OB_OPERATION_HANDLE_CREATE) {
ACCESS_MASK denyMask = PROCESS_TERMINATE | PROCESS_VM_WRITE |
PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD |
THREAD_TERMINATE | THREAD_SUSPEND_RESUME | THREAD_SET_CONTEXT;
ACCESS_MASK original =
OperationInfo->Parameters->CreateHandleInformation.DesiredAccess;
OperationInfo->Parameters->CreateHandleInformation.DesiredAccess &= ~denyMask;
if (original != OperationInfo->Parameters->CreateHandleInformation.DesiredAccess) {
WCHAR details[256];
RtlStringCbPrintfW(details, sizeof(details),
L"Access 0x%X blocked for PID %d",
original & denyMask, (ULONG)(ULONG_PTR)targetPid);
LogSecurityEvent(EVENT_HANDLE_OPEN_BLOCKED, currentPid, targetPid, details);
}
}
}
}
return OB_PREOP_SUCCESS;
}
// 注册表回调
NTSTATUS RegistryCallback(
PVOID CallbackContext,
PVOID Argument1,
PVOID Argument2
) {
UNREFERENCED_PARAMETER(CallbackContext);
REG_NOTIFY_CLASS notifyClass = (REG_NOTIFY_CLASS)(ULONG_PTR)Argument1;
if (notifyClass == RegNtPreSetValueKey ||
notifyClass == RegNtPreDeleteValueKey) {
LogSecurityEvent(EVENT_REGISTRY_MODIFY,
PsGetCurrentProcessId(), NULL, L"Registry modification");
}
return STATUS_SUCCESS;
}
// 初始化回调
NTSTATUS InitializeCallbacks() {
NTSTATUS status;
// 进程回调
status = PsSetCreateProcessNotifyRoutineEx(ProcessNotifyCallback, FALSE);
if (!NT_SUCCESS(status)) {
DbgPrint("[Security] Failed to register process callback: 0x%X\n", status);
return status;
}
// 线程回调
status = PsSetCreateThreadNotifyRoutine(ThreadNotifyCallback);
if (!NT_SUCCESS(status)) {
PsSetCreateProcessNotifyRoutineEx(ProcessNotifyCallback, TRUE);
return status;
}
// 模块回调
status = PsSetLoadImageNotifyRoutine(ImageLoadCallback);
if (!NT_SUCCESS(status)) {
PsSetCreateProcessNotifyRoutineEx(ProcessNotifyCallback, TRUE);
PsRemoveCreateThreadNotifyRoutine(ThreadNotifyCallback);
return status;
}
// 对象回调
OB_OPERATION_REGISTRATION opReg[2] = {
{ PsProcessType, OB_OPERATION_HANDLE_CREATE, ObjectPreCallback, NULL },
{ PsThreadType, OB_OPERATION_HANDLE_CREATE, ObjectPreCallback, NULL }
};
UNICODE_STRING altitude;
RtlInitUnicodeString(&altitude, L"321000");
OB_CALLBACK_REGISTRATION callbackReg = {
OB_FLT_REGISTRATION_VERSION, 2, altitude, NULL, opReg
};
status = ObRegisterCallbacks(&callbackReg, &g_Context.ObjectCallback);
if (!NT_SUCCESS(status)) {
DbgPrint("[Security] Failed to register object callback: 0x%X\n", status);
// 继续,对象回调可选
}
// 注册表回调
RtlInitUnicodeString(&altitude, L"320000");
status = CmRegisterCallbackEx(RegistryCallback, &altitude,
NULL, NULL, &g_Context.RegistryCallback, NULL);
DbgPrint("[Security] Callbacks initialized\n");
return STATUS_SUCCESS;
}
// 清理回调
VOID CleanupCallbacks() {
PsSetCreateProcessNotifyRoutineEx(ProcessNotifyCallback, TRUE);
PsRemoveCreateThreadNotifyRoutine(ThreadNotifyCallback);
PsRemoveLoadImageNotifyRoutine(ImageLoadCallback);
if (g_Context.ObjectCallback) {
ObUnRegisterCallbacks(g_Context.ObjectCallback);
}
if (g_Context.RegistryCallback.QuadPart) {
CmUnRegisterCallback(g_Context.RegistryCallback);
}
DbgPrint("[Security] Callbacks cleaned up\n");
}
5.2、项目2:用户模式控制程序
// SecurityClient.c - 用户模式控制程序
#include <windows.h>
#include <stdio.h>
#define DEVICE_NAME "\\\\.\\SecurityDriver"
// IOCTL定义(与驱动一致)
#define IOCTL_ADD_PROTECTED_PID CTL_CODE(0x8000, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_REMOVE_PROTECTED_PID CTL_CODE(0x8000, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_ADD_BLOCKED_IMAGE CTL_CODE(0x8000, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_GET_EVENT_LOG CTL_CODE(0x8000, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_SET_PROTECTION_MODE CTL_CODE(0x8000, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _SECURITY_CLIENT {
HANDLE hDevice;
} SECURITY_CLIENT, *PSECURITY_CLIENT;
BOOL SecurityClient_Connect(PSECURITY_CLIENT client) {
client->hDevice = CreateFileA(DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
return client->hDevice != INVALID_HANDLE_VALUE;
}
void SecurityClient_Disconnect(PSECURITY_CLIENT client) {
if (client->hDevice != INVALID_HANDLE_VALUE) {
CloseHandle(client->hDevice);
}
}
BOOL SecurityClient_ProtectPid(PSECURITY_CLIENT client, DWORD pid, BOOL protect) {
DWORD bytesReturned;
DWORD ioctl = protect ? IOCTL_ADD_PROTECTED_PID : IOCTL_REMOVE_PROTECTED_PID;
return DeviceIoControl(client->hDevice, ioctl,
&pid, sizeof(pid), NULL, 0, &bytesReturned, NULL);
}
BOOL SecurityClient_BlockImage(PSECURITY_CLIENT client, const WCHAR* imageName) {
DWORD bytesReturned;
DWORD len = (DWORD)(wcslen(imageName) + 1) * sizeof(WCHAR);
return DeviceIoControl(client->hDevice, IOCTL_ADD_BLOCKED_IMAGE,
(PVOID)imageName, len, NULL, 0, &bytesReturned, NULL);
}
BOOL SecurityClient_SetMode(PSECURITY_CLIENT client, DWORD mode) {
DWORD bytesReturned;
return DeviceIoControl(client->hDevice, IOCTL_SET_PROTECTION_MODE,
&mode, sizeof(mode), NULL, 0, &bytesReturned, NULL);
}
void PrintUsage(const char* name) {
printf("Usage:\n");
printf(" %s protect <pid> - Protect a process\n", name);
printf(" %s unprotect <pid> - Remove protection\n", name);
printf(" %s block <name.exe> - Block an image\n", name);
printf(" %s mode <0|1|2> - Set protection mode\n", name);
printf(" 0=Monitor, 1=Alert, 2=Block\n");
}
int main(int argc, char* argv[]) {
SECURITY_CLIENT client = {0};
printf("=== Security Driver Client ===\n\n");
if (!SecurityClient_Connect(&client)) {
printf("Failed to connect to driver. Error: %d\n", GetLastError());
printf("Make sure the driver is loaded.\n");
return 1;
}
printf("Connected to security driver.\n");
if (argc < 2) {
PrintUsage(argv[0]);
SecurityClient_Disconnect(&client);
return 0;
}
if (strcmp(argv[1], "protect") == 0 && argc >= 3) {
DWORD pid = atoi(argv[2]);
if (SecurityClient_ProtectPid(&client, pid, TRUE)) {
printf("Process %d is now protected.\n", pid);
} else {
printf("Failed to protect process. Error: %d\n", GetLastError());
}
}
else if (strcmp(argv[1], "unprotect") == 0 && argc >= 3) {
DWORD pid = atoi(argv[2]);
if (SecurityClient_ProtectPid(&client, pid, FALSE)) {
printf("Process %d protection removed.\n", pid);
}
}
else if (strcmp(argv[1], "block") == 0 && argc >= 3) {
WCHAR imageName[260];
MultiByteToWideChar(CP_ACP, 0, argv[2], -1, imageName, 260);
if (SecurityClient_BlockImage(&client, imageName)) {
printf("Image '%s' is now blocked.\n", argv[2]);
}
}
else if (strcmp(argv[1], "mode") == 0 && argc >= 3) {
DWORD mode = atoi(argv[2]);
if (SecurityClient_SetMode(&client, mode)) {
const char* modeNames[] = {"Monitor Only", "Alert", "Block"};
printf("Protection mode set to: %s\n", modeNames[mode]);
}
}
else if (strcmp(argv[1], "self") == 0) {
// 保护当前进程
DWORD pid = GetCurrentProcessId();
if (SecurityClient_ProtectPid(&client, pid, TRUE)) {
printf("Current process (%d) is now protected.\n", pid);
printf("Try to kill this process with Task Manager...\n");
printf("Press Enter to exit and remove protection.\n");
getchar();
}
}
else {
PrintUsage(argv[0]);
}
SecurityClient_Disconnect(&client);
return 0;
}
5.3、项目3:驱动IOCTL处理
// SecurityIoctl.c - IOCTL处理
#include "SecurityDriver.h"
NTSTATUS DispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PVOID buffer = Irp->AssociatedIrp.SystemBuffer;
ULONG inputLen = irpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG outputLen = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
NTSTATUS status = STATUS_SUCCESS;
ULONG bytesReturned = 0;
switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_ADD_PROTECTED_PID: {
if (inputLen >= sizeof(ULONG)) {
ULONG pid = *(PULONG)buffer;
ExAcquireFastMutex(&g_Context.ConfigMutex);
if (g_Context.ProtectedCount < 64) {
g_Context.ProtectedPids[g_Context.ProtectedCount++] = pid;
DbgPrint("[Security] Protected PID: %d\n", pid);
} else {
status = STATUS_INSUFFICIENT_RESOURCES;
}
ExReleaseFastMutex(&g_Context.ConfigMutex);
}
break;
}
case IOCTL_REMOVE_PROTECTED_PID: {
if (inputLen >= sizeof(ULONG)) {
ULONG pid = *(PULONG)buffer;
ExAcquireFastMutex(&g_Context.ConfigMutex);
for (ULONG i = 0; i < g_Context.ProtectedCount; i++) {
if (g_Context.ProtectedPids[i] == pid) {
g_Context.ProtectedPids[i] =
g_Context.ProtectedPids[--g_Context.ProtectedCount];
DbgPrint("[Security] Unprotected PID: %d\n", pid);
break;
}
}
ExReleaseFastMutex(&g_Context.ConfigMutex);
}
break;
}
case IOCTL_ADD_BLOCKED_IMAGE: {
if (inputLen > 0 && buffer) {
ExAcquireFastMutex(&g_Context.ConfigMutex);
if (g_Context.BlockedImageCount < 32) {
RtlCopyMemory(g_Context.BlockedImages[g_Context.BlockedImageCount],
buffer, min(inputLen, 260 * sizeof(WCHAR)));
g_Context.BlockedImageCount++;
DbgPrint("[Security] Blocked image added\n");
}
ExReleaseFastMutex(&g_Context.ConfigMutex);
}
break;
}
case IOCTL_SET_PROTECTION_MODE: {
if (inputLen >= sizeof(ULONG)) {
ULONG mode = *(PULONG)buffer;
if (mode <= MODE_BLOCK) {
g_Context.Mode = (PROTECTION_MODE)mode;
DbgPrint("[Security] Mode set to: %d\n", mode);
}
}
break;
}
case IOCTL_GET_EVENT_LOG: {
// 返回事件日志
KIRQL oldIrql;
KeAcquireSpinLock(&g_Context.EventLock, &oldIrql);
// 实现事件导出...
KeReleaseSpinLock(&g_Context.EventLock, oldIrql);
break;
}
default:
status = STATUS_INVALID_DEVICE_REQUEST;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = bytesReturned;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
6、课后作业
- 扩展驱动添加文件系统监控
- 实现事件日志的持久化存储
- 添加网络连接监控功能
- 实现规则配置文件的加载
7、最佳实践
-
安全编码
- 所有用户输入必须验证
- 使用安全的字符串函数
- 正确处理异常
-
性能优化
- 避免在回调中执行耗时操作
- 使用工作项处理复杂任务
- 合理使用缓存
-
稳定性
- 充分测试各种边界条件
- 使用Driver Verifier
- 正确处理卸载
-
兼容性
- 测试多个Windows版本
- 考虑32/64位兼容
- 处理版本差异
8、扩展阅读
- Windows驱动开发最佳实践
- EDR产品架构分析
- 内核安全对抗技术