内核中执行代码后需要将结果动态显示给应用层的用户,DeviceIoControl 是直接发送控制代码到指定的设备驱动程序,使相应的移动设备以执行相应的操作的函数,如下代码是一个经典的驱动开发模板框架,在开发经典驱动时会用到的一个通用案例。

驱动程序开发通用模板代码如下:

#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;
}

应用层通用测试模板代码如下:

#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;
}

输出效果如下:

驱动开发:应用DeviceIoContro开发模板的更多相关文章

  1. 领域驱动(DDD)设计和开发实战

    领域驱动设计(DDD)的中心内容是如何将业务领域概念映射到软件工件中.大部分关于此主题的著作和文章都以 Eric Evans 的书<领域驱动设计>为基础,主要从概念和设计的角度探讨领域建模 ...

  2. Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构

    分享两篇Win 10应用开发的XML文档结构:Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构. Win 10 开发中Adapt ...

  3. ASP.NET自定义控件组件开发 第五章 模板控件开发

    原文:ASP.NET自定义控件组件开发 第五章 模板控件开发 第五章 模板控件开发 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接 ...

  4. 任务驱动,学习.NET开发系列第2篇------单词统计

    一 高效学习编程的办法 1 任务驱动方式学习软件开发 大部分人学习软件开发技术是通过看书,看视频,听老师上课的方式.这些方式有一个共同点即按知识点进行讲解.比如拿c#编程为例,首先是讲解大量的基础概念 ...

  5. 基于vuecli3构建一个快速开发h5 APP的模板

    基于vuecli3构建的一个快速开发h5 APP的模板,集成了高德地图.mint-ui,以及antv-f2可视化框架 vue-cli3安装 查看vue cli版本 vue --version 要求no ...

  6. 【Linux开发】Linux V4L2驱动架构解析与开发导引

    Linux V4L2驱动架构解析与开发导引 Andrew按:众所周知,linux中可以采用灵活的多层次的驱动架构来对接口进行统一与抽象,最低层次的驱动总是直接面向硬件的,而最高层次的驱动在linux中 ...

  7. 瀑布式开发、迭代开发、敏捷开发、XP与SCRUM的区别

    瀑布式开发.迭代开发,区别[都属于,生命周期模型]         两者都是一种开发模式,就像设计模式一样,考虑的角度不一样,个人感觉谈不到取代一说.         传统的瀑布式开发,也就是从需求到 ...

  8. 【团购活动】接口最全最好用的S5PV210开发板Sate210-F 开发板开始团购活动了,一起学习linux!

    接口最全最好用的S5PV210开发板Sate210-F 开发板开始团购活动了,一起学习linux!http://bbs.eeworld.com.cn/forum.php?mod=viewthread& ...

  9. Web程序员开发App系列 - 开发我的第一个App,源码下载

    Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...

  10. 【嵌入式开发】 嵌入式开发工具简介 (裸板调试示例 | 交叉工具链 | Makefile | 链接器脚本 | eclipse JLink 调试环境)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42239705  参考博客 : [嵌入式开发]嵌入式 开发环境 (远 ...

随机推荐

  1. 【django drf】 阶段练习

    目录 需求 settings.py views.py urls.py serializers.py permissions.py page.py authenticate.py model.py 权限 ...

  2. 解决延迟有 Wi-Fi 6 就够了!

    最近二狗子家里的路由器坏了,而家里的数据网络信号又非常差,失去了路由器基本上就等于和世界隔离,所以二狗子打算去附近商城随便买一个新的路由器,结果售货员张口就问:"买 Wi-Fi 6 的路由器 ...

  3. 关于改造维护工单BAPI_ALM_ORDER_MAINTAIN用于生产订单组件批量修改

    1.研究背景 1.1.业务背景 由于销售.研发.工艺等需要频繁变更,导致工单中组件需要频繁的进行变更,修改组件的物料,数量,库存地点,工序等内容. 1.2.技术痛点 为了满足要求,使用了函数:CO_X ...

  4. C# NLog 配置

    首先用NuGet安装NLog依赖DLL NLog NLog.Config NLog.Schema NLog配置文件NLog.config: <?xml version="1.0&quo ...

  5. TCP 拥塞控制对数据延迟的影响

    哈喽大家好,我是咸鱼 今天分享一篇文章,是关于 TCP 拥塞控制对数据延迟产生的影响的.作者在服务延迟变高之后进行抓包分析,结果发现时间花在了 TCP 本身的机制上面:客户端并不是将请求一股脑发送给服 ...

  6. Codeforces Round #677 (Div. 3) (A - E题题)

    1433A. Boring Apartments #include <bits/stdc++.h> using namespace std; int main() { int t; cin ...

  7. [tslint] Identifier 'loggedIn' is never reassigned; use 'const' instead of 'let'. (prefer-const)

  8. P1439-DP【绿】

    轻敌了啊...题目一共只有几句话但我却忽略了一个重大信息... 总之我显示写出了时空复杂度都是n^2级别的朴素递推算法,这没什么,基本功而已,然后50分 我试了试滚动数组,把空间复杂度降到了n级别,但 ...

  9. STM32CubeMX教程20 SPI - W25Q128驱动

    1.准备材料 开发板(正点原子stm32f407探索者开发板V2.4) STM32CubeMX软件(Version 6.10.0) 野火DAP仿真器 keil µVision5 IDE(MDK-Arm ...

  10. 0xGame 2023【WEEK3】Crypto WP

    EzECC 1.题目信息 还在偷听小爱和小爆的通讯! Hint 1: 也许SageMath能给你想要的东西 Hint 2: 预期解法时间估计可能一两分钟左右,可能更短 Hint 3: 阿贝尔群上的加加 ...