【发布时间】:2017-07-23 11:21:18
【问题描述】:
我有一个设备驱动程序,用于从内核空间读取其他进程虚拟内存,因此我不必使用 ReadProcessMemory 或 WriteProcessMemory 之类的函数。
当我使用结构作为媒介通过DeviceIoControl 将参数传递给内核时,这可以正常工作,但是当我使用无符号长整数等普通变量时,驱动程序会使我的计算机崩溃。
这是一个完美运行的代码示例
(司机):
#define IO_KERNEL_READ_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0701, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
typedef struct _KERNEL_READ_REQUEST
{
ULONG ProcessId;
ULONG Address;
ULONG Response;
ULONG Size;
} KERNEL_READ_REQUEST, *PKERNEL_READ_REQUEST;
if (ControlCode == IO_KERNEL_READ_REQUEST)
{
PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
PKERNEL_READ_REQUEST ReadOutput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
PEPROCESS Process;
PsLookupProcessByProcessId(ReadInput->ProcessId, &Process);
KeReadVirtualMemory(Process, ReadInput->Address, &ReadOutput->Response, ReadInput->Size);
DbgPrintEx(0, 0, "Read Params: %lu, %#010x \n", ReadInput->ProcessId, ReadInput->Address);
DbgPrintEx(0, 0, "Value: %lu \n", ReadOutput->Response);
status = STATUS_SUCCESS;
bytesIO = sizeof(KERNEL_READ_REQUEST);
}
(程序):
template <typename type>
type KernelRead(HANDLE hDriver, ULONG ProcessId, ULONG ReadAddress, SIZE_T ReadSize)
{
if (hDriver == INVALID_HANDLE_VALUE)
return (type)false;
DWORD Return;
DWORD Bytes;
KERNEL_READ_REQUEST ReadRequest;
ReadRequest.ProcessId = ProcessId;
ReadRequest.Address = ReadAddress;
ReadRequest.Size = ReadSize;
if (DeviceIoControl(hDriver, IO_KERNEL_READ_REQUEST, &ReadRequest, sizeof(ReadRequest),
&ReadRequest, sizeof(ReadRequest), &Bytes, NULL)) {
return (type)ReadRequest.Response;
}
else
return (type)false;
}
这是导致问题的原因
#define IO_KERNEL_GET_ID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0703, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
else if (ControlCode == IO_KERNEL_GET_ID)
{
// ProcessId is an ULONG initialized at the driver entry
PULONG OutPut = (PULONG)Irp->AssociatedIrp.SystemBuffer;
OutPut = &ProcessId;
DbgPrintEx(0, 0, "Kernel Get Id: %d \n", *OutPut);
status = STATUS_SUCCESS;
bytesIO = sizeof(OutPut);
}
DWORD KernelGetProcessId(HANDLE hDriver)
{
if (hDriver == INVALID_HANDLE_VALUE)
return false;
ULONG Id;
if (DeviceIoControl(hDriver, IO_KERNEL_GET_ID, &, sizeof(Id),
&Id, sizeof(Id), 0, NULL))
return Id;
else
return false;
}
调用KernelGetProcessId 使我的驱动程序和整个计算机崩溃,如何解决?我在这里做错了什么?
【问题讨论】:
-
据我了解,从驱动程序到用户模式的通信是通过将堆栈(?)或堆栈的某些项目复制到用户空间然后处理来实现的。全局变量保存该值,而我只是在创建一个指向该值的指针并使用它的事实导致了这种情况,因为全局变量不在堆栈上?
-
1) 你没有从
IrpSp->Parameters.DeviceIoControl检查InputBufferLength和OutputBufferLength2) 你没有检查PsLookupProcessByProcessId的结果 3) 你没有打电话给ObfDereferenceObject(Process)4)ULONG Address必须是@ 987654334@ 或ULONG_PTR,你检查Address吗? 5) 您必须分析memory.dmp(或pagefile.sys)以查看崩溃的确切位置 -
@RbMm 这是一个愚蠢的错误,已经找到了修复它。请检查我的答案
-
你做什么 - 不修复
-
您没有发布足够多的代码。例如,您设置了一个名为
OutPut的变量,但我们永远看不到它的用途。
标签: c++ c windows kernel driver