EXE和SYS通信DeviceIoControl

时间:2022-09-06 13:56:01

IoCode.h

#ifndef IOCODE_HEAD_FILE
#define IOCODE_HEAD_FILE
#pragma once




// 内核使用
#define DRV_DEVICE L"\\Device\\helloworld" //设备名称
#define DRV_SYSLNK L"\\??\\helloworld" //符号链接

//应用层使用
#define DEVICE_NAME_USER L"\\\\.\\helloworld"


#define IOCTL_SENDEVENT CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) //发送事件
#define IOCTL_OUTBUFFER CTL_CODE(FILE_DEVICE_UNKNOWN,0x801,METHOD_BUFFERED,FILE_ANY_ACCESS) //获取数据
#define IOCTL_CLOSEEVEN CTL_CODE(FILE_DEVICE_UNKNOWN,0x802,METHOD_BUFFERED,FILE_ANY_ACCESS) //关闭事件




#pragma pack(push, 1)

typedef struct _SEND_EVENT
{
DWORD dStructSize; //结构大小
DWORD UniqueProcessId; //通信进程ID
DWORD hEvent; //通信事件
} SEND_EVENT, *PSEND_EVENT;

typedef struct _CLOSE_EVENT
{
DWORD dStructSize; //结构大小
DWORD UniqueProcessId; //通信进程ID
}CLOSE_EVENT, *PCLOSE_EVENT;


typedef struct _OUTBUFFER
{
DWORD dStructSize; //结构大小
DWORD UniqueProcessId; //通信进程ID
DWORD ParentId; //父进程
DWORD ProcessId; //子进程
char szProcessImage[16]; //进程名
} OUTBUFFER, *POUTBUFFER;

#pragma pack(pop)


#endif


EXE

#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include <assert.h>
#include "..\..\Define\IoCode.h"




HANDLE g_hEvent;
HANDLE g_hFile;




DWORD WINAPI GetInputDataThreadProc(LPVOID lpParameter)
{
static OUTBUFFER OutputBuffer={0};
DWORD dwOutput;

DeviceIoControl(g_hFile,IOCTL_OUTBUFFER,NULL,0,&OutputBuffer,sizeof(OutputBuffer),&dwOutput,NULL);
while (TRUE)
{
DWORD waitresult=WaitForSingleObject(g_hEvent,INFINITE);
if (waitresult==WAIT_FAILED || waitresult==WAIT_ABANDONED)
{
assert(FALSE);
break;
}
ResetEvent(g_hEvent);
printf("ParentId=%d ProcessId=%d szProcessImage=%s\n",OutputBuffer.ParentId,OutputBuffer.ProcessId,OutputBuffer.szProcessImage);


RtlZeroMemory(&OutputBuffer,sizeof(OutputBuffer));
DeviceIoControl(g_hFile,IOCTL_OUTBUFFER,NULL,0,&OutputBuffer,sizeof(OutputBuffer),&dwOutput,NULL);
}

return TRUE;
}


int main (void)
{

DWORD dwOutput;
g_hFile=CreateFile(DEVICE_NAME_USER,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (g_hFile==INVALID_HANDLE_VALUE)
{
assert(FALSE);
}

g_hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
SEND_EVENT sendEvent={0};
sendEvent.dStructSize=sizeof(SEND_EVENT);
sendEvent.UniqueProcessId=GetCurrentProcessId();
sendEvent.hEvent=(DWORD)g_hEvent;
if (DeviceIoControl(g_hFile,IOCTL_SENDEVENT,&sendEvent,sizeof(SEND_EVENT),NULL,0,&dwOutput,NULL))
{
CreateThread(NULL,NULL,GetInputDataThreadProc,NULL,NULL,NULL);
}

getchar();
getchar();

CLOSE_EVENT closeEvent={0};
closeEvent.dStructSize=sizeof(CLOSE_EVENT);
closeEvent.UniqueProcessId=GetCurrentProcessId();
DeviceIoControl(g_hFile,IOCTL_CLOSEEVEN,&closeEvent,sizeof(CLOSE_EVENT),NULL,0,&dwOutput,NULL);
CloseHandle(g_hEvent);
CloseHandle(g_hFile);

getchar();
getchar();
return 0;
}

SYS


stdafx.h

#ifndef _STDAFX_HEAD_FILE
#define _STDAFX_HEAD_FILE
#pragma once
#include <ntifs.h>
#include <ntddk.h>
#include <ntintsafe.h>
#include "..\Define\IoCode.h"


//减少对象引用计数
#define SafeDereferenceObject(Object) { if(Object){ObDereferenceObject(Object);Object=NULL;} }

//删除指针
#define SafeFreeDelete(pData) { if(pData){ExFreePool(pData);pData=NULL;} }

//设备扩展结构
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName;
UNICODE_STRING ustrSymLinkName;

}DEVICE_EXTENSION, *PDEVICE_EXTENSION;

//IRP列表
typedef struct _tagPendingIrpList
{
LIST_ENTRY ListEntry;
PIRP MarkIrpPend;
}PENDINGIRPLIST, *PPENDINGIRPLIST;


#endif


#include "stdafx.h"static PRKEVENT g_CommunicationEventObject=NULL;			//通信事件static DWORD	g_CommunicationUniqueProcessId=0;			//通信进程IDstatic KSPIN_LOCK g_IrpPendingrSpinLock;					//IRP挂起互斥static LIST_ENTRY g_IrpPendingListHead;						//IRP挂起列表UCHAR * PsGetProcessImageFileName(PEPROCESS Process);//获取进程名  PCHAR GetProcessName16ByProcessId(HANDLE ProcessId){	//定义变量  	PUCHAR ProcessName = NULL;	PEPROCESS ProcessObj;	NTSTATUS status;	//进程ID和返回一个引用指针的过程EPROCESS结构  	status=PsLookupProcessByProcessId(ProcessId, &ProcessObj);	if (NT_SUCCESS(status))	{		// ImageFileName    : [16]  "SogouExplorer.e"  		//使用这个函数,只能获取进程名称是16的长度,后面的被截取了。。。  		ProcessName = PsGetProcessImageFileName(ProcessObj);		ObfDereferenceObject(ProcessObj);	}	return ProcessName;}//创建设备  NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject){	//定义变量  	NTSTATUS status;	PDEVICE_OBJECT pDevObj;	PDEVICE_EXTENSION pDevExt;	OBJECT_ATTRIBUTES ObjectAttributes;	HANDLE hThread = NULL;	//初始化字符串	UNICODE_STRING devname;	UNICODE_STRING symLinkName;	RtlInitUnicodeString(&devname, DRV_DEVICE);	RtlInitUnicodeString(&symLinkName, DRV_SYSLNK);	//创建设备	status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &devname, FILE_DEVICE_UNKNOWN, NULL, TRUE, &pDevObj);	if (!NT_SUCCESS(status))	{		KdPrint(("创建设备失败\n"));		return status;	}	pDevObj->Flags |= DO_BUFFERED_IO;;	pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;	pDevExt->pDevice = pDevObj;	pDevExt->ustrDeviceName = devname;	pDevExt->ustrSymLinkName = symLinkName;	//创建符号连接	status = IoCreateSymbolicLink(&symLinkName, &devname);	if (!NT_SUCCESS(status))	{		KdPrint(("创建符号连接失败\n"));		IoDeleteDevice(pDevObj);		return status;	}	return STATUS_SUCCESS;}//打开设备NTSTATUS DriverCreate(IN PDEVICE_OBJECT pDevobj, IN PIRP pIrp){	//返回成功	UNREFERENCED_PARAMETER(pDevobj);	pIrp->IoStatus.Information = 0;	pIrp->IoStatus.Status = STATUS_SUCCESS;	IoCompleteRequest(pIrp, IO_NO_INCREMENT);	return STATUS_SUCCESS;}//关闭设备NTSTATUS DriverClose(IN PDEVICE_OBJECT pDevobj, IN PIRP pIrp){	//返回成功	UNREFERENCED_PARAMETER(pDevobj);	pIrp->IoStatus.Information = 0;	pIrp->IoStatus.Status = STATUS_SUCCESS;	IoCompleteRequest(pIrp, IO_NO_INCREMENT);	return STATUS_SUCCESS;}//取消挂起的请求VOID CancelIoCompleteRequest(IN PIRP Irp){	PIO_STACK_LOCATION psl = IoGetCurrentIrpStackLocation(Irp);	PIO_STACK_LOCATION pPendingsl;	PPENDINGIRPLIST IrpPendingListHead;	PLIST_ENTRY Head = NULL;	PLIST_ENTRY Next = NULL;	KIRQL      OldIrql;	BOOLEAN  IsWork = TRUE;	PIRP  pCurIrp = NULL;	while (IsWork)	{		pCurIrp = NULL;		KeAcquireSpinLock(&g_IrpPendingrSpinLock, &OldIrql);		Head = ((PLIST_ENTRY)&g_IrpPendingListHead);		Next = Head->Flink;		while (Next != Head)		{			IrpPendingListHead = CONTAINING_RECORD(Next, PENDINGIRPLIST, ListEntry);			if (IrpPendingListHead == NULL)			{				ASSERT(FALSE);				IsWork = FALSE;				break;			}			pPendingsl = IoGetCurrentIrpStackLocation(IrpPendingListHead->MarkIrpPend);			if (pPendingsl == NULL)			{				ASSERT(FALSE);				IsWork = FALSE;				break;			}			if (pPendingsl->FileObject == psl->FileObject)			{				pCurIrp = IrpPendingListHead->MarkIrpPend;				RemoveEntryList(Next);				break;			}			Next = Next->Flink;		}		if (Next == Head)		{			IsWork = FALSE;		}		KeReleaseSpinLock(&g_IrpPendingrSpinLock, OldIrql);		if (pCurIrp)		{			IoCancelIrp(pCurIrp);		}	}	return;}//移除取消的IRPVOID RemoveCencelIrp(IN PIRP Irp){	PIO_STACK_LOCATION psl = IoGetCurrentIrpStackLocation(Irp);	PIO_STACK_LOCATION pPendingsl;	PPENDINGIRPLIST IrpPendingListHead;	PLIST_ENTRY Head = NULL;//->Flink	PLIST_ENTRY Next = NULL;	KIRQL      OldIrql;	KeAcquireSpinLock(&g_IrpPendingrSpinLock, &OldIrql);	Head = ((PLIST_ENTRY)&g_IrpPendingListHead);	Next = Head->Flink;	while (Next != Head)	{		IrpPendingListHead = CONTAINING_RECORD(Next, PENDINGIRPLIST, ListEntry);		pPendingsl = IoGetCurrentIrpStackLocation(IrpPendingListHead->MarkIrpPend);		if (!pPendingsl)		{			break;		}		if (pPendingsl->FileObject == psl->FileObject)		{			RemoveEntryList(Next);			SafeFreeDelete(IrpPendingListHead);			break;		}		Next = Next->Flink;	}	KeReleaseSpinLock(&g_IrpPendingrSpinLock, OldIrql);	return;}NTSTATUS DriverCleanUp(IN PDEVICE_OBJECT pDevobj, IN PIRP pIrp){	//取消挂起的请求	CancelIoCompleteRequest(pIrp);	SafeDereferenceObject(g_CommunicationEventObject);	g_CommunicationUniqueProcessId = 0;	pIrp->IoStatus.Information = 0;	pIrp->IoStatus.Status = STATUS_SUCCESS;	IoCompleteRequest(pIrp, IO_NO_INCREMENT);	return STATUS_SUCCESS;}VOID CancelIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){	RemoveCencelIrp(Irp);	IoReleaseCancelSpinLock(Irp->CancelIrql);	Irp->IoStatus.Status = STATUS_CANCELLED;	Irp->IoStatus.Information = 0;	IoCompleteRequest(Irp, IO_NO_INCREMENT);	return;}//控制函数NTSTATUS DriverControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){	NTSTATUS status = STATUS_UNSUCCESSFUL;	PIO_STACK_LOCATION psl = IoGetCurrentIrpStackLocation(Irp);							//获取当前IRP	ULONG  IoCtrlCode = psl->Parameters.DeviceIoControl.IoControlCode;					//控制码	ULONG  InputBufferLength = psl->Parameters.DeviceIoControl.InputBufferLength;		//输入长度	ULONG  OutputBufferLength = psl->Parameters.DeviceIoControl.OutputBufferLength;		//输出长度	PVOID  pSystemBuffer = Irp->AssociatedIrp.SystemBuffer;								//buff	switch (IoCtrlCode)	{	case IOCTL_SENDEVENT:		//发送事件	{		if (pSystemBuffer && InputBufferLength == sizeof(SEND_EVENT))		{			PSEND_EVENT pSendEvent = (PSEND_EVENT)pSystemBuffer;			if (pSendEvent->dStructSize == sizeof(SEND_EVENT) || pSendEvent->UniqueProcessId == PsGetCurrentProcessId())			{				status = ObReferenceObjectByHandle(pSendEvent->hEvent, EVENT_ALL_ACCESS, *ExEventObjectType, KernelMode, &g_CommunicationEventObject, NULL);				if (NT_SUCCESS(status))				{					g_CommunicationUniqueProcessId = PsGetCurrentProcessId();				}			}		}	}	break;	case IOCTL_OUTBUFFER:	//接受数据	{		if (pSystemBuffer && OutputBufferLength == sizeof(OUTBUFFER))		{			PPENDINGIRPLIST pPendIrplist = NULL;			KIRQL      OldIrql;			pPendIrplist = (PPENDINGIRPLIST)ExAllocatePool(NonPagedPool, sizeof(PENDINGIRPLIST));			RtlZeroMemory(pPendIrplist, sizeof(PENDINGIRPLIST));			IoSetCancelRoutine(Irp, CancelIrp);			IoMarkIrpPending(Irp);			pPendIrplist->MarkIrpPend = Irp;			KeAcquireSpinLock(&g_IrpPendingrSpinLock, &OldIrql);			InsertHeadList(&g_IrpPendingListHead, &pPendIrplist->ListEntry);			KeReleaseSpinLock(&g_IrpPendingrSpinLock, OldIrql);			status = STATUS_PENDING;			Irp->IoStatus.Status = status;			return status;		}	}	break;	case IOCTL_CLOSEEVEN:			//关闭事件	{		if (pSystemBuffer  && InputBufferLength == sizeof(CLOSE_EVENT))		{			PCLOSE_EVENT pSendClose = (PCLOSE_EVENT)pSystemBuffer;			if (pSendClose->dStructSize == sizeof(CLOSE_EVENT) || pSendClose->UniqueProcessId == PsGetCurrentProcessId())			{				SafeDereferenceObject(g_CommunicationEventObject);				g_CommunicationUniqueProcessId = 0;				status = STATUS_SUCCESS;			}		}	}	break;	default:		break;	}	Irp->IoStatus.Status = status;	IoCompleteRequest(Irp, IO_NO_INCREMENT);	return status;}void NotificationData(HANDLE ParentId, HANDLE ProcessId){	do	{		if (!g_CommunicationEventObject)break;		char* pName = GetProcessName16ByProcessId(ProcessId);		if (pName == NULL)break;		OUTBUFFER outBuff = { 0 };		outBuff.dStructSize = sizeof(OUTBUFFER);		outBuff.UniqueProcessId = g_CommunicationUniqueProcessId;		outBuff.ParentId = ParentId;		outBuff.ProcessId = ProcessId;		RtlCopyMemory(outBuff.szProcessImage, pName, 16);		KIRQL      OldIrql;		KeAcquireSpinLock(&g_IrpPendingrSpinLock, &OldIrql);		while (!IsListEmpty(&g_IrpPendingListHead))		{			NTSTATUS Status = STATUS_UNSUCCESSFUL;			ULONG_PTR Information = 0;			PLIST_ENTRY pEntry = RemoveHeadList(&g_IrpPendingListHead);			PPENDINGIRPLIST pPendIrp = CONTAINING_RECORD(pEntry, PENDINGIRPLIST, ListEntry);			PIRP Irp = pPendIrp->MarkIrpPend;			PIO_STACK_LOCATION psl = IoGetCurrentIrpStackLocation(Irp);			SafeFreeDelete(pPendIrp);			if (psl->Parameters.DeviceIoControl.OutputBufferLength == sizeof(OUTBUFFER))			{				RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &outBuff, psl->Parameters.DeviceIoControl.OutputBufferLength);				Status = STATUS_SUCCESS;				Information = psl->Parameters.DeviceIoControl.OutputBufferLength;			}			IoSetCancelRoutine(Irp, NULL);			Irp->IoStatus.Status = Status;			Irp->IoStatus.Information = Information;			IoCompleteRequest(Irp, IO_NO_INCREMENT);			KeSetEvent(g_CommunicationEventObject, 0, FALSE);		}		KeReleaseSpinLock(&g_IrpPendingrSpinLock, OldIrql);	} while (FALSE);	return;}// 处理进程销毁VOID HandleProcessDestroy(HANDLE ParentId, HANDLE ProcessId){	NotificationData(ParentId, ProcessId);	return;}// 处理进程创建VOID HandleProcessCreate(HANDLE ParentId, HANDLE ProcessId){	NotificationData(ParentId, ProcessId);	return;}//进程创建通知回调函数VOID CreateProcessNotify(HANDLE ParentId, HANDLE ProcessId, BOOLEAN Create){	if (Create)		HandleProcessCreate(ParentId, ProcessId);	else		HandleProcessDestroy(ParentId,ProcessId);	return;}VOID DriverUnload(IN PDRIVER_OBJECT DriverObject){	SafeDereferenceObject(g_CommunicationEventObject);	g_CommunicationUniqueProcessId = 0;	PsSetCreateProcessNotifyRoutine((PCREATE_PROCESS_NOTIFY_ROUTINE)CreateProcessNotify, TRUE);	return;}NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath){	NTSTATUS status;	DriverObject->DriverUnload = DriverUnload;	//创建设备	status = CreateDevice(DriverObject);	if (!NT_SUCCESS(status))	{		ASSERT(FALSE);		return STATUS_UNSUCCESSFUL;	}	if (DriverObject->DeviceObject)	{		DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverCreate;		DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverClose;		DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DriverCleanUp;		DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverControl;	}	DbgBreakPoint();	InitializeListHead(&g_IrpPendingListHead);	KeInitializeSpinLock(&g_IrpPendingrSpinLock);	status = PsSetCreateProcessNotifyRoutine((PCREATE_PROCESS_NOTIFY_ROUTINE)CreateProcessNotify, FALSE);	return STATUS_SUCCESS;}