首页
社区
课程
招聘
[求助]RtlCopyMemory数据拷贝失败,想请教下各位~
2019-3-6 21:23 3673

[求助]RtlCopyMemory数据拷贝失败,想请教下各位~

2019-3-6 21:23
3673
本人菜鸡,在学习windows驱动缓冲区IO读的时候,写了这样的代码来试试手。
编译没问题,但是在执行的时候驱动就会有STATUS_ACCESS_VIOLATION 的报错,
应用程序也无法读到驱动传出来的“This is a string from kernel”>-<
似乎是DispatchRead中RtlCopyMemory的问题,但很无奈能力有限,不知道怎么解决
求助各位朋友,希望能有个好的解决方法~

驱动代码Driver.c:
//Driver.c
#include<ntddk.h>

VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
	KdPrint(("Driver Unload!\n"));
	UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\HelloDDK");
	IoDeleteDevice(DriverObject->DeviceObject);
	IoDeleteSymbolicLink(&SymbolicLinkName);
}

NTSTATUS DispatchRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	static PCHAR typeIrp[] = {
		  "IRP_MJ_CREATE			     "
		, "IRP_MJ_CREATE_NAMED_PIPE		 "
		, "IRP_MJ_CLOSE					 "
		, "IRP_MJ_READ					 "
		, "IRP_MJ_WRITE					 "
		, "IRP_MJ_QUERY_INFORMATION		 "
		, "IRP_MJ_SET_INFORMATION		 "
		, "IRP_MJ_QUERY_EA				 "
		, "IRP_MJ_SET_EA				 "
		, "IRP_MJ_FLUSH_BUFFERS			 "
		, "IRP_MJ_QUERY_VOLUME_INFORMATION"
		, "IRP_MJ_SET_VOLUME_INFORMATION "
		, "IRP_MJ_DIRECTORY_CONTROL		 "
		, "IRP_MJ_FILE_SYSTEM_CONTROL	 "
		, "IRP_MJ_DEVICE_CONTROL		 "
		, "IRP_MJ_INTERNAL_DEVICE_CONTROL"
		, "IRP_MJ_SHUTDOWN				 "
		, "IRP_MJ_LOCK_CONTROL			 "
		, "IRP_MJ_CLEANUP				 "
		, "IRP_MJ_CREATE_MAILSLOT		 "
		, "IRP_MJ_QUERY_SECURITY		 "
		, "IRP_MJ_SET_SECURITY			 "
		, "IRP_MJ_POWER					 "
		, "IRP_MJ_SYSTEM_CONTROL		 "
		, "IRP_MJ_DEVICE_CHANGE			 "
		, "IRP_MJ_QUERY_QUOTA			 "
		, "IRP_MJ_SET_QUOTA				 "
		, "IRP_MJ_PNP					 "
		, "IRP_MJ_PNP_POWER				 "
		, "IRP_MJ_MAXIMUM_FUNCTION		 " };

	KdPrint(("%s\n", typeIrp[stack->MajorFunction]));
	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;

}

NTSTATUS DispatchRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	NTSTATUS status = STATUS_SUCCESS;
	ULONG Length;

	
	__try
	{
		Length = stack->Parameters.Read.Length;
		if (Length > 512)
		{
			RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, "This is a string from kernel", strlen("This is a string from kernel"));
			status = STATUS_SUCCESS;
			Length = strlen("This is a string from kernel");
		}
		else
		{
			status = STATUS_INSUFFICIENT_RESOURCES;
			Length = 0;
		}
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		status = GetExceptionCode();
		KdPrint(("DispatchRead failed! 0x%x\n", status));
		Length = 0;
	}

	Irp->IoStatus.Information = Length;	//返回至dwRet
	Irp->IoStatus.Status = status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
	NTSTATUS status;
	PDEVICE_OBJECT DeviceObject;
	UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\HelloDDK");
	UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\HelloDDK");
	DriverObject->DriverUnload = Unload;

	status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("CreateDevice failed! 0x%x\n",status));
		return status;
	}
	
	status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("CreateSymbolicLink failed! 0x%x\n",status));
		IoDeleteDevice(DeviceObject);
		return status;
	}

	ULONG i;
	for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
	{
		DriverObject->MajorFunction[i] = DispatchRoutine;
	}
	DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
	return STATUS_SUCCESS;
}

应用程序代码App.c:
#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>

int main()
{
	HANDLE hDevice = CreateFile(
		TEXT("\\\\.\\HelloDDK"),
		GENERIC_ALL,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL);
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		printf("Device open failed! %d\n", GetLastError());
		return -1;
	}

	DWORD dwRet;
	char readBuffer[1024] = { 0 };
	ReadFile(hDevice, readBuffer, sizeof(readBuffer), &dwRet, NULL);
	printf("DataReadFromKernel:%s\n", readBuffer);
	printf("DataReadSize:%d\n", dwRet);

	CloseHandle(hDevice);
	return 0;
}

在此感谢各位朋友了~

[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞0
打赏
分享
最新回复 (3)
雪    币: 914
活跃值: (2183)
能力值: ( LV5,RANK:68 )
在线值:
发帖
回帖
粉丝
万剑归宗 1 2019-3-7 11:19
2
0
你好骚(6)啊
雪    币: 364
活跃值: (1346)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
wujimaa 1 2019-3-7 12:58
3
0
是不是Irp->AssociatedIrp.SystemBuffer  不让写,你看buffer属性。 RtlCopyMemory之前加断点,调试一下,就知道了
雪    币: 2087
活跃值: (472)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
gaveu屯烫烫 1 2019-3-9 17:10
4
0
wujimaa 是不是Irp->AssociatedIrp.SystemBuffer 不让写,你看buffer属性。 RtlCopyMemory之前加断点,调试一下,就知道了
发现问题所在了,需要等DriverEntry中所有语句执行完毕后再对设备对象的Flags进行一些赋值,才能进行缓冲区读操作
DeviceObject->Flags |= DO_BUFFERED_IO;                                //通知操作系统该设备为缓冲区读写方式
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;                //通知操作系统该设备已可以使用了
谢谢老铁了~
游客
登录 | 注册 方可回帖
返回