1 驱动程序 编译出64位
#include <ntddk.h>
#define DEVICE_NAME L"\\Device\\MyDevice"
#define SYMBOLIC_LINK_NAME L"\\??\\MyDeviceLink"
#define IOCTL_WRITE_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
// 设备扩展结构
typedef struct _DEVICE_EXTENSION {
HANDLE FileHandle; // 保存打开文件的句柄
} DEVICE_EXTENSION, * PDEVICE_EXTENSION;
NTSTATUS DeviceIoControlHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp);
VOID UnloadDriver(PDRIVER_OBJECT DriverObject);
NTSTATUS MyCreateHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
//PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
// 这里可以添加打开文件的逻辑,比如设置某些设备状态、初始化资源等
UNREFERENCED_PARAMETER(DeviceObject);
DbgPrint("Device opened successfully.\n");
// 设置 IRP 处理结果
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; // 可以返回的信息数量
IoCompleteRequest(Irp, IO_NO_INCREMENT); // 完成 IRP 请求
return STATUS_SUCCESS;
}
NTSTATUS MyCloseHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
// 这里可以添加关闭文件的逻辑,比如释放资源等
UNREFERENCED_PARAMETER(DeviceObject);
DbgPrint("Device closed successfully.\n");
// 设置 IRP 处理结果
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); // 完成 IRP 请求
return STATUS_SUCCESS;
}
// 驱动程序入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
UNREFERENCED_PARAMETER(RegistryPath);
NTSTATUS status;
UNICODE_STRING deviceName, symbolicLinkName;
// 创建设备名称
RtlInitUnicodeString(&deviceName, DEVICE_NAME);
// 创建设备
PDEVICE_OBJECT deviceObject;
status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &deviceName,
FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject);
if (!NT_SUCCESS(status)) {
return status; // 创建设备失败
}
// 创建符号链接指向设备名称
RtlInitUnicodeString(&symbolicLinkName, L"\\DosDevices\\MyDeviceLink");
status = IoCreateSymbolicLink(&symbolicLinkName, &deviceName);
if (NT_SUCCESS(status)) {
DbgPrint("Symbolic link created successfully: %wZ -> %wZ\n", &symbolicLinkName, &deviceName);
}
else {
DbgPrint("Failed to create symbolic link: %08X\n", status);
IoDeleteDevice(deviceObject); // 清理资源
return status;
}
// 设置驱动程序的主要函数指针
DriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateHandler;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyCloseHandler;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControlHandler;
// 设置卸载处理函数
DriverObject->DriverUnload = UnloadDriver;
// 初始化设备扩展
PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
deviceExtension->FileHandle = NULL; // 初始化文件句柄
return STATUS_SUCCESS;
}
// 在驱动程序卸载时,别忘了删除符号链接
VOID UnloadDriver(PDRIVER_OBJECT DriverObject) {
UNICODE_STRING symbolicLinkName;
RtlInitUnicodeString(&symbolicLinkName, L"\\DosDevices\\MyDeviceLink");
// 删除符号链接
IoDeleteSymbolicLink(&symbolicLinkName);
DbgPrint("Symbolic link deleted: %wZ\n", &symbolicLinkName);
// 删除设备
IoDeleteDevice(DriverObject->DeviceObject);
DbgPrint("Driver unloaded successfully.\n");
}
NTSTATUS DeviceIoControlHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
ULONG inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
PVOID inputBuffer = Irp->AssociatedIrp.SystemBuffer;
// 验证输入缓冲区大小
if (inputBufferLength < sizeof(HANDLE) + sizeof(char[256])) {
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; // 设置 IRP 的状态
Irp->IoStatus.Information = 0; // 设置返回信息字节数
IoCompleteRequest(Irp, IO_NO_INCREMENT); // 完成 IRP,以避免挂起
return STATUS_INVALID_PARAMETER; // 返回错误码
}
// 获取传递的文件句柄和数据
HANDLE fileHandle = *(HANDLE*)inputBuffer; // 假设传递句柄在缓冲区的开始
char* dataBuffer = (char*)((char*)inputBuffer + sizeof(HANDLE)); // 获取数据
IO_STATUS_BLOCK ioStatusBlock;
ULONG bytesWritten = 0;
// 用传递的句柄写入文件
status = ZwWriteFile(fileHandle, NULL, NULL, NULL, &ioStatusBlock,
dataBuffer, (ULONG)strlen(dataBuffer), NULL, NULL);
// 检查写入结果
if (NT_SUCCESS(status)) {
bytesWritten = (ULONG)ioStatusBlock.Information; // 写入的字节数
}
// 完成 IRP
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = bytesWritten; // 可以返回写入的字节数
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
2 应用程序 编译出 64位 编译出32为可以体验参数不对的情况 因为HANDLE 在32位 64位长度不一样 保证 C:\\Path 这个文件目录存在
// writefileblock.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <windows.h>
#include <stdio.h>
#define IOCTL_WRITE_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
void SendWriteRequest(HANDLE deviceHandle, HANDLE fileHandle, const char* data) {
DWORD bytesReturned;
// 发送 IOCTL 请求,将文件句柄和数据写入内核
struct {
HANDLE hFile; // 文件句柄
char data[256]; // 待写入的数据
} inputBuffer;
inputBuffer.hFile = fileHandle; // 设置文件句柄
strcpy_s(inputBuffer.data, sizeof(inputBuffer.data), data); // 设置数据
BOOL result = DeviceIoControl(deviceHandle,
IOCTL_WRITE_DATA,
&inputBuffer,
sizeof(inputBuffer), // 包括句柄和数据
NULL,
0,
&bytesReturned,
NULL);
if (!result) {
printf("DeviceIoControl failed: %lu\n", GetLastError());
}
else {
printf("Data written successfully!\n");
}
}
int main() {
// 打开设备(这里需要替换为你的设备名称)
HANDLE deviceHandle = CreateFile(L"\\\\.\\MyDeviceLink",
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (deviceHandle == INVALID_HANDLE_VALUE) {
printf("Failed to open device: %lu\n", GetLastError());
return 1;
}
// 打开文件并获取句柄
HANDLE fileHandle = CreateFile(L"C:\\Path\\YourFile.txt",
GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fileHandle == INVALID_HANDLE_VALUE) {
printf("Failed to open file: %lu\n", GetLastError());
CloseHandle(deviceHandle);
return 1;
}
const char* dataToWrite = "Hello, Kernel!";
SendWriteRequest(deviceHandle, fileHandle, dataToWrite);
// 关闭文件和设备
CloseHandle(fileHandle);
CloseHandle(deviceHandle);
return 0;
}