windows 驱动与内核调试 学习4
Posted 不会写代码的丝丽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了windows 驱动与内核调试 学习4相关的知识,希望对你有一定的参考价值。
前言
本文编写驱动DeviceIoControl
逻辑。
首先我们需要CTL_CODE
这个宏定义控制码
控制码相关文档
#define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access)
其中比较难理解的是Method
参数,这个参数决定输出输入缓存流如何定于,
这个参数同时也要受限与DEVICE_OBJECT
的flags
字段.比如DEVICE_OBJECT
.flags
为DO_DIRECT_IO
时不能使用METHOD_BUFFERED
Buffer Descriptions for I/O Control Codes
我们举例如下控制码生命
//Function 0x800以下为保留字段
#define MY_CTL(NUM) CTL_CODE(FILE_DEVICE_UNKNOWN,0x800+NUM, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define CTL_ENUM_1 MY_CTL(2)
#define CTL_ENUM_2 MY_CTL(3)
一个常规的创建驱动设备代码
//驱动被加载的时候会调用此函数
NTSTATUS
DriverEntry(
_In_ struct _DRIVER_OBJECT* DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
//如果你没有用到参数需要告诉系统。
UNREFERENCED_PARAMETER(RegistryPath);
//打印信息
DbgPrint("hello drive loaded");
//触发一个断点
//DbgBreakPoint();
//驱动卸载回调注册
DriverObject->DriverUnload = myUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchControl;
UNICODE_STRING ustrDevName;
RtlInitUnicodeString(&ustrDevName, L"\\\\Device\\\\MytestDriver");
PDEVICE_OBJECT pDevObj = NULL;
auto ret = IoCreateDevice(DriverObject, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevObj);
if (NT_SUCCESS(ret))
//指定IO模式
pDevObj->Flags |= DO_BUFFERED_IO;
DbgPrint("IoCreateDevice 成功 \\r\\n");
else
DbgPrint("IoCreateDevice 失败 %d\\r\\n", ret);
return STATUS_FAIL_CHECK;
UNICODE_STRING symbolDevName;
RtlInitUnicodeString(&symbolDevName, L"\\\\DosDevices\\\\MytestDriver");
ret = IoCreateSymbolicLink(&symbolDevName, &ustrDevName);
if (NT_SUCCESS(ret))
DbgPrint("IoCreateSymbolicLink 成功 \\r\\n");
else
DbgPrint("IoCreateSymbolicLink 失败%d\\r\\n", ret);
IoDeleteDevice(pDevObj);
return STATUS_FAIL_CHECK;
return STATUS_SUCCESS;
驱动核心的代码实现
NTSTATUS
DispatchControl(
_In_ struct _DEVICE_OBJECT* DeviceObject,
_Inout_ struct _IRP* Irp
)
DbgPrint("DispatchControl");
UNREFERENCED_PARAMETER(Irp);
UNREFERENCED_PARAMETER(DeviceObject);
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG nIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
ULONG nInputBufferLength = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG nOutputBufferLength = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
//这个SystemBuffer又作输入和输出
PVOID lpBuffer = Irp->AssociatedIrp.SystemBuffer;
switch (nIoControlCode)
case CTL_ENUM_1:
DbgPrint("DispatchControl CTL_ENUM_1 buf %p content %s inputLen %d outlen %d controlcode %d ",lpBuffer,lpBuffer, nInputBufferLength, nOutputBufferLength, nIoControlCode);
memcpy(lpBuffer, "CTL_ENUM_1", 10);
break;
case CTL_ENUM_2:
DbgPrint("DispatchControl CTL_ENUM_2 buf %p content %s inputLen %d outlen %d controlcode %d ", lpBuffer, lpBuffer, nInputBufferLength, nOutputBufferLength, nIoControlCode);
memcpy(lpBuffer, "CTL_ENUM_2", 10);
break;
default:
break;
Irp->iostatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 10;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
上层代码
#include <iostream>
#include<Windows.h>
#include<stdlib.h>
#define MY_CTL(NUM) CTL_CODE(FILE_DEVICE_UNKNOWN,0x800+NUM, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define CTL_ENUM_1 MY_CTL(2)
#define CTL_ENUM_2 MY_CTL(3)
int main()
std::cout << "Hello World!\\n";
HANDLE hFile;
hFile = CreateFile("\\\\\\\\\\?\\\\MytestDriver",
GENERIC_WRITE | GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFile == INVALID_HANDLE_VALUE)
std::cout << "INVALID_HANDLE_VALUE "<< GetLastError()<<"\\n";
return EXIT_FAILURE;
/*std::cout << "open ok\\n";
DWORD dwBytes = 0;
if (WriteFile(hFile, "hello", 6, &dwBytes, NULL))
std::cout << "write ok " << dwBytes << std::endl;
else
std::cout << "write failure " << dwBytes << std::endl;
DWORD drBytes = 0;
char szBuffer[120];
if (ReadFile(hFile, szBuffer, sizeof szBuffer, &drBytes, NULL))
std::cout << "read ok " << drBytes << " "<< szBuffer << std::endl;
else
std::cout << "read failure " << std::endl;
*/
char szControlIn[120]="hello";
char szControlOut[120]="hello myboy";
DWORD out=0;
if (DeviceIoControl(hFile, CTL_ENUM_1, szControlIn, sizeof szControlIn, szControlOut, sizeof szControlOut, &out, nullptr))
std::cout << "DeviceIoControl success out" << out <<" szControlOut:"<< szControlIn << std::endl;
printf("\\r\\n szControlIn %s\\r\\n", szControlIn);
printf("\\r\\n szControlOut %s\\r\\n", szControlOut);
else
std::cout << "DeviceIoControl failure " <<GetLastError() << std::endl;
CloseHandle(hFile);
system("pause");
return EXIT_SUCCESS;
以上是关于windows 驱动与内核调试 学习4的主要内容,如果未能解决你的问题,请参考以下文章