NTSTATUS GenerateFileName(IN PFLT_INSTANCE Instance, IN PFILE_OBJECT FileObject, IN PFLT_CALLBACK_DATA CallbackData, IN FLT_FILE_NAME_OPTIONS NameOptions, OUT PBOOLEAN CacheFileNameInformation, OUT PFLT_NAME_CONTROL FileName ) //上层的minifilter过滤驱动的名字请求进行处理 { NTSTATUS Status = STATUS_UNSUCCESSFUL; PFILE_OBJECT StreamObject = FileObject; PFLT_FILE_NAME_INFORMATION FileNameInformation = NULL; BOOLEAN bEncryptResource = FALSE; PFCB Fcb = FileObject->FsContext; PCCB Ccb = FileObject->FsContext2; FsRtlEnterFileSystem(); try { if(IsMyFakeFcb(FileObject)) { ExAcquireResourceSharedLite(Fcb->EncryptResource,TRUE); bEncryptResource = TRUE; if(BooleanFlagOn(Fcb->FcbState,SCB_STATE_SHADOW_CLOSE) || Ccb->StreamFileInfo.StreamObject == NULL) { try_return (Status = STATUS_FILE_DELETED); } else { StreamObject = Ccb->StreamFileInfo.StreamObject; } } ClearFlag(NameOptions,FLT_FILE_NAME_REQUEST_FROM_CURRENT_PROVIDER); if(FlagOn(NameOptions,FLT_FILE_NAME_NORMALIZED)) { ClearFlag(NameOptions,FLT_FILE_NAME_NORMALIZED); SetFlag(NameOptions,FLT_FILE_NAME_OPENED); } if (CallbackData) { PFILE_OBJECT TemFileObject = CallbackData->Iopb->TargetFileObject; CallbackData->Iopb->TargetFileObject = StreamObject; FltSetCallbackDataDirty(CallbackData); Status = FltGetFileNameInformation(CallbackData,NameOptions, &FileNameInformation); CallbackData->Iopb->TargetFileObject = TemFileObject; FltClearCallbackDataDirty(CallbackData); } else { Status = FltGetFileNameInformationUnsafe(StreamObject,Instance, NameOptions, &FileNameInformation); } if(!NT_SUCCESS(Status)) { try_return (Status); } Status = FltCheckAndGrowNameControl(FileName, FileNameInformation->Name.Length); if(!NT_SUCCESS(Status)) { try_return (Status); } RtlCopyUnicodeString(&FileName->Name, &FileNameInformation->Name); if(FileNameInformation != NULL) { FltReleaseFileNameInformation(FileNameInformation); } Status = STATUS_SUCCESS; try_exit: NOTHING; } finally { if(bEncryptResource) { ExReleaseResourceLite( Fcb->EncryptResource ); } } FsRtlExitFileSystem(); return Status; }
FLT_PREOP_CALLBACK_STATUS FLTAPI FilterPreCreate( FLT_CALLBACK_DATA* Data, PCFLT_RELATED_OBJECTS FltObjects, PVOID* CompletionContext ) { NTSTATUS status; FLT_FILE_NAME_INFORMATION *nameInformation; UNICODE_STRING *fullPath; status = FltGetFileNameInformation( Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &nameInformation ); if (status == STATUS_SUCCESS) { status = FltParseFileNameInformation(nameInformation); if (status == STATUS_SUCCESS) { FLT_FILE_LIST_ENTRY *file = FltFileList; fullPath = &nameInformation->Name; if ((Data->Iopb->Parameters.Create.SecurityContext->DesiredAccess & FILE_EXECUTE) //Execute && (nameInformation->FinalComponent.Length == 16 //d3d8.dll/d3d9.dll || nameInformation->FinalComponent.Length == 18)) //d3d10.dll/d3d11.dll { if (wcsncmp(L"d3d8.dll", nameInformation->FinalComponent.Buffer, 8) == 0 || wcsncmp(L"d3d9.dll", nameInformation->FinalComponent.Buffer, 8) == 0 || wcsncmp(L"d3d10.dll", nameInformation->FinalComponent.Buffer, 9) == 0 || wcsncmp(L"d3d11.dll", nameInformation->FinalComponent.Buffer, 9) == 0) { PROCESSID processId; DEVICE_EXTENSION *deviceExtension; processId = FltGetRequestorProcessId(Data); deviceExtension = g_DeviceObject->DeviceExtension; deviceExtension->imageEvent.processID = processId; KeSetEvent(PushGpuAccelerationEvent, 0, FALSE); KeClearEvent(PushGpuAccelerationEvent); DbgPrint("[PUSH] %u loaded %wZ\n", processId, fullPath); } } while (file != 0) { if (fullPath->Length == file->NameLength && wcsncmp(file->Name, fullPath->Buffer, file->NameLength / sizeof(WCHAR)) == 0) { UNICODE_STRING newName; UNICODE_STRING redirect; UNICODE_STRING *currentName; UINT16 newNameSize; WCHAR *buffer; //DbgPrint("[PUSH] %ws matches %wZ", file->Name, fullPath); RtlInitUnicodeString(&newName, PUSH_RAMDISK_DEVICE_NAME L"\\"); // Calculate the size of the name newNameSize = newName.Length + nameInformation->FinalComponent.Length; redirect.Length = newName.Length; redirect.MaximumLength = newNameSize; redirect.Buffer = ExAllocatePool(NonPagedPool, newNameSize); // Copy ramdisk device name into buffer RtlCopyMemory(redirect.Buffer, newName.Buffer, newName.Length); // Append original file name //RtlAppendUnicodeStringToString(&redirect, &nameInformation->FinalComponent); buffer = &redirect.Buffer[redirect.Length / sizeof(WCHAR)]; RtlMoveMemory( buffer, nameInformation->FinalComponent.Buffer, nameInformation->FinalComponent.Length ); redirect.Length += nameInformation->FinalComponent.Length; currentName = &Data->Iopb->TargetFileObject->FileName; // Throw away the current file name ExFreePool(currentName->Buffer); currentName->Length = 0; currentName->MaximumLength = redirect.MaximumLength; currentName->Buffer = ExAllocatePool(NonPagedPool, redirect.MaximumLength); // Copy new path to buffer RtlCopyUnicodeString(currentName, &redirect); // Be nice and give back what was given to us ExFreePool(redirect.Buffer); Data->IoStatus.Information = IO_REPARSE; Data->IoStatus.Status = STATUS_REPARSE; Data->Iopb->TargetFileObject->RelatedFileObject = NULL; FltSetCallbackDataDirty(Data); return FLT_PREOP_COMPLETE; } file = file->NextEntry; } } } return FLT_PREOP_SUCCESS_NO_CALLBACK; }