首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DeviceIoControl与DWORD

DeviceIoControl与DWORD
EN

Stack Overflow用户
提问于 2017-05-09 20:21:38
回答 1查看 525关注 0票数 0

我的操作系统是Win7 64位。我试图通过DeviceIoControl将变量的值传递给我的驱动程序,而不是它的地址(process,DWORD)。我试过几次,但只得到了蓝屏或998的错误代码。

在用户模式方面,我确保hDevice是有效的,CTL_CODE如下所示:

代码语言:javascript
复制
#define SENDPID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)

那我就这么做:

代码语言:javascript
复制
DWORD pID = FindProcessName("someprocess.exe");
if (!pID) return false;
if (!DeviceIoControl(hDevice, SENDPID, &pID, sizeof(pID), NULL, 0, &BytesIO, 0))
{
    cout << GetLastError() << endl;
    return false;
}

在Kernelmode (DriverEntry)上:

代码语言:javascript
复制
NTSTATUS DriverEntry(PDRIVER_OBJECT Object, PUNICODE_STRING RegistryPath)
{
UNICODE_STRING dNUS = { 0 };
RtlInitUnicodeString(&dNUS, L"\\Device\\testdriver");

UNICODE_STRING dSLU = { 0 };
RtlInitUnicodeString(&dSLU, L"\\DosDevices\\testdriver");

IoCreateDevice(Object, 0, &dNUS, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObj);
IoCreateSymbolicLink(&dSLU, &dNUS);

Object->MajorFunction[IRP_MJ_CREATE] = CCreate;
Object->MajorFunction[IRP_MJ_CLOSE] = CClose;
Object->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IOCTL;
Object->DriverUnload = Unload;

return(STATUS_SUCCESS);
}

我的IOCTL功能:

代码语言:javascript
复制
NTSTATUS IOCTL(PDEVICE_OBJECT Object, PIRP IRP)
{
PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(IRP);
size_t size = 0;
DWORD pID = 0;

if (StackLocation->Parameters.DeviceIoControl.IoControlCode == SENDPID)
{
    pID = IRP->AssociatedIrp.SystemBuffer;
    size = sizeof(pID);
}

IRP->IoStatus.Status = STATUS_SUCCESS;
IRP->IoStatus.Information = size;
IofCompleteRequest(IRP, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}

如果有人能告诉我要改什么,请告诉我:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-09 20:54:06

在应用程序端,为什么FindProcessName()返回一个DWORD*指针而不是一个DWORD值?或者,它真的返回一个DWORD值,而您只是错误地将其类型转换为一个DWORD*指针吗?

通过将pID定义为DWORD*指针,sizeof(pID)是传递给DeviceIoControl()的错误值。它传递指针本身的大小(32位上的4位,64位上的8位),而不是指向的DWORD值的大小(sizeof(DWORD)总是4)。

如果pID是内存中指向DWORD的真正指针,则需要使用sizeof(*pID)而不是sizeof(pID)。但是如果FindProcessName()返回0呢?然后,您将传递一个空指针到DeviceIoControl(),即使您告诉DeviceIoControl()您要传递它的4个字节。

您应该更改FindProcessName()以返回一个DWORD值(如果它尚未返回),而不是一个DWORD*指针,然后使用&操作符将该DWORD的地址传递给DeviceIoControl(),例如:

代码语言:javascript
复制
DWORD pID = FindProcessName("DayZ.exe");
if (!DeviceIoControl(hDevice, SENDPID, &pID, sizeof(pID), NULL, 0, &BytesIO, 0))

然后在内核端,只需键入SystemBuffer以访问值(当然,在验证SystemBuffer至少包含4个字节之后):

代码语言:javascript
复制
NTSTATUS IOCTL(PDEVICE_OBJECT Object, PIRP IRP)
{
    PIO_STACK_LOCATION StackLocation = IoGetCurrentIrpStackLocation(IRP);
    size_t size = 0;
    DWORD pID = 0;

    if ((StackLocation->Parameters.DeviceIoControl.IoControlCode == SENDPID) &&
        (StackLocation->Parameters.DeviceIoControl.InputBufferLength >= sizeof(pID)))
    {
        pID = *(DWORD*)(IRP->AssociatedIrp.SystemBuffer);
        size = sizeof(pID);
    }

    IRP->IoStatus.Status = STATUS_SUCCESS;
    IRP->IoStatus.Information = size;
    IofCompleteRequest(IRP, IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43879179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档