DeviceIoControl с DWORD

Моя ОС Win7 64bit. Я пытаюсь передать значение переменной, а не ее адрес (идентификатор процесса, DWORD) через DeviceIoControl в мой драйвер. Я пробовал это несколько раз, но получил только синие экраны или код ошибки 998.

На стороне пользовательского режима я удостоверяюсь, что hDevice действителен, CTL_CODE выглядит так:

#define SENDPID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)

Тогда я делаю это:

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):

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:

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);
}

Если кто-нибудь может сказать мне, что изменить, пожалуйста, дайте мне знать 🙂

-1

Решение

На стороне приложения, почему FindProcessName() возвращая DWORD* указатель вместо DWORD значение? Или это действительно возвращает DWORD значение, и вы просто ошибочно приведете его к DWORD* указатель?

Определяя pID как DWORD* указатель, sizeof(pID) неправильное значение для передачи DeviceIoControl(), Он передает размер самого указателя (4 на 32 бита, 8 на 64 бита), а не размер DWORD значение, на которое указывают (sizeof(DWORD) всегда 4).

Если pID реальный указатель на DWORD в памяти, вам нужно будет использовать sizeof(*pID) вместо sizeof(pID), Но что, если FindProcessName() возвращает 0? Тогда вы в конечном итоге передали бы нулевой указатель на DeviceIoControl()даже если вы говорите DeviceIoControl() что вы передаете его 4 байта.

Вы должны изменить FindProcessName() вернуть DWORD значение (если оно еще не) вместо DWORD* указатель, а затем используйте & Оператор передать адрес этого DWORD в DeviceIoControl()Например:

DWORD pID = FindProcessName("DayZ.exe");
if (!DeviceIoControl(hDevice, SENDPID, &pID, sizeof(pID), NULL, 0, &BytesIO, 0))

Затем на стороне ядра, просто приведите SystemBuffer получить доступ к значению (после проверки того, что SystemBuffer содержит, как минимум, 4 байта):

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

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector