From 9ac035709aaf0928784b17b7dd196fc5532fc6ec Mon Sep 17 00:00:00 2001 From: GIL Date: Mon, 17 Sep 2018 00:51:14 +0900 Subject: [PATCH] =?UTF-8?q?CommunicationPort=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Common/Common.h | 14 ++++++++ GilRan/GilRan.c | 54 ++++++++++++++++++++-------- GilRan/GilRan.vcxproj | 3 ++ GilRan/GilRan.vcxproj.filters | 9 +++++ GilRan/Port.c | 68 +++++++++++++++++++++++++++++++++++ GilRan/Port.h | 30 ++++++++++++++++ GilRan/PreCreate.c | 25 +++++++++---- GilRan/Utils.c | 6 ++-- GilRan/Utils.h | 6 ++-- 9 files changed, 191 insertions(+), 24 deletions(-) create mode 100644 Common/Common.h create mode 100644 GilRan/Port.c create mode 100644 GilRan/Port.h diff --git a/Common/Common.h b/Common/Common.h new file mode 100644 index 0000000..f7b9456 --- /dev/null +++ b/Common/Common.h @@ -0,0 +1,14 @@ +#pragma once + +#define PORT_NAME L"\\GilRanPort" +#define PORT_BUFFER_SIZE 1024 + +typedef struct _PORT_REQUEST { + HANDLE ProcessID; + WCHAR VolumeName[PORT_BUFFER_SIZE]; + WCHAR FilePath[PORT_BUFFER_SIZE]; +} PORT_REQUEST, *PPORT_REQUEST; + +typedef struct _PORT_RESPONSE { + BOOLEAN Access; +} PORT_RESPONSE, *PPORT_RESPONSE; \ No newline at end of file diff --git a/GilRan/GilRan.c b/GilRan/GilRan.c index ce84148..43b126c 100644 --- a/GilRan/GilRan.c +++ b/GilRan/GilRan.c @@ -18,11 +18,12 @@ Module Name: #include #include +#include "../Common/Common.h" #include "PreCreate.h" +#include "Port.h" #pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers") -PFLT_FILTER gFilterHandle; ULONG_PTR OperationStatusCtx = 1; /************************************************************************* @@ -133,23 +134,47 @@ Return Value: status = FltRegisterFilter( DriverObject, &FilterRegistration, - &gFilterHandle ); + &PortInformation.Filter ); FLT_ASSERT( NT_SUCCESS( status ) ); - if (NT_SUCCESS( status )) { - - // - // Start filtering i/o - // - - status = FltStartFiltering( gFilterHandle ); - - if (!NT_SUCCESS( status )) { - - FltUnregisterFilter( gFilterHandle ); + if (!NT_SUCCESS(status)) return status; + + UNICODE_STRING PortName; + RtlInitUnicodeString(&PortName, PORT_NAME); + + PSECURITY_DESCRIPTOR pSecurityDescriptor; + status = FltBuildDefaultSecurityDescriptor(&pSecurityDescriptor, FLT_PORT_ALL_ACCESS); + if (NT_SUCCESS(status)) { + OBJECT_ATTRIBUTES ObjectAttributes; + InitializeObjectAttributes( + &ObjectAttributes, + &PortName, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + pSecurityDescriptor + ); + + status = FltCreateCommunicationPort( + PortInformation.Filter, + &PortInformation.ServerPort, + &ObjectAttributes, + NULL, + ClientConnect, + ClientDisConnect, + NULL, + 1 + ); + FltFreeSecurityDescriptor(pSecurityDescriptor); + + if (NT_SUCCESS(status)) { + status = FltStartFiltering(PortInformation.Filter); + + if (NT_SUCCESS(status)) return STATUS_SUCCESS; } + FltCloseCommunicationPort(PortInformation.ServerPort); } + FltUnregisterFilter(PortInformation.Filter); return status; } @@ -181,7 +206,8 @@ Return Value: PAGED_CODE(); - FltUnregisterFilter( gFilterHandle ); + FltCloseCommunicationPort(PortInformation.ServerPort); + FltUnregisterFilter( PortInformation.Filter ); return STATUS_SUCCESS; } \ No newline at end of file diff --git a/GilRan/GilRan.vcxproj b/GilRan/GilRan.vcxproj index 88e908a..28f3efb 100644 --- a/GilRan/GilRan.vcxproj +++ b/GilRan/GilRan.vcxproj @@ -35,6 +35,7 @@ + @@ -193,6 +194,8 @@ + + diff --git a/GilRan/GilRan.vcxproj.filters b/GilRan/GilRan.vcxproj.filters index d383e0d..447965f 100644 --- a/GilRan/GilRan.vcxproj.filters +++ b/GilRan/GilRan.vcxproj.filters @@ -33,6 +33,9 @@ Source Files + + Source Files + @@ -46,5 +49,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/GilRan/Port.c b/GilRan/Port.c new file mode 100644 index 0000000..180fd47 --- /dev/null +++ b/GilRan/Port.c @@ -0,0 +1,68 @@ +#include +#include +#include + +#include "../Common/Common.h" +#include "Port.h" + +PORT_INFORMATION PortInformation; + +NTSTATUS +ClientConnect( + _In_ PFLT_PORT ClientPort, + _In_opt_ PVOID ServerPortCookie, + _In_reads_bytes_opt_(SizeOfContext) PVOID ConnectionContext, + _In_ ULONG SizeOfContext, + _Outptr_result_maybenull_ PVOID *ConnectionCookie +) +{ + UNREFERENCED_PARAMETER(ServerPortCookie); + UNREFERENCED_PARAMETER(ConnectionContext); + UNREFERENCED_PARAMETER(SizeOfContext); + UNREFERENCED_PARAMETER(ConnectionCookie); + + FLT_ASSERT(PortInformation.ClientPort == NULL); + FLT_ASSERT(PortInformation.UserProcess == NULL); + + PortInformation.UserProcess = PsGetCurrentProcess(); + PortInformation.ClientPort = ClientPort; + + return STATUS_SUCCESS; +} + +VOID +ClientDisConnect( + _In_opt_ PVOID ConnectionCookie +) +{ + UNREFERENCED_PARAMETER(ConnectionCookie); + + PortInformation.UserProcess = NULL; + FltCloseClientPort(PortInformation.Filter, &PortInformation.ClientPort); +} + +NTSTATUS +PortSendMessage( + _In_ PPORT_REQUEST pPortRequest, + _Out_ PBOOLEAN Access +) +{ + ULONG szResponse = sizeof(FILTER_REPLY_HEADER) + sizeof(PORT_RESPONSE); + PPORT_RESPONSE PortResponse = ExAllocatePoolWithTag(NonPagedPool, szResponse, 'vLIG'); + + if (PortResponse == NULL) return STATUS_UNSUCCESSFUL; + + NTSTATUS status = FltSendMessage( + PortInformation.Filter, + &PortInformation.ClientPort, + pPortRequest, + sizeof(PORT_REQUEST), + &PortResponse, + &szResponse, + NULL + ); + *Access = PortResponse->Access; + + ExFreePoolWithTag(PortResponse, 'vLIG'); + return status; +} \ No newline at end of file diff --git a/GilRan/Port.h b/GilRan/Port.h new file mode 100644 index 0000000..91c5180 --- /dev/null +++ b/GilRan/Port.h @@ -0,0 +1,30 @@ +#pragma once +typedef struct _PORT_INFORMATION { + PDRIVER_OBJECT DriverObject; + PFLT_FILTER Filter; + PFLT_PORT ServerPort; + PEPROCESS UserProcess; + PFLT_PORT ClientPort; +} PORT_INFORMATION, *PPORT_INFORMATION; + +extern PORT_INFORMATION PortInformation; + +NTSTATUS +ClientConnect( + _In_ PFLT_PORT ClientPort, + _In_opt_ PVOID ServerPortCookie, + _In_reads_bytes_opt_(SizeOfContext) PVOID ConnectionContext, + _In_ ULONG SizeOfContext, + _Outptr_result_maybenull_ PVOID *connectionCookie +); + +VOID +ClientDisConnect( + _In_opt_ PVOID ConnectionCookie +); + +NTSTATUS +PortSendMessage( + _In_ PPORT_REQUEST pPortRequest, + _Out_ PBOOLEAN Acces +); \ No newline at end of file diff --git a/GilRan/PreCreate.c b/GilRan/PreCreate.c index f852ffc..9a61a65 100644 --- a/GilRan/PreCreate.c +++ b/GilRan/PreCreate.c @@ -3,7 +3,9 @@ #include #include +#include "../Common/Common.h" #include "PreCreate.h" +#include "Port.h" #include "Utils.h" FLT_PREOP_CALLBACK_STATUS @@ -17,15 +19,26 @@ PreCreate( NTSTATUS status; - WCHAR FilePath[1024], VolumeName[1024]; + PORT_REQUEST PortRequest; - status = GetFilePath(Data, FilePath); - if (!NT_SUCCESS(status)) return FLT_PREOP_COMPLETE; + status = GetFilePath(Data, PortRequest.FilePath); + if (!NT_SUCCESS(status)) return FLT_PREOP_SUCCESS_NO_CALLBACK; - status = GetVolumeName(FltObjects, VolumeName); - if (!NT_SUCCESS(status)) return FLT_PREOP_COMPLETE; + status = GetVolumeName(FltObjects, PortRequest.VolumeName); + if (!NT_SUCCESS(status)) return FLT_PREOP_SUCCESS_NO_CALLBACK; - DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_INFO_LEVEL, "FilePath: %ws%ws\n", VolumeName, FilePath); + PortRequest.ProcessID = PsGetCurrentProcessId(); + BOOLEAN Access; + status = PortSendMessage(&PortRequest, &Access); + + if (NT_SUCCESS(status) && !Access) { + FltCancelFileOpen(FltObjects->Instance, FltObjects->FileObject); + + Data->IoStatus.Status = STATUS_ACCESS_DENIED; + Data->IoStatus.Information = 0; + + return FLT_PREOP_COMPLETE; + } return FLT_PREOP_SUCCESS_NO_CALLBACK; } \ No newline at end of file diff --git a/GilRan/Utils.c b/GilRan/Utils.c index fa21873..da978b9 100644 --- a/GilRan/Utils.c +++ b/GilRan/Utils.c @@ -4,7 +4,8 @@ #include #include "Utils.h" -NTSTATUS GetFilePath( +NTSTATUS +GetFilePath ( _In_ PFLT_CALLBACK_DATA Data, _Out_ PWCHAR pFilePath ) @@ -23,7 +24,8 @@ NTSTATUS GetFilePath( return STATUS_SUCCESS; } -NTSTATUS GetVolumeName( +NTSTATUS +GetVolumeName( _In_ PCFLT_RELATED_OBJECTS FltObjects, _Out_ PWCHAR pVolumeName ) diff --git a/GilRan/Utils.h b/GilRan/Utils.h index 66cbfdc..2745cb0 100644 --- a/GilRan/Utils.h +++ b/GilRan/Utils.h @@ -1,10 +1,12 @@ #pragma once -NTSTATUS GetFilePath( +NTSTATUS +GetFilePath( _In_ PFLT_CALLBACK_DATA Data, _Out_ PWCHAR pFilePath ); -NTSTATUS GetVolumeName( +NTSTATUS +GetVolumeName( _In_ PCFLT_RELATED_OBJECTS FltObjects, _Out_ PWCHAR pVolumeName ); \ No newline at end of file