功能:应用层与内核可以通讯,交互数据,这里演示的是常规IO输入输出的通讯。
学习自B站 UP主:写驱动的女装大佬《中级篇第三课》
设备扩展
* IoCreateDevice创建设备
参数1:driver 设备对象;
参数2:0 设备扩展的大小;
参数3:&deviceanme 设备名字;
参数4:FILE_DEVICE_UNKNOWN(未知设备) 设备类型
参数5:0 默认参数
参数6:TRUE 默认参数
参数7:&pdevice 输出参数,设备创建成功后,会把设备对象传出来
*/
status = IoCreateDevice(driver,200, &deviceanme, FILE_DEVICE_UNKNOWN,0,TRUE,&pdevice);
驱动层代码
#include <ntddk.h>
#include <windef.h>
#define DEVICE_NAME L"\\Device\\MyfirstDevice"
#define SYM_NAME L"\\??\\MyfirstDevice"
#define IOCTL_MUL CTL_CODE(FILE_DEVICE_UNKNOWN,0x9888,METHOD_BUFFERED,FILE_ANY_ACCESS)
VOID nothing(HANDLE ppid, HANDLE mypid, BOOLEAN bcreate)
{
DbgPrint("ProcessNotify\n");
}
NTSTATUS MyCreate(PDEVICE_OBJECT pdevice, PIRP pirp)
{
NTSTATUS status = STATUS_SUCCESS;
DbgPrint("My Device has be opende\n");
pirp->IoStatus.Status = status;
pirp->IoStatus.Information = 0;
IoCompleteRequest(pirp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS MyClose(PDEVICE_OBJECT pdevice, PIRP pirp)
{
NTSTATUS status = STATUS_SUCCESS;
DbgPrint("My Device has be closed\n");
pirp->IoStatus.Status = status;
pirp->IoStatus.Information = 0;
IoCompleteRequest(pirp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS MyCleanUp(PDEVICE_OBJECT pdevice, PIRP pirp)
{
NTSTATUS status = STATUS_SUCCESS;
DbgPrint("My Device has be CleanUped\n");
pirp->IoStatus.Status = status;
pirp->IoStatus.Information = 0;
IoCompleteRequest(pirp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS MyRead(PDEVICE_OBJECT pdevice, PIRP pirp)
{
NTSTATUS status = STATUS_SUCCESS;
DbgPrint("My Device has be Readed\n");
PIO_STACK_LOCATION pstack = IoGetCurrentIrpStackLocation(pirp);
ULONG readsize = pstack->Parameters.Read.Length;
PCHAR readbuffer = pirp->AssociatedIrp.SystemBuffer;
RtlCopyMemory(readbuffer, "This Message Come From Kernel.", strlen("This Message Come From Kernel."));
pirp->IoStatus.Status = status;
pirp->IoStatus.Information = strlen("This Message Come From Kernel.");
DbgPrint("Really Read Info Len is %d", strlen("This Message Come From Kernel."));
IoCompleteRequest(pirp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS MyWrite(PDEVICE_OBJECT pdevice, PIRP pirp)
{
NTSTATUS status = STATUS_SUCCESS;
DbgPrint("My Device has be Writeed\n");
PIO_STACK_LOCATION pstack = IoGetCurrentIrpStackLocation(pirp);
ULONG writesize = pstack->Parameters.Write.Length;
PCHAR writebuffer = pirp->AssociatedIrp.SystemBuffer;
RtlZeroMemory(pdevice->DeviceExtension,200);
RtlCopyMemory(pdevice->DeviceExtension, writebuffer, writesize);
DbgPrint("--%p--%s\n", writebuffer, (PCHAR)pdevice->DeviceExtension);
pirp->IoStatus.Status = status;
pirp->IoStatus.Information = 13;
IoCompleteRequest(pirp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS MyControl(PDEVICE_OBJECT pdevice, PIRP pirp)
{
NTSTATUS status = STATUS_SUCCESS;
DbgPrint("My Device has be Controled\n");
PIO_STACK_LOCATION pstack = IoGetCurrentIrpStackLocation(pirp);
ULONG iocode = pstack->Parameters.DeviceIoControl.IoControlCode;
ULONG inlen = pstack->Parameters.DeviceIoControl.InputBufferLength;
ULONG outlen = pstack->Parameters.DeviceIoControl.OutputBufferLength;
ULONG ioinfo = 0;
DbgPrint("--kernel ControlCode %d--\n", iocode);
switch (iocode)
{
case IOCTL_MUL:
{
DWORD indata = *(PDWORD)pirp->AssociatedIrp.SystemBuffer;
DbgPrint("--Kernel Indata %d--\n",indata);
indata = indata * 5;
*(PDWORD)pirp->AssociatedIrp.SystemBuffer = indata;
ioinfo = 666;
break;
}
default:
status = STATUS_UNSUCCESSFUL;
ioinfo = 0;
break;
}
pirp->IoStatus.Status = status;
pirp->IoStatus.Information = ioinfo;
IoCompleteRequest(pirp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID DrvUnload(PDRIVER_OBJECT pdriver)
{
DbgPrint("Unload\n");
if (pdriver->DeviceObject)
{
IoDeleteDevice(pdriver->DeviceObject);
UNICODE_STRING symname = {
0 };
RtlInitUnicodeString(&symname, SYM_NAME);
IoDeleteSymbolicLink(&symname);
}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING deviceanme = {
0 };
PDEVICE_OBJECT pdevice = NULL;
driver->DriverUnload=DrvUnload;
RtlInitUnicodeString(&deviceanme, DEVICE_NAME);
status = IoCreateDevice(driver,200, &deviceanme, FILE_DEVICE_UNKNOWN,0,TRUE,&pdevice);
if (!NT_SUCCESS(status))
{
DbgPrint("Create Device Failed:%x\n",status);
return status;
}
pdevice->Flags |= DO_BUFFERED_IO;
UNICODE_STRING symname = {
0 };
RtlInitUnicodeString(&symname, SYM_NAME);
status = IoCreateSymbolicLink(&symname, &deviceanme);
if (!NT_SUCCESS(status))
{
DbgPrint("Create SymbolicLink Failed:%x\n", status);
IoDeleteDevice(pdevice);
return status;
}
driver->MajorFunction[IRP_MJ_CREATE] = MyCreate;
driver->MajorFunction[IRP_MJ_CLOSE] = MyClose;
driver->MajorFunction[IRP_MJ_CLEANUP] = MyCleanUp;
driver->MajorFunction[IRP_MJ_READ] = MyRead;
driver->MajorFunction[IRP_MJ_WRITE] = MyWrite;
driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyControl;
return 0;
}
应用层cmd代码
#include <iostream>
#include <Windows.h>
#include <stdlib.h>
#include <winioctl.h>
#define IOCTL_MUL CTL_CODE(FILE_DEVICE_UNKNOWN,0x9888,METHOD_BUFFERED,FILE_ANY_ACCESS)
int main()
{
HANDLE hdevice = NULL;
CHAR readbuffer[50] = {
0 };
DWORD bread = 0;
hdevice = CreateFile("\\\\.\\MyfirstDevice",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hdevice==INVALID_HANDLE_VALUE)
{
printf("Open Device Faile\n");
system("pause");
return 0;
}
printf("Open Sucess\n");
system("pause");
ReadFile(hdevice,(PVOID)readbuffer,50,&bread,NULL);
printf("-%p-%s--%d--\n",readbuffer,readbuffer, bread);
printf("Write!\n");
system("pause");
WriteFile(hdevice,"This Message come from R3.",strlen("This Message come from R3."), &bread, NULL);
printf("-write size--%d--\n",bread);
printf("DeviceIo!ControlCode --%d\n", IOCTL_MUL);
system("pause");
DWORD a = 888, b = 0;
DeviceIoControl(hdevice, IOCTL_MUL, &a,4,&b,4,&bread,NULL);
printf("--in %d--out %d--really info %d\n", a,b,bread);
CloseHandle(hdevice);
system("pause");
return 0;
}
运行后效果图: