// 设备I/O控制分发例程
NTSTATUS DeviceIoControlHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
PIO_STACK_LOCATION irpSp;
ULONG ioControlCode;
ULONG inputBufferLength;
ULONG outputBufferLength;
PVOID systemBuffer;
ULONG returnedInformation = 0;
HANDLE currentProcessId;
ULONG flags;
ULONG someGlobalFlag;
// 获取当前进程ID
currentProcessId = PsGetCurrentProcessId();
// 获取当前I/O堆栈位置
irpSp = IoGetCurrentIrpStackLocation(Irp);
if (irpSp == NULL)
{
ZmnDbgPrint(7, "Main.c", 455, "DeviceIoControlHandler", STATUS_INVALID_PARAMETER,
"IO Stack Location is NULL");
status = STATUS_INVALID_PARAMETER;
goto CompleteRequest;
}
// 提取IRP中的常用字段
flags = irpSp->Flags;
systemBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = irpSp->Parameters.DeviceIoControl.InputBufferLength;
ioControlCode = irpSp->Parameters.DeviceIoControl.IoControlCode;
// 权限检查(IOCTL_REGISTER_PROCESS 绕过检查)
if (!IsIoctlAllowed(ioControlCode, currentProcessId))
{
status = STATUS_ACCESS_DENIED;
ZmnDbgPrint(7, "Main.c", 482, "DeviceIoControlHandler", STATUS_ACCESS_DENIED,
"ProcessID %d is not authorized to send IOCTLs ", currentProcessId);
goto CompleteRequest;
}
// 根据IOCTL代码分发处理
switch (ioControlCode)
{
// ----- 0x80002000 范围 -----
...略
case IOCTL_REGISTER_PROCESS: // 0x80002010
ZmnDbgPrint(1, "Main.c", 520, "DeviceIoControlHandler", 0,
"IOCTL_REGISTER_PROCESS");
status = sub_1400102CC(systemBuffer);
break;
···略
case IOCTL_TERMINATE_PROCESS: // 0x80002048
ZmnDbgPrint(1, "Main.c", 645, "DeviceIoControlHandler", 0,
"IOCTL_TERMINATE_PROCESS");
status = ZmnFullPhTerminateProcessById((ULONG_PTR)systemBuffer);
returnedInformation = status;
break;
···略
default:
// 未知IOCTL
ZmnDbgPrint(7, "Main.c", 780, "DeviceIoControlHandler",
STATUS_INVALID_DEVICE_REQUEST,
"Unknown IOCTL code provided 0x%X", ioControlCode);
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
CompleteRequest:
// 设置IRP完成状态和信息
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = returnedInformation;
ZmnDbgPrint(1, "Main.c", 789, "DeviceIoControlHandler", 0,
"Response size %d", returnedInformation);
IofCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
BOOLEAN IsIoctlAllowed(ULONG IoControlCode, HANDLE ProcessId)
{
// 特殊情况:注册进程的IOCTL总是允许
if (IoControlCode == IOCTL_REGISTER_PROCESS)
return TRUE;
LONG adjustedCode = IoControlCode + 2147475372; // 相当于 IoControlCode - 0x80002010
if (adjustedCode <= 0x10)
{
// 在范围内,进一步检查位图
__int64 bitMap = 69633; // 位图值,二进制 10001000000000001? 需要按位测试
// _bittest 测试 (bitMap) 的第 adjustedCode 位
if (_bittest((const LONG*)&bitMap, adjustedCode))
return TRUE; // 位被设置,允许
}
// 默认需要检查进程是否已注册
if (sub_140009BD8(SomeParameter, "Main.c") && !ZmnAuthIsRegisteredProcessId(ProcessId))
return FALSE; // 未注册且未通过安全检查,拒绝
return TRUE; // 所有检查通过
}