Hi all!
1)Actually I want to develop a minifilter driver to block the upload access from browser site ( For eg: I want to upload a profile picture on Facebook, I click on the upload button so that it will open an "open dialog " local directory where I can search the picture. I want to block this upload dialog or restrict access to the file system directory). I looked upon UI windows automation where I can block this open dialog but the real problem is drag and drop. Do u guys know any idea about how to approach or is there any change in the IRP callback data to identify whether this IRP is from the particular browser or site.
I wrote a code that gives the process image path and fileName (TEXTFILE.txt) when I open the TEXTFILE.txt
#include<fltKernel.h>
#include<dontuse.h>
#include “ntddk.h”
typedef NTSTATUS(*QUERY_INFO_PROCESS) (
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
QUERY_INFO_PROCESS ZwQueryInformationProcess;
#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, “Not valid for kernel mode drivers”)
PFLT_FILTER FilterHandle;
FLT_PREOP_CALLBACK_STATUS MiniPreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext);
FLT_POSTOP_CALLBACK_STATUS MiniPostCreate(Inout PFLT_CALLBACK_DATA Data,
In PCFLT_RELATED_OBJECTS FltObjects,
In_opt PVOID CompletionContext,
In FLT_POST_OPERATION_FLAGS Flags);
NTSTATUS NullQueryTeardown(In PCFLT_RELATED_OBJECTS FltObjects,In FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags);
const FLT_OPERATION_REGISTRATION Callbacks =
{
{IRP_MJ_CREATE, 0 , MiniPreCreate, MiniPostCreate},
{IRP_MJ_OPERATION_END}
};
NTSTATUS MiniUnload(FLT_FILTER_UNLOAD_FLAGS Flags)
{
UNREFERENCED_PARAMETER(Flags);
PAGED_CODE();
KdPrint((“Driver UNloaded\r\n”));
FltUnregisterFilter(FilterHandle);
return STATUS_SUCCESS;
}
const FLT_REGISTRATION FilterRegistration = {
sizeof(FLT_REGISTRATION),
FLT_REGISTRATION_VERSION,0,
NULL,
Callbacks,
MiniUnload,
NULL, NullQueryTeardown, NULL, NULL, NULL, NULL, NULL, NULL
};
NTSTATUS GetProcessImageName(HANDLE processId, PUNICODE_STRING ProcessImageName)
{
NTSTATUS status;
ULONG returnedLength;
ULONG bufferLength;
HANDLE hProcess= NULL;
PVOID buffer;
PEPROCESS eProcess;
PUNICODE_STRING imageName;
PAGED_CODE(); // this eliminates the possibility of the IDLE Thread/Process
status = PsLookupProcessByProcessId(processId, &eProcess);
if (NT_SUCCESS(status))
{
status = ObOpenObjectByPointer(eProcess, 0, NULL, 0, 0, KernelMode, &hProcess);
if (NT_SUCCESS(status))
{
}
else {
DbgPrint("ObOpenObjectByPointer Failed: %08x\n", status);
}
ObDereferenceObject(eProcess);
}
else {
DbgPrint("PsLookupProcessByProcessId Failed: %08x\n", status);
}
if (NULL == ZwQueryInformationProcess) {
UNICODE_STRING routineName;
RtlInitUnicodeString(&routineName, L"ZwQueryInformationProcess");
ZwQueryInformationProcess =
(QUERY_INFO_PROCESS)MmGetSystemRoutineAddress(&routineName);
if (NULL == ZwQueryInformationProcess) {
DbgPrint("Cannot resolve ZwQueryInformationProcess\n");
}
}
/* Query the actual size of the process path */
status = ZwQueryInformationProcess(hProcess,
ProcessImageFileName,
NULL, // buffer
0, // buffer size
&returnedLength);
if (STATUS_INFO_LENGTH_MISMATCH != status) {
return status;
}
/* Check there is enough space to store the actual process
path when it is found. If not return an error with the
required size */
bufferLength = returnedLength - sizeof(UNICODE_STRING);
if (ProcessImageName->MaximumLength < bufferLength)
{
ProcessImageName->MaximumLength = (USHORT)bufferLength;
return STATUS_BUFFER_OVERFLOW;
}
/* Allocate a temporary buffer to store the path name */
buffer = ExAllocatePoolWithTag(NonPagedPool, returnedLength, 'uLT1');
if (NULL == buffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Retrieve the process path from the handle to the process */
status = ZwQueryInformationProcess(hProcess,
ProcessImageFileName,
buffer,
returnedLength,
&returnedLength);
if (NT_SUCCESS(status))
{
/* Copy the path name */
imageName = (PUNICODE_STRING)buffer;
RtlCopyUnicodeString(ProcessImageName, imageName);
}
/* Free the temp buffer which stored the path */
ExFreePoolWithTag(buffer, 'uLT1');
return status;
}
FLT_PREOP_CALLBACK_STATUS MiniPreCreate(PFLT_CALLBACK_DATA Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext = NULL);
PAGED_CODE();
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
FLT_POSTOP_CALLBACK_STATUS MiniPostCreate(Inout PFLT_CALLBACK_DATA Data,In PCFLT_RELATED_OBJECTS FltObjects,In_opt PVOID CompletionContext,In FLT_POST_OPERATION_FLAGS Flags)
{
UNREFERENCED_PARAMETER(CompletionContext);
UNREFERENCED_PARAMETER(Flags);
PAGED_CODE();
if (Data->RequestorMode == KernelMode)
{
return FLT_POSTOP_FINISHED_PROCESSING;
}
if (Data->Iopb->MajorFunction == IRP_MJ_WRITE || Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION || Data->Iopb->MajorFunction == IRP_MJ_CREATE)
{
PFLT_FILE_NAME_INFORMATION FileNameInfo;
NTSTATUS status;
WCHAR Name[200];
PEPROCESS objCurProcess = NULL;
HANDLE hProcess ;
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &FileNameInfo);
if (NT_SUCCESS(status))
{
status = FltParseFileNameInformation(FileNameInfo);
if (NT_SUCCESS(status))
{
if (FileNameInfo->Name.MaximumLength < 260)
{
RtlCopyMemory(Name, FileNameInfo->Name.Buffer, FileNameInfo->Name.MaximumLength);
_wcsupr(Name);
if (wcsstr(Name, L"TEXTFILE.TXT") != NULL)
{
KdPrint(("post create and file name matched"));
UNICODE_STRING fullPath;
objCurProcess = IoThreadToProcess(Data->Thread);
hProcess = PsGetProcessId(objCurProcess);
fullPath.Length = 0;
fullPath.MaximumLength = 520;
fullPath.Buffer = (PWSTR)ExAllocatePoolWithTag(NonPagedPool, 520, 'uUT1');
GetProcessImageName(hProcess, &fullPath);
PFILE_OBJECT file = FltObjects->FileObject;
KdPrintEx((DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "%wZ is writing to [ %ws ]\n\n", fullPath, file->FileName.Buffer));
//To block the IO OPERATIONS
//auto params = &Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess;
/*if (params == GENERIC_WRITE || params == GENERIC_READ || params == GENERIC_ALL)
{
KdPrint(("File creation ACCESS DENIED: %wZ \n", &Data->Iopb->TargetFileObject->FileName));
FltCancelFileOpen(FltObjects->Instance, FltObjects->FileObject);
FltReleaseFileNameInformation(FileNameInfo);
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
Data->IoStatus.Information = 0;
return FLT_POSTOP_FINISHED_PROCESSING;
}*/
}
}
}
}
FltReleaseFileNameInformation(FileNameInfo);
}
return FLT_POSTOP_FINISHED_PROCESSING;
}
NTSTATUS NullQueryTeardown(
In PCFLT_RELATED_OBJECTS FltObjects,
In FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(Flags);
PAGED_CODE();
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING PsGetProcessImageFileNameStr = { 0 };
RtlInitUnicodeString(&PsGetProcessImageFileNameStr, L"PsGetProcessImageFileName");
KdPrint(("driver loaded successfully"));
if (NT_SUCCESS(status))
{
status = FltStartFiltering(FilterHandle);
if (!NT_SUCCESS(status))
{
FltUnregisterFilter(FilterHandle);
}
}
return status;
}
Sometimes This code gives Blue Screen of Death.
The output of my code when I upload my TEXTFILE from a site from Microsoft edge browser its process name is browserbroker.exe and runtimebroker.exe
- This ZwQueryInformationProcess I referred in
https://stackoverflow.com/questions/3707133/how-to-use-zwqueryinformationprocess-to-get-processimagefilename-in-a-kernel-dri
Why can’t I use header files like Windows.h? How can I include these types of header files? I can’t close the handle by using CloseHandle() as I cant use this header file.
Thankyou For reading this! It will be helpful if u have some ideas about how to approach my project or any suggestions.