内核中执行代码后需要将结果动态显示给应用层的用户,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. COOIS增强

    一.订单抬头增强 二.结构添加字段 添加ZGCWL字段 三.BADI增强 四.其他界面增强 不同的界面,选择不同的修改结构 抬头 ct_ioheader 组件 ct_ioopcomp 工序 ct_io ...

  2. C#9.0:Init

    背景 在以前的C#版本里面,如果需要定义一个不可修改的的类型的做法一般是:声明为readonly,并设置为只包含get访问器,不包含set访问器.如下: 1 public class PersonIn ...

  3. POJ: 2236 Wireless Network 题解

    POJ 2236 Wireless Network 加工并储存数据的数据结构 并查集 这是并查集的基本应用,两台修好的电脑若距离d内则加入合并.不过不小心的话会TLE,比如: #include < ...

  4. 【每日一题】1. tokitsukaze and Soldier (优先队列 + 排序)

    题目链接:Here 思路:这道题很容易看出来是考察 优先队列(priority_queue) 和 sort . 对于容忍人数越高的人来说,团队人数低也更能做到: for i = 0 to n - 1: ...

  5. 勇者游戏(巴什博弈)- HDU 1846

    博弈算法中比较经典的一个博弈问题是巴什博奕,巴什博弈是这样的: 有一堆物品,数量为n,两个人轮流取,规定每次最多取m个,最少取1个. 我们定义先取者为F(first),后取者为S(second) 网上 ...

  6. 3 分钟创建 Serverless Job 定时获取新闻热搜

    不用掏手机,不用登微博,借助 SAE 定时任务就可以实现每小时获取实时新闻热搜!SAE 场景体验火热开启中,参与还可领好礼! Job 作为一种运完即停的负载类型,在企业级开发中承载着丰富的使用场景.S ...

  7. 小程序-轮播图swiper

  8. 国内服务器 3 分钟将 ChatGPT 接入微信公众号(超详细)

    原文链接:https://forum.laf.run/d/364 最近很火的ChatGPT可以说已经满大街可见了,到处都有各种各样的体验地址,有收费的也有免费的,总之是五花八门.花里胡哨. 所以呢,最 ...

  9. Liunx常用操作(九)-进阶命令

    一.查看用户who 1.查看所有用户:who

  10. 小白学正则表达式之 regexp

    1. 正则表达式介绍 正则表达式是程序文本处理常用的模板模式,按照解析正则表达式的引擎可将正则表达式分为 POSIX 基础正则表达式(Basic regular expression,BRE) 引擎和 ...