这两天学习了一下上层应用程序与底层驱动程序的通信,
写了一个简单的消息通信程序,即sys与exe互传了一句话给对方。
代码如下:
/* 驱动SYS irp1.h */
#include <ntddk.h>
/*采用缓冲区内存模式IOCTL,
MY_DVC_BUFFERED_CODE是自定义的控制码*/
#define MY_DVC_BUFFERED_CODE \
(ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, \
0x900, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
//---------函数声明---------
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING registryPath);
NTSTATUS
MyDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS
MyCreateClose(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
VOID
MyDriverOnUnload(IN PDRIVER_OBJECT DriverObject);
//-------------------------
/* 驱动SYS irp1.c */
#include "irp1.h"
//------------驱动入口----------
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING registryPath )
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT Device;
UNICODE_STRING DeviceName, DeviceLink; //设备名,符号链接名
DbgPrint("[Aliwy] DriverEntry\n");
RtlInitUnicodeString(&DeviceName, L"\\Device\\Aliwy"); //初始化设备名
RtlInitUnicodeString(&DeviceLink, L"\\DosDevices\\IamAliwy"); //初始化符号链接名
/* IoCreateDevice 生成设备对象 */
ntStatus = IoCreateDevice(DriverObject, //生成设备的驱动对象
0, //设备扩展区内存大小
&DeviceName, //设备名,\Device\Aliwy
FILE_DEVICE_UNKNOWN, //设备类型
0, //填写0即可
FALSE, //必须为FALSE
&Device); //设备对象指针返回到DeviceObject中
if (!NT_SUCCESS(ntStatus))
{
DbgPrint("[Aliwy] IoCreateDevice FALSE: %.8X\n", ntStatus);
return ntStatus; //生成失败就返回
}
else
DbgPrint("[Aliwy] IoCreateDevice SUCCESS\n");
/* IoCreateSymbolicLink 生成符号链接 */
ntStatus = IoCreateSymbolicLink(&DeviceLink, &DeviceName);
if (!NT_SUCCESS(ntStatus))
{
DbgPrint("[Aliwy] IoCreateSymbolicLink FALSE: %.8X\n", ntStatus);
IoDeleteDevice(Device); //删除设备
return ntStatus;
}
else
DbgPrint("[Aliwy] IoCreateSymbolicLink SUCCESS\n");
Device->Flags &= ~DO_DEVICE_INITIALIZING; //设备初始化完成标记
DriverObject->DriverUnload = MyDriverOnUnload;
/*设备控制请求,对应Ring3 DeviceIoControl*/
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDeviceIoControl;
/*设备打开请求,对应Ring3 CreateFile*/
DriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateClose; //要与应用层通信,
/*设备关闭请求,对应Ring3 CloseHandle*/ //必须有打开、关闭请求!
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyCreateClose;
return ntStatus;
}
//------------------------------
//---------设备请求处理---------
NTSTATUS MyDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
PIO_STACK_LOCATION irpSp; //当前IRP调用栈空间
ULONG code; //功能号
NTSTATUS ntStatus = STATUS_SUCCESS;
ULONG inBufLength; //输入缓冲区长度
ULONG outBufLength; //输出缓冲区长度
PCHAR inBuf; //输入缓冲区
PCHAR outBuf; //输出缓冲区
PCHAR outData = "[Aliwy] outBuf: This String is from Driver !!!"; //向应用层输出的信息
ULONG outDataLen = strlen(outData) + 1; //信息长度含结尾一个NULL
DbgPrint("[Aliwy] MyDeviceIoControl\n");
irpSp = IoGetCurrentIrpStackLocation(Irp); //获得当前IRP调用栈空间
code = irpSp->Parameters.DeviceIoControl.IoControlCode; //得到功能号,即控制码
inBufLength = irpSp->Parameters.DeviceIoControl.InputBufferLength; //取输入缓冲区长度
outBufLength = irpSp->Parameters.DeviceIoControl.OutputBufferLength;//取输出缓冲区长度
inBuf = Irp->AssociatedIrp.SystemBuffer; //输入缓冲区
outBuf = Irp->AssociatedIrp.SystemBuffer; //输出缓冲区
if (code == MY_DVC_BUFFERED_CODE) //我们自定义的控制码
{
DbgPrint("[Aliwy] inBuf: %s\n", inBuf); //打印出应用层传入的内容
RtlCopyBytes(outBuf, outData, outBufLength); //复制我们要传入的内容到输出缓冲区
Irp->IoStatus.Information = (outBufLength > outDataLen ? outBufLength : outDataLen);
Irp->IoStatus.Status = STATUS_SUCCESS;
}
else
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
IoCompleteRequest(Irp, IO_NO_INCREMENT); //结束IRP请求
DbgPrint("[Aliwy] MyDeviceIoControl Over\n");
return Irp->IoStatus.Status;
}
//------------------------------
//----------打开关闭------------
NTSTATUS MyCreateClose( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
DbgPrint("[Aliwy] MyCreateClose\n");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
//------------------------------
//----------驱动卸载------------
VOID MyDriverOnUnload( IN PDRIVER_OBJECT DriverObject )
{
UNICODE_STRING DeviceLink; //符号链接名
DbgPrint("[Aliwy] MyDriverOnUnload\n");
RtlInitUnicodeString(&DeviceLink, L"\\DosDevices\\IamAliwy");
IoDeleteSymbolicLink(&DeviceLink); //删除符号链接
if (DriverObject->DeviceObject != NULL)
{
IoDeleteDevice(DriverObject->DeviceObject); //删除设备
}
}
//------------------------------
/* 应用层EXE irp1.cpp */
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
/*采用缓冲区内存模式IOCTL,MY_DVC_IN_CODE是自定义的控制码*/
#define MY_DVC_BUFFERED_CODE \
(ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, \
0x900, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS)
void main()
{
ULONG bytesReturned;
char inBuf[50] = "This String is from User !!!"; //传入驱动的内容
char outBuf[50]; //用于接收驱动传出内容的缓冲区
/*打开设备,用我们自定的符号链接,响应驱动IRP_MJ_CREATE*/
HANDLE hDevice = CreateFile("\\\\.\\IamAliwy",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("设备打开失败 %d %.8x\n", GetLastError(), hDevice);
return;
}
memset(outBuf, 0, sizeof(outBuf));
/*控制设备,响应驱动IRP_MJ_DEVICE_CONTROL*/
BOOL ret = DeviceIoControl(hDevice,
MY_DVC_BUFFERED_CODE, //我们自定义的功能号
&inBuf, //传入驱动的内容
strlen(inBuf) + 1, //传入内容长度
&outBuf, //驱动输出的缓冲区
sizeof(outBuf), //驱动输出缓冲区大小
&bytesReturned, //返回的长度
NULL);
if (!ret)
{
printf("Error in DeviceIoControl: %d", GetLastError());
}
else
printf("%s(%d)\n", outBuf, bytesReturned); //打印驱动传给我们的内容
/*关闭设备,对应驱动IRP_MJ_CLOSE*/
CloseHandle(hDevice);
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)