143 lines
6.7 KiB
C++
143 lines
6.7 KiB
C++
#include "DriverCommon.h"
|
|
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
|
|
UNREFERENCED_PARAMETER(FltObjects);
|
|
UNREFERENCED_PARAMETER(CompletionContext);
|
|
|
|
if (Data->RequestorMode == KernelMode) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
if (KeGetCurrentIrql() > APC_LEVEL) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
|
|
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
|
|
NTSTATUS status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo);
|
|
if (!NT_SUCCESS(status) || !nameInfo) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
|
|
status = FltParseFileNameInformation(nameInfo);
|
|
if (!NT_SUCCESS(status) || !nameInfo->Name.Buffer || nameInfo->Name.Length == 0) {
|
|
FltReleaseFileNameInformation(nameInfo);
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
}
|
|
|
|
HANDLE Pid = PsGetCurrentProcessId();
|
|
FLT_PREOP_CALLBACK_STATUS callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
|
|
ULONG CreateDisposition = (Data->Iopb->Parameters.Create.Options >> 24) & 0xFF;
|
|
BOOLEAN IsCreateAction = (CreateDisposition == FILE_CREATE || CreateDisposition == FILE_SUPERSEDE || CreateDisposition == FILE_OVERWRITE || CreateDisposition == FILE_OVERWRITE_IF || CreateDisposition == FILE_OPEN_IF);
|
|
ULONG DesiredAccess = Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess;
|
|
|
|
ULONG Operation = 0;
|
|
if (IsCreateAction) Operation |= OP_CREATE;
|
|
if (DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES | WRITE_DAC | WRITE_OWNER | GENERIC_WRITE)) Operation |= OP_WRITE;
|
|
if (DesiredAccess & (DELETE | FILE_DELETE_CHILD)) Operation |= OP_DELETE;
|
|
|
|
if (Operation != 0) {
|
|
ULONG RuleCode = 0;
|
|
BOOLEAN Kill = FALSE;
|
|
if (EvaluateFileRule(Pid, &nameInfo->Name, Operation, NULL, 0, &RuleCode, &Kill)) {
|
|
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
|
|
QueueRuleProcessTermination(Pid, Kill);
|
|
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
|
callbackStatus = FLT_PREOP_COMPLETE;
|
|
}
|
|
}
|
|
|
|
FltReleaseFileNameInformation(nameInfo);
|
|
return callbackStatus;
|
|
}
|
|
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreSetInfo(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
|
|
UNREFERENCED_PARAMETER(FltObjects);
|
|
UNREFERENCED_PARAMETER(CompletionContext);
|
|
|
|
if (Data->RequestorMode == KernelMode) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
if (KeGetCurrentIrql() > APC_LEVEL) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
|
|
FILE_INFORMATION_CLASS infoClass = Data->Iopb->Parameters.SetFileInformation.FileInformationClass;
|
|
if (infoClass != FileDispositionInformation && infoClass != FileRenameInformation && infoClass != FileRenameInformationEx) {
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
}
|
|
|
|
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
|
|
if (!NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo)) || !nameInfo) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
if (!NT_SUCCESS(FltParseFileNameInformation(nameInfo)) || !nameInfo->Name.Buffer) {
|
|
FltReleaseFileNameInformation(nameInfo);
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
}
|
|
|
|
HANDLE Pid = PsGetCurrentProcessId();
|
|
FLT_PREOP_CALLBACK_STATUS callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
ULONG Operation = 0;
|
|
|
|
if (infoClass == FileDispositionInformation) {
|
|
Operation = OP_DELETE;
|
|
}
|
|
else {
|
|
Operation = OP_RENAME;
|
|
}
|
|
|
|
ULONG RuleCode = 0;
|
|
BOOLEAN Kill = FALSE;
|
|
if (EvaluateFileRule(Pid, &nameInfo->Name, Operation, NULL, 0, &RuleCode, &Kill)) {
|
|
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
|
|
QueueRuleProcessTermination(Pid, Kill);
|
|
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
|
callbackStatus = FLT_PREOP_COMPLETE;
|
|
}
|
|
|
|
FltReleaseFileNameInformation(nameInfo);
|
|
return callbackStatus;
|
|
}
|
|
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_PreWrite(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
|
|
UNREFERENCED_PARAMETER(FltObjects);
|
|
UNREFERENCED_PARAMETER(CompletionContext);
|
|
|
|
if (Data->RequestorMode == KernelMode) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
if (KeGetCurrentIrql() > APC_LEVEL) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
if (Data->Iopb->IrpFlags & (IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO | IRP_NOCACHE)) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
|
|
ULONG WriteLength = Data->Iopb->Parameters.Write.Length;
|
|
if (WriteLength == 0) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
|
|
PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
|
|
if (!NT_SUCCESS(FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInfo)) || !nameInfo) return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
if (!NT_SUCCESS(FltParseFileNameInformation(nameInfo)) || !nameInfo->Name.Buffer) {
|
|
FltReleaseFileNameInformation(nameInfo);
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
}
|
|
|
|
HANDLE Pid = PsGetCurrentProcessId();
|
|
FLT_PREOP_CALLBACK_STATUS callbackStatus = FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
|
|
PVOID SystemBuffer = NULL;
|
|
PMDL Mdl = Data->Iopb->Parameters.Write.MdlAddress;
|
|
if (!Mdl && Data->Iopb->Parameters.Write.WriteBuffer && KeGetCurrentIrql() <= APC_LEVEL) {
|
|
if (NT_SUCCESS(FltLockUserBuffer(Data))) Mdl = Data->Iopb->Parameters.Write.MdlAddress;
|
|
}
|
|
if (Mdl) SystemBuffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority | MdlMappingNoExecute);
|
|
|
|
ULONG RuleCode = 0;
|
|
BOOLEAN Kill = FALSE;
|
|
if (EvaluateFileRule(Pid, &nameInfo->Name, OP_WRITE, SystemBuffer, WriteLength, &RuleCode, &Kill)) {
|
|
SendMessageToUser(RuleCode, (ULONG)(ULONG_PTR)Pid, nameInfo->Name.Buffer, nameInfo->Name.Length);
|
|
QueueRuleProcessTermination(Pid, Kill);
|
|
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
|
|
callbackStatus = FLT_PREOP_COMPLETE;
|
|
}
|
|
|
|
FltReleaseFileNameInformation(nameInfo);
|
|
return callbackStatus;
|
|
}
|
|
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_SetSecurity(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
|
|
UNREFERENCED_PARAMETER(Data);
|
|
UNREFERENCED_PARAMETER(FltObjects);
|
|
UNREFERENCED_PARAMETER(CompletionContext);
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
}
|
|
|
|
FLT_PREOP_CALLBACK_STATUS ProtectFile_FileSystemControl(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext) {
|
|
UNREFERENCED_PARAMETER(Data);
|
|
UNREFERENCED_PARAMETER(FltObjects);
|
|
UNREFERENCED_PARAMETER(CompletionContext);
|
|
return FLT_PREOP_SUCCESS_NO_CALLBACK;
|
|
} |