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;}