-
-
[原创] 驱动开发:应用DeviceIoContro开发模板
-
2022-11-1 13:35 5575
-
内核中执行代码后需要将结果动态显示给应用层的用户,DeviceIoControl 是直接发送控制代码到指定的设备驱动程序,使相应的移动设备以执行相应的操作的函数,如下代码是一个经典的驱动开发模板框架,在开发经典驱动时会用到的一个通用案例。
驱动程序开发通用模板代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | #include <ntifs.h> #include <windef.h> / / 控制器 #define IOCTL_IO_LyShark CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) / / 卸载驱动执行 VOID UnDriver(PDRIVER_OBJECT pDriver) { PDEVICE_OBJECT pDev; / / 用来取得要删除设备对象 UNICODE_STRING SymLinkName; / / 局部变量symLinkName pDev = pDriver - >DeviceObject; IoDeleteDevice(pDev); / / 调用IoDeleteDevice用于删除设备 RtlInitUnicodeString(&SymLinkName, L "\\??\\LySharkDriver" ); / / 初始化字符串将symLinkName定义成需要删除的符号链接名称 IoDeleteSymbolicLink(&SymLinkName); / / 调用IoDeleteSymbolicLink删除符号链接 DbgPrint( "驱动卸载完毕..." ); } / / 创建设备连接 NTSTATUS CreateDriverObject(IN PDRIVER_OBJECT pDriver) { NTSTATUS Status; PDEVICE_OBJECT pDevObj; UNICODE_STRING DriverName; UNICODE_STRING SymLinkName; / / 创建设备名称字符串 RtlInitUnicodeString(&DriverName, L "\\Device\\LySharkDriver" ); Status = IoCreateDevice(pDriver, 0 , &DriverName, FILE_DEVICE_UNKNOWN, 0 , TRUE, &pDevObj); / / 指定通信方式为缓冲区 pDevObj - >Flags | = DO_BUFFERED_IO; / / 创建符号链接 RtlInitUnicodeString(&SymLinkName, L "\\??\\LySharkDriver" ); Status = IoCreateSymbolicLink(&SymLinkName, &DriverName); return STATUS_SUCCESS; } / / 创建回调函数 NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp) { pIrp - >IoStatus.Status = STATUS_SUCCESS; / / 返回成功 DbgPrint( "派遣函数 IRP_MJ_CREATE 执行 \n" ); IoCompleteRequest(pIrp, IO_NO_INCREMENT); / / 指示完成此IRP return STATUS_SUCCESS; / / 返回成功 } / / 关闭回调函数 NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp) { pIrp - >IoStatus.Status = STATUS_SUCCESS; / / 返回成功 DbgPrint( "派遣函数 IRP_MJ_CLOSE 执行 \n" ); IoCompleteRequest(pIrp, IO_NO_INCREMENT); / / 指示完成此IRP return STATUS_SUCCESS; / / 返回成功 } / / 主控制器,用于判断R3发送的控制信号 / / lyshark.com NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp) { NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; PIO_STACK_LOCATION pIrpStack; ULONG uIoControlCode; PVOID pIoBuffer; ULONG uInSize; ULONG uOutSize; / / 获得IRP里的关键数据 pIrpStack = IoGetCurrentIrpStackLocation(pIrp); / / 获取控制码 uIoControlCode = pIrpStack - >Parameters.DeviceIoControl.IoControlCode; / / 输入和输出的缓冲区(DeviceIoControl的InBuffer和OutBuffer都是它) pIoBuffer = pIrp - >AssociatedIrp.SystemBuffer; / / EXE发送传入数据的 BUFFER 长度(DeviceIoControl的nInBufferSize) uInSize = pIrpStack - >Parameters.DeviceIoControl.InputBufferLength; / / EXE接收传出数据的 BUFFER 长度(DeviceIoControl的nOutBufferSize) uOutSize = pIrpStack - >Parameters.DeviceIoControl.OutputBufferLength; / / 对不同控制信号的处理流程 switch (uIoControlCode) { / / 接收或发送 case IOCTL_IO_LyShark: { DWORD dw = 0 ; / / 得到输入参数 memcpy(&dw, pIoBuffer, sizeof(DWORD)); DbgPrint( "[+] hello lyshark \n" ); / / 对输入参数进行处理 dw + + ; / / 设置输出参数 memcpy(pIoBuffer, &dw, sizeof(DWORD)); / / 返回通信状态 status = STATUS_SUCCESS; break ; } pIrp - >IoStatus.Status = status; pIrp - >IoStatus.Information = uOutSize; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; } / / 设定DeviceIoControl的 * lpBytesReturned的值(如果通信失败则返回 0 长度) if (status = = STATUS_SUCCESS) pIrp - >IoStatus.Information = uOutSize; else pIrp - >IoStatus.Information = 0 ; / / 设定DeviceIoControl的返回值是成功还是失败 pIrp - >IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; } / / 入口函数 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING RegistryPath) { / / 调用创建设备 CreateDriverObject(pDriver); pDriver - >DriverUnload = UnDriver; / / 卸载函数 pDriver - >MajorFunction[IRP_MJ_CREATE] = DispatchCreate; / / 创建派遣函数 pDriver - >MajorFunction[IRP_MJ_CLOSE] = DispatchClose; / / 关闭派遣函数 pDriver - >MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; / / 分发函数 DbgPrint( "By:LyShark ..." ); return STATUS_SUCCESS; } |
应用层通用测试模板代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <iostream> #include <Windows.h> #include <winioctl.h> #define IOCTL_IO_LyShark CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) int main( int argc, char * argv[]) { HANDLE hDevice = CreateFileA( "\\\\.\\LySharkDriver" , GENERIC_READ | GENERIC_WRITE, 0 , NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDevice = = INVALID_HANDLE_VALUE) { CloseHandle(hDevice); return 0 ; } / / 发送控制信号 / / input = 发送数据 output = 接受数据 ref_len = 数据长度 DWORD input = 100 , output = 0 , ref_len = 0 ; DeviceIoControl(hDevice, IOCTL_IO_LyShark, & input , sizeof( input ), &output, sizeof(output), &ref_len, 0 ); printf( "输出: %d \n" , output); system( "pause" ); CloseHandle(hDevice); return 0 ; } |
输出效果如下:
赞赏
他的文章
[原创] PE格式:手写PE结构解析工具
17342
[原创] CE修改器教程 [入门篇]
5577
[原创] PE格式:新建节并插入代码
20711
[原创] PE格式:分析IatHook并实现
13083