内核中执行代码后需要将结果动态显示给应用层的用户,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. C# RSA 非对称加密

    代码: RSAHelper.cs(RSA加密工具类): using System; using System.Security.Cryptography; using System.Text; nam ...

  2. #627 DIV3 题解

    A. 每组给一个和个数(),每次操作可以给一个加2,求是否能使n个数相等 4 3 1 1 3 4 1 1 2 1 2 11 11 1 100 YES NO YES YES 直接扫一遍,记录最大值与当前 ...

  3. HDU - 2181 :哈密顿绕行世界问题

    Descriptions: 一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市. Input 前20行的第i行有3个数,表示与第i个 ...

  4. Codeforces Round #722 (Div. 2) A~D题解

    补题链接:Here 1529A. Eshag Loves Big Arrays [题意描述] 给定一个长度为 \(n\) 的正整数数组 \(a\) ,现在可执行若干次操作(可为 \(0\)) 具体操作 ...

  5. 版本升级 | v1.0.12发布,许可证风险早知道

    新版本来啦~~~~ 一.v1.0.12更新内容 优化许可证检出功能,可通过JSON / HTML / SPDX 报告获知许可证信息 支持HTML报告自定义分页 二.更新说明 1. 优化许可证检出功能, ...

  6. SpringCloud学习 系列四、微服务中心 Eureka介绍及创建一个Eureka中心服务

    系列导航 SpringCloud学习 系列一. 前言-为什么要学习微服务 SpringCloud学习 系列二. 简介 SpringCloud学习 系列三. 创建一个没有使用springCloud的服务 ...

  7. 面试重点:webpack

    webpack 熟练掌握Webpack的常用配置,能够自己构建前端环境,并进行项目优化; 001.谈谈你对webpack的看法: webpack是一个模块打包工具,可以使用它管理项目中的模块依赖,并编 ...

  8. 第65篇 AJAX初识 校验用户名 登录示例 文件上传 csrftoken

    1, 知识储备 2. AJAX的定义 异步的JavaScript和XML 使用场景: JavaScript和后端的数据传递 2.1原生的JavaScript实现AJAX 2.2 JQuery实现 2. ...

  9. python · ssh · SQL | python 连接远程 SQL 数据库

    python 连接本地 SQL 的 教程存档. 如果要连接远程的 SQL 数据库,需要先开一个 ssh 连接,在 ssh 连接里写 pymysql 的 connect 代码. 代码如下: ''' pi ...

  10. Oracledb_exporter 获取表大小信息的简单方法

    Oracledb_exporter 获取表大小信息的简单方法 背景 用我儿子的现状作为背景: 我爱学习, 学习让我妈快乐. 下载exporter exporter 可以在github上面下载最新版本是 ...