Windows驱动系列均来自于学习《Windows内核安全与驱动开发》中所遇见的问题及自己思考解决的过程,源代码均出自此书,但其中涉及变量不同,为方便记忆做过改动
#include <ntddk.h>
#include <wdmsec.h>
#pragma warning(disable:4100)
//FILE_DEVICE_UNKNOWN: not associated with any hardware device
//0x0~0x7ff resevered for microsoft
//METHOD_BUFFERED:we will use buffer trying to copy data from kernel and Ring3,which means we use irp->AssociatedIrp.SystemBuffer
//FILE_WRITE_DATA:the Authority we need for this operation.Since we send some data which equals write
#define ATK_SEND_STR (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN,0x83e,METHOD_BUFFERED,FILE_WRITE_DATA)
#define KTA_RECV_STR (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN,0X83f,METHOD_BUFFERED,FILE_WRITE_DATA)
#define control_device_syb L"\\?\\cdo_syb_51138e7"
const GUID cbo_uuid = { 0x3e9e9d04L, 0xf1df, 0x4138,{ 0xbd,0xbf, 0x27, 0xa7, 0xd9, 0x93, 0x02, 0x10 } };//uuidgen generates this--a tool from Linux
PDEVICE_OBJECT g_cdo = NULL;
NTSTATUS atkDispatch(PDEVICE_OBJECT dev,PIRP irp)
{
//we need the irp's stack location to get some patameters and majorfuntions
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp);
NTSTATUS status = STATUS_SUCCESS;
ULONG ret_len = 0;
while (dev == g_cdo)//we generate only one device:g_cbo
{
if (irpsp->MajorFunction == IRP_MJ_CREATE || irpsp->MajorFunction == IRP_MJ_CLOSE)
{
break;
}
if (irpsp->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
PVOID buffer = irp->AssociatedIrp.SystemBuffer;
ULONG inlen = irpsp->Parameters.DeviceIoControl.InputBufferLength;
ULONG outlen = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
{
case ATK_SEND_STR:
ASSERT(buffer != NULL);
ASSERT(inlen > 0);
ASSERT(outlen == 0);
DbgPrint("ATK_SEND_STR success\n");
break;
case KTA_RECV_STR:
default:
status = STATUS_INVALID_PARAMETER;
break;
}
}
break //一开始竟然忘了这个break,摔
}
//since the dev is not we want,just finish this IRP
irp->IoStatus.Information = ret_len;
irp->IoStatus.Status = status;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;
}
VOID UnloadDriver(PDRIVER_OBJECT driver)
{
UNICODE_STRING control_device_symbol = RTL_CONSTANT_STRING(control_device_syb);
ASSERT(g_cdo != NULL);
IoDeleteSymbolicLink(&control_device_symbol);
IoDeleteDevice(g_cdo);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
NTSTATUS status;
ULONG i;
//UCHAR buffer[256] = { 0 };
//generate a control device object and a symbol link
UNICODE_STRING sddl = RTL_CONSTANT_STRING(L"D:P(A;;GA;;;WD)"); //a parameter in IoCreateDevice--DefaultSDDLString
UNICODE_STRING control_device_object = RTL_CONSTANT_STRING(L"\\Device\\cdo_5113ef8");
UNICODE_STRING control_device_symbol = RTL_CONSTANT_STRING(control_device_syb);
KdBreakPoint();
//IoCreateDeviceSecure comes from wdmsec.h
status = IoCreateDeviceSecure(driver, 0, &control_device_object, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &sddl, (LPCGUID)&cbo_uuid, &g_cdo);
if (!NT_SUCCESS(status))
return status;
IoDeleteSymbolicLink(&control_device_symbol);
status = IoCreateSymbolicLink(&control_device_symbol, &control_device_object);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(g_cdo);
return status;
}
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
driver->MajorFunction[i] = atkDispatch;
}
driver->DriverUnload = UnloadDriver;
g_cdo->Flags &= ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
编译报错说:unresolved external symbol _WdmlibIoCreateDeviceSecure@36 referenced in function _DriverEntry@8
没道理啊,lib难道没链接上去?
MSDN查一下这个IoCreateDeviceSecure
Requirements
- Header Wdmsec.h (include Wdmsec.h)
- Library Wdmsec.lib
把这个lib添加进项目->属性->链接->输入->附加依赖项就好啦~
照着敲了一次,但有几个地方还是不理解
- CTL_CODE这个宏中的METHOD_BUFFERED规定了后面使用的是irp->AssociatedIrp.SystemBuffer,这个和使用irp->UserBuffer的区别在哪里呢?
- g_cbo是一个生成的设备对象,那一个驱动对象可以同时生成多个设备对象吗?Ring3程序和内核通信时的直接目标就是这个我们暴露出来的设备对象吗?通过IRP来进行数据摆渡?
这些疑问留待日后学习