Ring3创建事件Ring0设置事件

时间:2025-02-04 10:35:02

应用程序中创建的事件和在内核中创建的事件对象,本质上是同一个东西,在用户模式中,他用句柄表示,在内核模式下,他用KEVENT表示数据结构表示。在应用程序中,所有的内核对象都不会被用户看到,用户看到的知识代表内核对象的对象句柄。
这个代码就是要在Ring3与RIng0之间用一个事件对象。
解决的第一个问题就是如何将Ring3创建的事件传递给驱动:
使用DeviceIoControl,在Ring3中创建一个同步事件,然后用DeviceIoControl将事件句柄传递给驱动程序。需要指出的是句柄和进程是相关的,也就是说一个进程的句柄只有在这个进程中有效。句柄相当于事件对象在进程中的索引,通过这个索引操作系统就可以得到事件对象的指针:ObReferenceObjectByHandle,函数返回一个状态值,表示是否成功获得指针
这个函数在得到指针的同时,会为对象的指针维护一个计数,没记调用的时候会使计数+1。因此为了计数平衡,在使用玩ObReferenceObjectByHandle之后要调用ObDereferenceObject函数,它使计数-1

Ring0(设置事件).h

 #include <ntifs.h>

 #define CTL_EVENT \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define CTL_SET_EVENT \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_BUFFERED,FILE_ANY_ACCESS) #define DEVICE_OBJECT_NAME L"\\Device\\Ring0DeviceObjectName" #define DEVICE_LINK_NAME L"\\DosDevices\\Ring0DeviceLinkName" NTSTATUS PassThroughDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS ControlThroughDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp); NTSTATUS Ring3EventHandleToRing0KernelEvent(HANDLE* EventHandle, ULONG_PTR EventHandleCount); VOID DriverUnload(PDRIVER_OBJECT DriverObject);

Ring0(设置事件).c

 #include "Ring0(设置事件).h"

 PKEVENT  __KernelEvent[] = {  };
ULONG_PTR __KernelEventCount = ; extern
POBJECT_TYPE* ExEventObjectType; NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject = NULL;
UNICODE_STRING DeviceObjectName;
UNICODE_STRING DeviceLinkName; DbgPrint("DriverEntry()\r\n");
DriverObject->DriverUnload = DriverUnload; RtlInitUnicodeString(&DeviceObjectName, DEVICE_OBJECT_NAME); Status = IoCreateDevice(
DriverObject,
NULL,
&DeviceObjectName,
FILE_DEVICE_UNKNOWN,
,
FALSE,
&DeviceObject
);
if (!NT_SUCCESS(Status))
{
return Status;
} //创建设备连接名称
RtlInitUnicodeString(&DeviceLinkName, DEVICE_LINK_NAME); //将设备连接名称与设备名称关联
Status = IoCreateSymbolicLink(&DeviceLinkName, &DeviceObjectName);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(DeviceObject);
return Status;
} //我们要的派遣函数
for (int i = ; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = PassThroughDispatch;
}
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlThroughDispatch; return Status;
} NTSTATUS ControlThroughDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ULONG_PTR Information = ;
PVOID InputData = NULL;
ULONG InputDataLength = ;
PVOID OutputData = NULL;
ULONG OutputDataLength = ;
ULONG IoControlCode = ;
PEPROCESS EProcess = NULL;
PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp); //Irp堆栈
IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
InputData = Irp->AssociatedIrp.SystemBuffer;
OutputData = Irp->AssociatedIrp.SystemBuffer;
InputDataLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
OutputDataLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
switch (IoControlCode)
{
case CTL_EVENT:
{ if (InputData != NULL&&InputDataLength == sizeof(HANDLE) * )
{ Status = Ring3EventHandleToRing0KernelEvent((HANDLE*)InputData, InputDataLength / sizeof(HANDLE)); } Information = ; break; } case CTL_SET_EVENT:
{ DbgPrint("Ring0触发Ring3\r\n");
KeSetEvent(__KernelEvent[], IO_NO_INCREMENT, FALSE); DbgPrint("Ring0等待\r\n");
Status = KeWaitForSingleObject(__KernelEvent[],
Executive, KernelMode, FALSE, NULL); //注意这里的最后一个参数NULL 是永久等待 DbgPrint("Ring3触发Ring0\r\n"); Information = ;
break; } default:
{ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = ; break;
}
} Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Information;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
} NTSTATUS Ring3EventHandleToRing0KernelEvent(HANDLE* EventHandle, ULONG_PTR EventHandleCount)
{
NTSTATUS Status = STATUS_SUCCESS;
PULONG_PTR HandleArray = NULL;
ULONG i = ; if (EventHandle == NULL)
{
return STATUS_UNSUCCESSFUL;
}
__KernelEventCount = EventHandleCount; for (i = ; i < EventHandleCount; i++)
{
Status = ObReferenceObjectByHandle((HANDLE)EventHandle[i],
SYNCHRONIZE,
*ExEventObjectType,
KernelMode,
&__KernelEvent[i],
NULL
);
if (!NT_SUCCESS(Status))
{
break;
}
} if (Status != STATUS_SUCCESS)
{
for (i = ; i < EventHandleCount; i++)
{
if (__KernelEvent[i] != NULL)
{
ObDereferenceObject(__KernelEvent[i]); __KernelEvent[i] = NULL;
}
}
}
return Status;
} VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{ DbgPrint("DriverUnload()\r\n");
} NTSTATUS PassThroughDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS; //LastError()
Irp->IoStatus.Information = ; //ReturnLength
IoCompleteRequest(Irp, IO_NO_INCREMENT); //将Irp返回给Io管理器
return STATUS_SUCCESS;
}

Ring3(创建事件).cpp

 // Ring3(创建事件).cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <windows.h>
#include <iostream> using namespace std; #define CTL_EVENT \
CTL_CODE(FILE_DEVICE_UNKNOWN, 0x830, METHOD_BUFFERED, FILE_ANY_ACCESS) #define CTL_SET_EVENT \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_BUFFERED,FILE_ANY_ACCESS) #define DeviceLinkName L"\\\\.\\Ring0DeviceLinkName" DWORD WINAPI ThreadProc(LPVOID ParameterData); int main()
{
HANDLE DeviceHandle = CreateFile(
DeviceLinkName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL); if (DeviceHandle == INVALID_HANDLE_VALUE)
{
cout << "CreateFile FAIL " << GetLastError() << endl;
return ;
} HANDLE EventHandle[];
for (int i = ; i < ; i++)
{
//用户模式同步事件
EventHandle[i] = CreateEvent(
NULL,
FALSE,
FALSE,
NULL
);
}
BOOL IsOK = FALSE; DWORD ReturnLength = ; IsOK = DeviceIoControl(
DeviceHandle,
CTL_EVENT,
EventHandle,
sizeof(HANDLE)*,
NULL,
,
&ReturnLength,
NULL
); if (IsOK == FALSE)
{
goto Final;
}
//辅助线程
HANDLE ThreadHandle = CreateThread(
NULL,
,
(LPTHREAD_START_ROUTINE)ThreadProc,
(LPVOID)EventHandle,
,
NULL
); IsOK = DeviceIoControl(
DeviceHandle,
CTL_SET_EVENT,
NULL,
,
NULL,
,
&ReturnLength,
NULL); if (IsOK == FALSE)
{
cout << "Send IoCode Error" << endl;
SetEvent(EventHandle[]);
WaitForSingleObject(ThreadHandle, INFINITE);
goto Final;
} WaitForSingleObject(ThreadHandle, INFINITE); Final:
{
for (int i = ; i < ; i++)
{
if (EventHandle[i] != NULL)
{
CloseHandle(EventHandle[i]);
EventHandle[i] = NULL;
}
}
if (ThreadHandle != NULL)
{
CloseHandle(ThreadHandle);
ThreadHandle = NULL;
}
if (DeviceHandle != NULL)
{
CloseHandle(DeviceHandle);
DeviceHandle = NULL;
} } printf("先卸载驱动\r\n");
printf("Input AnyKey To Exit\r\n"); getchar();
return ;
} DWORD WINAPI ThreadProc(LPVOID ParameterData)
{
cout << "Ring3 等啊等" << endl;
DWORD Index = WaitForMultipleObjects(
,
(HANDLE*)ParameterData,
FALSE,
INFINITE
); if (Index == )
{
cout << "ThreadProc EXIT " << endl;
return ;
}
cout << "Ring0触发Ring3" << endl; cout << "put any key Ring3 触发Ring0" << endl; getchar();
getchar(); SetEvent(((HANDLE*)ParameterData)[]);
cout << "ThreadProc EXIT" << endl;
return ; }