我正在尝试做什么:
我不确定这段代码是否完全正常工作。我对驱动程序很新,所以我还没有设置调试,虚拟机还没有完成下载(连接速度慢)。
从用户模式应用程序获取进程ID应该正常工作,它应该作为ProcessId存储在PROCESS_INFO结构中。打开的句柄存储在与ProcessHandle相同的结构中,以发送回用户模式应用程序。我不确定如何将数据从内核返回到用户模式,也许有人可以简单解释一下。
这是我的代码:
#include <ntifs.h>
#include <wdf.h>
DRIVER_INITIALIZE DriverEntry;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\GetSysHandle"), SymbolicLink = RTL_CONSTANT_STRING(L"\\DosDevices\\GetSysHandle");
typedef struct _PROCESS_INFO
{
HANDLE ProcessId;
HANDLE ProcessHandle;
}PROCESS_INFO, *PPROCESS_INFO;
BOOLEAN GetSysHandle(PPROCESS_INFO ProcessInfo)
{
NTSTATUS status = STATUS_ACCESS_DENIED;
PEPROCESS eProcess = NULL;
status = PsLookupProcessByProcessId(ProcessInfo->ProcessId, &eProcess);
if ((!NT_SUCCESS(status)) || (!eProcess))
{
return FALSE;
}
status = ObOpenObjectByPointer(eProcess, 0, NULL, 0, 0, KernelMode, &ProcessInfo->ProcessHandle);
if ((!NT_SUCCESS(status)) || (!ProcessInfo->ProcessHandle))
{
ObDereferenceObject(eProcess);
return FALSE;
}
return TRUE;
}
void Unload(PDRIVER_OBJECT pDriverObject)
{
DbgPrint("# GetSysHandle driver unloaded.");
IoDeleteSymbolicLink(&SymbolicLink);
IoDeleteDevice(pDriverObject->DeviceObject);
}
NTSTATUS DriverDispatch(PDEVICE_OBJECT DeviceObject, PIRP irp)
{
PIO_STACK_LOCATION io;
PPROCESS_INFO ProcessInfo;
NTSTATUS status;
io = IoGetCurrentIrpStackLocation(irp);
irp->IoStatus.Information = 0;
switch (io->MajorFunction)
{
case IRP_MJ_CREATE:
status = STATUS_SUCCESS;
break;
case IRP_MJ_CLOSE:
status = STATUS_SUCCESS;
break;
case IRP_MJ_READ:
status = STATUS_SUCCESS;
break;
case IRP_MJ_WRITE:
ProcessInfo = (PPROCESS_INFO)MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
if (!ProcessInfo)
{
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
if (!GetSysHandle(ProcessInfo))
{
DbgPrint("# Failed to get process handle");
status = STATUS_UNSUCCESSFUL;
break;
}
status = STATUS_SUCCESS;
irp->IoStatus.Information = sizeof(PROCESS_INFO);
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
irp->IoStatus.Status = status;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
ULONG i;
DbgPrint("# GetSysHandle driver loaded");
IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
IoCreateSymbolicLink(&SymbolicLink, &DeviceName);
for (i = 0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
{
DriverObject->MajorFunction[i] = DriverDispatch;
}
return STATUS_SUCCESS;
}
答案 0 :(得分:0)
首先(避免混淆):此代码适用于Windows和Windows驱动程序。
我在驱动程序代码中看到的最大问题是您没有在DriverEntry中注册IRP主要功能。您需要将MajorFunction
的{{1}}参数设置为调度函数。如果不分配这些PDRIVER_OBJECT DriverObject
,驱动程序将无法知道在接收命令时要调用的函数。
为此,请将MajorFunctions
的案例分解为不同的调度函数。例如,switch (io->MajorFunction)
将是它自己的函数,你可以像这样声明它:
IRP_MJ_WRITE
在这种情况下,我们希望发给驱动程序的所有读命令都能运行DRIVER_DISPATCH DispatchReadFunction;
函数内的任何代码。所以定义看起来有点像这样:
DispatchReadFunction
我们写完NTSTATUS DispatchReadFunction(_In_ PDEVICE_OBJECT DriverObject, _In_ PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
//Do read code here
return status;
}
函数后,您需要将其分配到DispatchReadFunction
函数中的DriverObject->MajorFunction
,如下所示:
DriverEntry
最后,存根并编写您需要的其他DriverObject->MajorFunction[IRP_MJ_READ] = DispatchReadFunction;
函数,确保将它们分配给IRP_MJ_
MajorFunction
成员。
我的DriverObject
函数看起来像这样(我删除了额外的功能):
DriverEntry
一个好的起点是here。此链接还包含一个简单的示例(驱动程序代码和应用程序代码),可以执行您尝试执行的操作。
祝你好运!