博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对<<寒江独钓---Windows内核安全编程>>中第3章<<串口过滤>>的改进
阅读量:5751 次
发布时间:2019-06-18

本文共 7332 字,大约阅读时间需要 24 分钟。

  <<寒江独钓>>中第3章的串口过滤只实现了对写操作的过滤, 没有实现对读操作的过滤, 这里, 我改进了一下, 去掉了原来对所有串口的过滤, 改成了只对指定的串口过滤; 增加了同时对读操作的过滤,其实主要就是调用IoSetCompletionRoutine设置完成回调函数.

  源代码:

  

#include 
#include
/**********************************************************文件名称:comdrv.c文件路径:./comdrv/comdrv.c创建时间:2013-1-29,14:18:08文件作者:女孩不哭文件说明:该程序是对<
<寒江独钓>
>中comcap串口过滤驱动程序的改进版,改进: [+] 增加了对串口的读取操作的过滤(原来只有写操作) [-] 去掉了原来对所有串口(32个)的过滤,现在只对指定端口 [*] 优化了部分程序**********************************************************///读操作请求计数ULONG gReadRequestionCounter = 0;//我的设备 设备扩展定义typedef struct{ PDEVICE_OBJECT pFltObj; PDEVICE_OBJECT pTopDev;}COMDRV_DEVEXT,*PCOMDRV_DEVEXT;//函数的前向声明NTSTATUS comdrvOpenCom(ULONG comid, PDEVICE_OBJECT* ppOldObj);NTSTATUS comdrvAttachDevice(PDRIVER_OBJECT pDriver, PDEVICE_OBJECT pOldObj);void comdrvDriverUnload(PDRIVER_OBJECT pDriverObject);NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath);void PrintHexString(char* prefix, UCHAR* buffer, ULONG length);NTSTATUS comdrvDispatch(PDEVICE_OBJECT pDevice, PIRP pIrp);NTSTATUS comdrvWrite(PDEVICE_OBJECT pDevice, PIRP pIrp);NTSTATUS comdrvRead(PDEVICE_OBJECT pDevice, PIRP pIrp);NTSTATUS comdrvReadCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);//打开指定ID号的串口设备对象NTSTATUS comdrvOpenCom(ULONG comid, PDEVICE_OBJECT* ppOldObj){ NTSTATUS status; UNICODE_STRING name; WCHAR str[32] = {
0}; PFILE_OBJECT fileobj = NULL; PDEVICE_OBJECT devobj = NULL; RtlStringCchPrintfW(str, 32, L"\\Device\\Serial%d", comid); RtlInitUnicodeString(&name, str); status = IoGetDeviceObjectPointer(&name, FILE_ALL_ACCESS, &fileobj, &devobj); if(status == STATUS_SUCCESS) ObDereferenceObject(fileobj); *ppOldObj = devobj; return status;}//用指定的过虑设备绑定目标设备NTSTATUS comdrvAttachDevice(PDRIVER_OBJECT pDriver, PDEVICE_OBJECT pOldObj){ NTSTATUS status; PDEVICE_OBJECT pTopDev = NULL; PDEVICE_OBJECT pFltObj; PDEVICE_OBJECT next; PCOMDRV_DEVEXT pDevExt; //创建过虑设备 status = IoCreateDevice(pDriver, sizeof(COMDRV_DEVEXT), NULL, pOldObj->DeviceType, 0, TRUE, &pFltObj); if(status != STATUS_SUCCESS) return status; //拷贝重要标志位 if(pOldObj->Flags & DO_BUFFERED_IO) pFltObj->Flags |= DO_BUFFERED_IO; if(pOldObj->Flags & DO_DIRECT_IO) pFltObj->Flags |= DO_DIRECT_IO; if(pOldObj->Characteristics & FILE_DEVICE_SECURE_OPEN) pFltObj->Flags |= DO_POWER_PAGABLE; //绑定到另一设备上 pTopDev = IoAttachDeviceToDeviceStack(pFltObj, pOldObj); if(pTopDev == NULL){ IoDeleteDevice(pFltObj); pFltObj = NULL; status = STATUS_UNSUCCESSFUL; return status; } pFltObj->Flags &= ~DO_DEVICE_INITIALIZING; pDevExt = (PCOMDRV_DEVEXT)pFltObj->DeviceExtension; pDevExt->pFltObj = pFltObj; pDevExt->pTopDev = pTopDev; return STATUS_SUCCESS;}//打印出内存的16进制void PrintHexString(char* prefix, UCHAR* buffer, ULONG length){ int x; char* outbuf = NULL; char* poutbuf = NULL; //char* prefix = "comdrv_write:"; int buflen = length*3+3+strlen(prefix); do{ if(length == 0) break; outbuf = (char*)ExAllocatePool(NonPagedPool, buflen); if(outbuf == NULL){ KdPrint(("ExAllocatePool failed!\r\n")); break; } strcpy(outbuf, prefix); poutbuf = outbuf+strlen(prefix); for(x=0; x
DeviceExtension; ULONG len = pIrpSp->Parameters.Write.Length; PUCHAR buf = NULL; if(pIrp->MdlAddress != NULL) buf = (PUCHAR)MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, NormalPagePriority); else buf = (PUCHAR)pIrp->UserBuffer; if(buf == NULL) buf = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer; //打印出内容 PrintHexString("comdrv_write:", buf, len); IoSkipCurrentIrpStackLocation(pIrp); return IoCallDriver(pDevExt->pTopDev, pIrp);}//对读完成的处理NTSTATUS comdrvReadCompletion(PDEVICE_OBJECT pDeviceObject, PIRP pIrp, PVOID pContext){ PIO_STACK_LOCATION CurIrp = NULL; ULONG length = 0; PUCHAR buffer = NULL; ULONG i; CurIrp = IoGetCurrentIrpStackLocation(pIrp); //在操作成功的前提下进行操作 if(NT_SUCCESS(pIrp->IoStatus.Status)){ //得到输出缓冲区 buffer = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer; length = pIrp->IoStatus.Information; //打印出读取到的内容 PrintHexString("comdrv_read:", buffer, length); } //读操作已完成,保持平衡 gReadRequestionCounter--; if(pIrp->PendingReturned) IoMarkIrpPending(pIrp); return pIrp->IoStatus.Status;}//对读操作的处理NTSTATUS comdrvRead(PDEVICE_OBJECT pDevice, PIRP pIrp){ NTSTATUS status; PCOMDRV_DEVEXT pDevExt = NULL; PIO_STACK_LOCATION CurIrp = NULL; //错误处理 if(pIrp->CurrentLocation == 1){ ULONG ReturnedInfo = 0; KdPrint(("comdrv irp current location error\r\n")); status = STATUS_INVALID_DEVICE_REQUEST; pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = ReturnedInfo; return status; } //读操作增加 gReadRequestionCounter++; pDevExt = (PCOMDRV_DEVEXT)pDevice->DeviceExtension; //设置读完成回调函数并下发IRP CurIrp = IoGetCurrentIrpStackLocation(pIrp); IoCopyCurrentIrpStackLocationToNext(pIrp); IoSetCompletionRoutine(pIrp, comdrvReadCompletion, NULL, TRUE, TRUE, TRUE); return IoCallDriver(pDevExt->pTopDev, pIrp);}//通用分发函数NTSTATUS comdrvDispatch(PDEVICE_OBJECT pDevice, PIRP pIrp){ NTSTATUS status; PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp); PCOMDRV_DEVEXT pDevExt = (PCOMDRV_DEVEXT)pDevice->DeviceExtension; //忽略所有电源操作 if(pIrpSp->MajorFunction == IRP_MJ_POWER){ PoStartNextPowerIrp(pIrp); IoSkipCurrentIrpStackLocation(pIrp); return PoCallDriver(pDevExt->pTopDev, pIrp); } //直接下发所有请求 IoSkipCurrentIrpStackLocation(pIrp); return IoCallDriver(pDevExt->pTopDev, pIrp);}void comdrvDriverUnload(PDRIVER_OBJECT pDriverObject){#define DELAY_ONE_MICROSECOND (-10)#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000) LARGE_INTEGER li; PCOMDRV_DEVEXT pDevExt = NULL; li.QuadPart = 3*1000*DELAY_ONE_MILLISECOND; pDevExt = (PCOMDRV_DEVEXT)pDriverObject->DeviceObject->DeviceExtension; IoDetachDevice(pDevExt->pTopDev); while(gReadRequestionCounter) KeDelayExecutionThread(KernelMode, FALSE, &li); IoDeleteDevice(pDevExt->pFltObj);}NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath){ NTSTATUS status; int it; PDEVICE_OBJECT pDevObj = NULL; //我们只过滤读写操作,其它的操作交给下层驱动处理 for(it=0; it
MajorFunction[it] = comdrvDispatch; pDriverObject->MajorFunction[IRP_MJ_WRITE] = comdrvWrite; pDriverObject->MajorFunction[IRP_MJ_READ] = comdrvRead; pDriverObject->DriverUnload = comdrvDriverUnload; //1代表COM2,2代表COM3, ... status = comdrvOpenCom(1, &pDevObj); if(!NT_SUCCESS(status)) return status; status = comdrvAttachDevice(pDriverObject, pDevObj); if(!NT_SUCCESS(status)) return status; return STATUS_SUCCESS;}

源代码下载:

女孩不哭(QQ:191035066)@2013-02-25 13:59:23 http://www.cnblogs.com/nbsofer
2013-03-09:
  发现一个原书中的错误,作者说Windows上的串口设备按串口号依次是\Device\Serial0,\Device\Serial1, ...
  这在事实上是不正确的, 因为Prolific的PL2303 USB转RS232驱动生成的设备就不叫\Device\Serialx, 而叫\Device\ProlificSerialx, 这可让我调试程序花了好多时间, 找时间告诉作者.

  

你可能感兴趣的文章
【 D3.js 高级系列 — 2.0 】 机械图 + 人物关系图
查看>>
centos tomcat/resin安装配置 卸载系统自带的java tomcat安装配置 安装JDK resin安装配置 第二十八节课...
查看>>
Python3.2官方文件翻译--课堂笔记和异常是阶级
查看>>
版本控制系统相关知识
查看>>
Linux kernel scriptes bin2c "\x"
查看>>
【转】MYSQL 存储过程定时操作数据库
查看>>
我最常用的几个Xcode快键键
查看>>
Educational Codeforces Round 8 A. Tennis Tournament 暴力
查看>>
Node.js模块
查看>>
玩转iOS开发 - JSON 和 Xml 数据解析
查看>>
Undefined symbols for architecture i386: "_deflate", referenced from:
查看>>
String的split()方法探索和大揭秘
查看>>
mysql中变量character_set_connection的具体作用
查看>>
小酌重构系列[12]——去除上帝类
查看>>
FPGA学习手记(四)ModelSim入门及Testbench编写——合理利用仿真才是王道
查看>>
android 面试
查看>>
jQuery 遍历函数
查看>>
《寄生兽》观后感
查看>>
IntelliJ IDEA 的 Jetty部署插件
查看>>
x-forwarded-for的深度挖掘
查看>>