none
Ayuda con el desarrollo de un MiniFilter Driver RRS feed

  • Pregunta

  • Estoy desarrollando un antivirus el cual tiene la funcionalidad de monitoreo de archivos en tiempo real utilizando de un driver de tipo minifilter que también estoy desarrollando, cuando instalo el antivirus en windows 7 no hay ningún problema pero cuando se trata de windows 10 la aplicación comienza a disminuir el rendimiento del ordenador hasta imposibilitar su uso siendo necesario reiniciar el equipo para poder seguir usándolo con normalidad. Realicé diversas pruebas e investigaciones y todo lleva a que el driver que desarrollé es el causante del problema, sin embargo, como mencioné con anterioridad, el problema solo se da en Windows 10 y las herramientas de depuración del WDK no pueden ser utilizadas por mi versión de Windows 10 por lo que no soy capaz de encontrar el punto en el que esté mal mi desarrollo. ¿Podrían apoyarme con algún asesoramiento?
    • Editado Alexis OG jueves, 28 de febrero de 2019 19:53
    jueves, 28 de febrero de 2019 17:57

Todas las respuestas

  • Hola Señor:

    ¿Puedes poner algo de driver?

    No haz puesto código alguno.

    Un cordial saludos.

    PD: ¿Por qué hacer un antivirus si hay miles ahsta gratuitos?


    http://electronica-pic.blogspot.com

    domingo, 3 de marzo de 2019 1:00
  • #pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")
    
    SCANNER_DATA ScannerData;
    
    
    NTSTATUS
    ScannerPortConnect(
    	IN PFLT_PORT ClientPort,
    	IN PVOID ServerPortCookie,
    	IN PVOID ConnectionContext,
    	IN ULONG SizeOfContext,
    	OUT PVOID *ConnectionCookie
    );
    
    VOID
    ScannerPortDisconnect(
    	IN PVOID ConnectionCookie
    );
    
    NTSTATUS
    ScannerpScanFileInUserMode(
    	IN PBOOLEAN CheckCache,
    	IN PFILE_OBJECT FileObject,
    	IN PULONG ProcID,
    	OUT PBOOLEAN SafeToOpen
    );
    
    
    
    
    #ifdef ALLOC_PRAGMA
    #pragma alloc_text(INIT, DriverEntry)
    #pragma alloc_text(PAGE, ScannerInstanceSetup)
    #pragma alloc_text(PAGE, ScannerPreCreate)
    #pragma alloc_text(PAGE, ScannerPortConnect)
    #pragma alloc_text(PAGE, ScannerPortDisconnect)
    #endif
    
    
    
    const FLT_OPERATION_REGISTRATION Callbacks[] = {
    
    	{ IRP_MJ_CREATE,
    	  0,
    	  ScannerPreCreate,
    	  ScannerPostCreate},
    
    	{ IRP_MJ_CLEANUP,
    	  0,
    	  ScannerPreCleanup,
    	  ScannerPostCleanup},
    
    	{ IRP_MJ_OPERATION_END}
    };
    
    
    const FLT_CONTEXT_REGISTRATION ContextRegistration[] = {
    
    	{ FLT_STREAMHANDLE_CONTEXT,
    	  0,
    	  NULL,
    	  sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
    	  'chBS' },
    
    	{ FLT_CONTEXT_END }
    };
    
    const FLT_REGISTRATION FilterRegistration = {
    
    	sizeof(FLT_REGISTRATION),         //  Size
    	FLT_REGISTRATION_VERSION,           //  Version
    	0,                                  //  Flags
    	ContextRegistration,                //  Context Registration.
    	Callbacks,                          //  Operation callbacks
    	ScannerUnload,                      //  FilterUnload
    	ScannerInstanceSetup,               //  InstanceSetup
    	ScannerQueryTeardown,               //  InstanceQueryTeardown
    	NULL,                               //  InstanceTeardownStart
    	NULL,                               //  InstanceTeardownComplete
    	NULL,                               //  GenerateFileName
    	NULL,                               //  GenerateDestinationFileName
    	NULL                                //  NormalizeNameComponent
    };
    
    
    NTSTATUS ScannerpScanFileInUserMode(
    	IN PBOOLEAN CheckCache,
    	IN PFILE_OBJECT FileObject,
    	IN PULONG ProcID,
    	OUT PBOOLEAN SafeToOpen
    )
    {
    	NTSTATUS status;
    	SCANNER_NOTIFICATION notification;
    	ULONG replyLength;
    	UNICODE_STRING DOSVol;
    	LARGE_INTEGER Timeout;
    	ULONG HashValue = 0;
    
    	UNICODE_STRING FilePath;
    	FilePath.Length = 0;
    	FilePath.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR);
    	FilePath.Buffer = ExAllocatePoolWithTag(NonPagedPool, FilePath.MaximumLength, 'chBS');
    	*SafeToOpen = TRUE;
    	status = IoVolumeDeviceToDosName(FileObject->DeviceObject, &DOSVol);
    
    	if (NT_SUCCESS(status))
    	{
    		if (DOSVol.Buffer == NULL || FileObject->FileName.Buffer == NULL)
    		{
    			//DbgPrint("Null error\n");
    			return STATUS_SUCCESS;
    		}
    
    		if ((DOSVol.Length + FileObject->FileName.Length) > 511)
    		{
    			//DbgPrint("Xlarge");
    			return STATUS_SUCCESS;
    		}
    
    		RtlUnicodeStringCopy(&FilePath, &DOSVol);
    		RtlUnicodeStringCat(&FilePath, &FileObject->FileName);
    		RtlStringCchCopyUnicodeString(&notification.Name, FilePath.Length, &FilePath);
    		status = RtlHashUnicodeString(&FilePath, TRUE, HASH_STRING_ALGORITHM_DEFAULT, &HashValue);
    
    		notification.Hash = HashValue;
    		notification.CheckCache = *CheckCache;
    		notification.ProcId = *ProcID;
    		//DbgPrint("%u %u\n",notification.Hash, notification.ProcId);
    
    
    		if (FilePath.Buffer != NULL)
    			ExFreePoolWithTag(FilePath.Buffer, 'chBS');
    
    
    
    		if (ScannerData.ClientPort == NULL)
    			return STATUS_SUCCESS;
    
    		replyLength = sizeof(SCANNER_REPLY);
    		Timeout.QuadPart = -((LONGLONG)5 * 10 * 1000 * 1000);
    
    
    		status = FltSendMessage(ScannerData.Filter,
    			&ScannerData.ClientPort,
    			&notification,
    			sizeof(notification),
    			&notification,
    			&replyLength,
    			&Timeout);
    
    		if (STATUS_SUCCESS == status)
    			*SafeToOpen = ((PSCANNER_REPLY)&notification)->SafeToOpen;
    		else
    		{
    
    			if (STATUS_TIMEOUT == status)
    				DbgPrint("TO: %u %ws\n", notification.Hash, notification.Name);
    			else
    				DbgPrint("E: %u %ws\n", notification.Hash, notification.Name);
    
    		}
    
    	}
    
    	return STATUS_SUCCESS;
    }
    
    NTSTATUS
    DriverEntry(
    	IN PDRIVER_OBJECT DriverObject,
    	IN PUNICODE_STRING RegistryPath
    )
    {
    	OBJECT_ATTRIBUTES oa;
    	UNICODE_STRING uniString;
    	PSECURITY_DESCRIPTOR sd;
    	NTSTATUS status;
    
    	UNREFERENCED_PARAMETER(RegistryPath);
    	status = FltRegisterFilter(DriverObject,
    		&FilterRegistration,
    		&ScannerData.Filter);
    
    
    	if (!NT_SUCCESS(status)) {
    
    		return status;
    	}
    
    
    	RtlInitUnicodeString(&uniString, ScannerPortName);
    	status = FltBuildDefaultSecurityDescriptor(&sd, FLT_PORT_ALL_ACCESS);
    
    	if (NT_SUCCESS(status)) {
    
    		InitializeObjectAttributes(&oa,
    			&uniString,
    			OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    			NULL,
    			sd);
    
    		status = FltCreateCommunicationPort(ScannerData.Filter,
    			&ScannerData.ServerPort,
    			&oa,
    			NULL,
    			ScannerPortConnect,
    			ScannerPortDisconnect,
    			NULL,
    			1);
    		FltFreeSecurityDescriptor(sd);
    
    		if (NT_SUCCESS(status)) {
    
    			status = FltStartFiltering(ScannerData.Filter);
    
    			if (NT_SUCCESS(status)) {
    
    				return STATUS_SUCCESS;
    			}
    
    			FltCloseCommunicationPort(ScannerData.ServerPort);
    		}
    	}
    
    	FltUnregisterFilter(ScannerData.Filter);
    
    	return status;
    }
    
    
    NTSTATUS
    ScannerPortConnect(
    	IN PFLT_PORT ClientPort,
    	IN PVOID ServerPortCookie,
    	IN PVOID ConnectionContext,
    	IN ULONG SizeOfContext,
    	OUT PVOID *ConnectionCookie
    )
    {
    	PAGED_CODE();
    
    	UNREFERENCED_PARAMETER(ServerPortCookie);
    	UNREFERENCED_PARAMETER(ConnectionContext);
    	UNREFERENCED_PARAMETER(SizeOfContext);
    	UNREFERENCED_PARAMETER(ConnectionCookie);
    
    	ASSERT(ScannerData.ClientPort == NULL);
    	ASSERT(ScannerData.UserProcess == NULL);
    
    	ScannerData.UserProcess = PsGetCurrentProcess();
    	ScannerData.ClientPort = ClientPort;
    
    	DbgPrint("Connected, port=0x%X\n", ClientPort);
    
    	return STATUS_SUCCESS;
    }
    
    
    VOID
    ScannerPortDisconnect(
    	IN PVOID ConnectionCookie
    )
    {
    	UNREFERENCED_PARAMETER(ConnectionCookie);
    
    	PAGED_CODE();
    	FltCloseClientPort(ScannerData.Filter, &ScannerData.ClientPort);
    	ScannerData.UserProcess = NULL;
    }
    
    
    NTSTATUS
    ScannerUnload(
    	FLT_FILTER_UNLOAD_FLAGS Flags
    )
    {
    	UNREFERENCED_PARAMETER(Flags);
    
    	FltCloseCommunicationPort(ScannerData.ServerPort);
    
    
    	FltUnregisterFilter(ScannerData.Filter);
    
    	return STATUS_SUCCESS;
    }
    
    NTSTATUS
    ScannerInstanceSetup(
    	IN PCFLT_RELATED_OBJECTS FltObjects,
    	IN FLT_INSTANCE_SETUP_FLAGS Flags,
    	IN DEVICE_TYPE VolumeDeviceType,
    	IN FLT_FILESYSTEM_TYPE VolumeFilesystemType
    )
    {
    	UNREFERENCED_PARAMETER(FltObjects);
    	UNREFERENCED_PARAMETER(Flags);
    	UNREFERENCED_PARAMETER(VolumeFilesystemType);
    
    	PAGED_CODE();
    
    	ASSERT(FltObjects->Filter == ScannerData.Filter);
    
    	return STATUS_SUCCESS;
    }
    
    NTSTATUS
    ScannerQueryTeardown(
    	IN PCFLT_RELATED_OBJECTS FltObjects,
    	IN FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
    )
    {
    	UNREFERENCED_PARAMETER(FltObjects);
    	UNREFERENCED_PARAMETER(Flags);
    
    	return STATUS_SUCCESS;
    }
    
    FLT_PREOP_CALLBACK_STATUS
    ScannerPreCleanup(
    	__inout PFLT_CALLBACK_DATA Data,
    	IN PCFLT_RELATED_OBJECTS FltObjects,
    	__deref_out_opt PVOID *CompletionContext
    )
    {
    
    	NTSTATUS status;
    	PSCANNER_STREAM_HANDLE_CONTEXT context;
    
    	UNREFERENCED_PARAMETER(Data);
    	UNREFERENCED_PARAMETER(CompletionContext);
    
    	status = FltGetStreamHandleContext(FltObjects->Instance,
    		FltObjects->FileObject,
    		&context);
    
    	if (NT_SUCCESS(status))
    	{
    		if (context->RescanRequired = FALSE)
    		{
    			FltReleaseContext(context);
    			return FLT_PREOP_SUCCESS_NO_CALLBACK;
    
    		}
    
    		FltReleaseContext(context);
    	}
    	else
    		return FLT_PREOP_SUCCESS_NO_CALLBACK;
    
    
    
    	if (!NT_SUCCESS(Data->IoStatus.Status) ||
    		(STATUS_REPARSE == Data->IoStatus.Status))
    		return FLT_PREOP_SUCCESS_NO_CALLBACK;
    
    
    
    	return FLT_PREOP_SUCCESS_WITH_CALLBACK;
    }
    
    
    FLT_PREOP_CALLBACK_STATUS
    ScannerPreCreate(
    	__inout PFLT_CALLBACK_DATA Data,
    	__in PCFLT_RELATED_OBJECTS FltObjects,
    	__deref_out_opt PVOID *CompletionContext
    )
    {
    
    	NTSTATUS status;
    
    	UNREFERENCED_PARAMETER(FltObjects);
    	UNREFERENCED_PARAMETER(CompletionContext);
    
    	PAGED_CODE();
    
    
    	if (IoThreadToProcess(Data->Thread) == ScannerData.UserProcess)
    	{
    		return FLT_PREOP_SUCCESS_NO_CALLBACK;
    	}
    
    
    
    	return FLT_PREOP_SUCCESS_WITH_CALLBACK;
    
    
    }
    
    NTSTATUS MyFltQueryInformationFile(PFLT_INSTANCE             Instance,
    	PFILE_OBJECT              FileObject,
    	PVOID                     FileInformation,
    	ULONG                     Length,
    	FILE_INFORMATION_CLASS    FileInformationClass,
    	PULONG                    LengthReturned)
    {
    	PFLT_CALLBACK_DATA  Data;
    	NTSTATUS            ntRes;
    
    	ntRes = FltAllocateCallbackData(Instance,
    		FileObject,
    		&Data);
    	if (!NT_SUCCESS(ntRes))
    	{
    		return ntRes;
    	}
    	Data->Iopb->MajorFunction = IRP_MJ_QUERY_INFORMATION;
    	Data->Iopb->IrpFlags = IRP_SYNCHRONOUS_API;
    	Data->Iopb->Parameters.QueryFileInformation.FileInformationClass = FileInformationClass;
    	Data->Iopb->Parameters.QueryFileInformation.Length = Length;
    	Data->Iopb->Parameters.QueryFileInformation.InfoBuffer = FileInformation;
    	FltPerformSynchronousIo(Data);
    	ntRes = Data->IoStatus.Status;
    	if (NT_SUCCESS(ntRes) &&
    		ARGUMENT_PRESENT(LengthReturned))
    	{
    		*LengthReturned = (ULONG)Data->IoStatus.Information;
    	}
    	FltFreeCallbackData(Data);
    	return ntRes;
    }
    
    
    FLT_POSTOP_CALLBACK_STATUS
    ScannerPostCreate(
    	IN OUT PFLT_CALLBACK_DATA Data,
    	IN PCFLT_RELATED_OBJECTS FltObjects,
    	IN PVOID CompletionContext,
    	IN FLT_POST_OPERATION_FLAGS Flags
    )
    {
    	PSCANNER_STREAM_HANDLE_CONTEXT scannerContext;
    	FLT_POSTOP_CALLBACK_STATUS returnStatus = FLT_POSTOP_FINISHED_PROCESSING;
    	NTSTATUS status;
    	BOOLEAN safeToOpen;
    	BOOLEAN IsDir;
    	BOOLEAN Cache = TRUE;
    	ULONG ProcId = 0;
    	FILE_STANDARD_INFORMATION FileInfo;
    
    
    	OBJECT_ATTRIBUTES objAttributes;
    	PFLT_FILE_NAME_INFORMATION pFileNameInformation;
    	HANDLE hFile = NULL;
    	IO_STATUS_BLOCK ioStatusBlock;
    
    
    	UNREFERENCED_PARAMETER(CompletionContext);
    	UNREFERENCED_PARAMETER(Flags);
    
    	if (!NT_SUCCESS(Data->IoStatus.Status) ||
    		(STATUS_REPARSE == Data->IoStatus.Status)) {
    
    		return FLT_POSTOP_FINISHED_PROCESSING;
    	}
    
    
    	if (FltObjects->FileObject->DeviceObject == NULL)
    		return FLT_POSTOP_FINISHED_PROCESSING;
    
    
    	//if (FlagOn( Data->Iopb->Parameters.Create.Options, FILE_COMPLETE_IF_OPLOCKED) )  
    	//{
    	//	DbgPrint( "Oplocked presente\n");
    	//	return FLT_POSTOP_FINISHED_PROCESSING ;
    
    	//}
    
    	if (FlagOn(Data->Iopb->Parameters.Create.Options, FILE_OPEN_REQUIRING_OPLOCK))
    	{
    		DbgPrint("FILE_OPEN_REQUIRING_OPLOCK ");
    		return FLT_POSTOP_FINISHED_PROCESSING;
    	}
    
    	if (Data->IoStatus.Status == STATUS_OPLOCK_BREAK_IN_PROGRESS)
    	{
    		DbgPrint("Oplocked riesgo\n");
    		return FLT_POSTOP_FINISHED_PROCESSING;
    
    	}
    
    	//if (FlagOn( Data->Iopb->OperationFlags, SL_OPEN_PAGING_FILE ) )  
    	//{
    	//	return FLT_POSTOP_FINISHED_PROCESSING ;	
    	//	DbgPrint( "Archivo PAGING");
    	//}
    
    
    	if ((Data->Iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_FILTER_OPLOCK) ||
    		(Data->Iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_BATCH_OPLOCK) ||
    		(Data->Iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_1) ||
    		(Data->Iopb->Parameters.FileSystemControl.Common.FsControlCode == FSCTL_REQUEST_OPLOCK_LEVEL_2))
    	{
    		DbgPrint("WARNING: WFI_PostCreate()...FsControlCode is OPLOCK ");
    		return FLT_POSTOP_FINISHED_PROCESSING;
    	}
    
    	//if( FlagOn(Data->Iopb->Parameters.Create.Options, FILE_RESERVE_OPFILTER) )
     //     {
     //     DbgPrint("WARNING: WFI_PostCreate()...FILE_RESERVE_OPFILTER ");
     //     return FLT_POSTOP_FINISHED_PROCESSING;
     //     }
    
    
    
    	status = FltIsDirectory(FltObjects->FileObject, FltObjects->Instance, &IsDir);
    	if (NT_SUCCESS(status))
    	{
    		if (IsDir == TRUE)
    			return FLT_POSTOP_FINISHED_PROCESSING;
    
    		status = MyFltQueryInformationFile(FltObjects->Instance, FltObjects->FileObject, (PVOID)&FileInfo, sizeof(FileInfo), FileStandardInformation, NULL);
    
    		if (NT_SUCCESS(status))
    		{
    			if (FileInfo.Directory == TRUE)
    				return FLT_POSTOP_FINISHED_PROCESSING;
    		}
    		else
    		{
    			return FLT_POSTOP_FINISHED_PROCESSING;
    		}
    
    
    		status = FltGetFileNameInformation(Data,
    			FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP,
    			&pFileNameInformation);
    
    		if (NT_SUCCESS(status))
    		{
    			InitializeObjectAttributes(&objAttributes,
    				&pFileNameInformation->Name,
    				OBJ_KERNEL_HANDLE,
    				NULL,
    				NULL);
    
    			status = FltCreateFile(FltObjects->Filter,
    				FltObjects->Instance,
    				&hFile,
    				GENERIC_READ,
    				&objAttributes,
    				&ioStatusBlock,
    				(PLARGE_INTEGER)NULL,
    				FILE_ATTRIBUTE_NORMAL,
    				FILE_SHARE_READ,
    				FILE_OPEN,
    				FILE_COMPLETE_IF_OPLOCKED,
    				NULL,
    				0,
    				IO_NO_PARAMETER_CHECKING);
    
    			if (!NT_SUCCESS(status))
    			{
    				DbgPrint("Error Create %wZ\n", &pFileNameInformation->Name);
    
    
    				status = FltAllocateContext(ScannerData.Filter,
    					FLT_STREAMHANDLE_CONTEXT,
    					sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
    					PagedPool,
    					&scannerContext);
    
    				if (NT_SUCCESS(status))
    				{
    					scannerContext->RescanRequired = TRUE;
    
    					(VOID)FltSetStreamHandleContext(FltObjects->Instance,
    						FltObjects->FileObject,
    						FLT_SET_CONTEXT_REPLACE_IF_EXISTS,
    						scannerContext,
    						NULL);
    
    
    					FltReleaseContext(scannerContext);
    				}
    
    				FltReleaseFileNameInformation(pFileNameInformation);
    				return FLT_POSTOP_FINISHED_PROCESSING;
    			}
    			else
    			{
    				FltClose(hFile);
    
    			}
    			FltReleaseFileNameInformation(pFileNameInformation);
    
    
    		}
    
    		ProcId = FltGetRequestorProcessId(Data);
    
    		(VOID)ScannerpScanFileInUserMode(&Cache,
    			FltObjects->FileObject,
    			&ProcId,
    			&safeToOpen);
    
    
    
    		if (!safeToOpen)
    		{
    			FltCancelFileOpen(FltObjects->Instance, FltObjects->FileObject);
    			Data->IoStatus.Status = STATUS_ACCESS_DENIED;
    			Data->IoStatus.Information = 0;
    
    			return FLT_POSTOP_FINISHED_PROCESSING;
    		}
    
    
    		if (FltObjects->FileObject->WriteAccess)
    		{
    
    
    			status = FltAllocateContext(ScannerData.Filter,
    				FLT_STREAMHANDLE_CONTEXT,
    				sizeof(SCANNER_STREAM_HANDLE_CONTEXT),
    				PagedPool,
    				&scannerContext);
    
    			if (NT_SUCCESS(status))
    			{
    				scannerContext->RescanRequired = TRUE;
    
    				(VOID)FltSetStreamHandleContext(FltObjects->Instance,
    					FltObjects->FileObject,
    					FLT_SET_CONTEXT_REPLACE_IF_EXISTS,
    					scannerContext,
    					NULL);
    
    
    				FltReleaseContext(scannerContext);
    			}
    		}
    
    	}
    
    	return returnStatus;
    }
    
    
    FLT_POSTOP_CALLBACK_STATUS
    ScannerPostCleanup(
    	IN OUT PFLT_CALLBACK_DATA Data,
    	IN PCFLT_RELATED_OBJECTS FltObjects,
    	IN PVOID CompletionContext,
    	IN FLT_POST_OPERATION_FLAGS Flags
    )
    {
    	PSCANNER_STREAM_HANDLE_CONTEXT scannerContext;
    	FLT_POSTOP_CALLBACK_STATUS returnStatus = FLT_POSTOP_FINISHED_PROCESSING;
    	NTSTATUS status;
    	BOOLEAN safeToOpen;
    	BOOLEAN Cache = FALSE;
    	ULONG  ProcId = 0;
    
    
    	UNREFERENCED_PARAMETER(CompletionContext);
    	UNREFERENCED_PARAMETER(Flags);
    
    
    	if (FltObjects->FileObject->DeviceObject != NULL)
    	{
    
    
    		ProcId = FltGetRequestorProcessId(Data);
    
    		(VOID)ScannerpScanFileInUserMode(&Cache,
    			FltObjects->FileObject,
    			&ProcId,
    			&safeToOpen);
    
    	}
    
    	return returnStatus;
    }

    Esta es una parte de mi código, no se en que pueda estar fallando ya que me  basé en la documentación de microsoft al igual que en un repositorio que tienen en Github.


    • Editado Alexis OG lunes, 25 de marzo de 2019 19:29
    jueves, 21 de marzo de 2019 15:55