ã©ãããããããã¢ã¯ã»ã¹ã管çããç¹å®ã®ããã»ã¹ã®äžéšãšããŠãã¡ã€ã«ã·ã¹ãã ã«ãªã¯ãšã¹ãããªãã€ã¬ã¯ãããã¿ã¹ã¯ã«ééããæ©äŒããããŸããã ã·ã³ãã«ã§ç°¡åã«æ§æå¯èœãªãœãªã¥ãŒã·ã§ã³ãå®è£
ããå¿
èŠããããŸããã
ããã¹ããã¡ã€ã«ã䜿çšããŠæ§æãããMiniFilterãã©ã€ããŒãéçºããããšã«ããŸããã
MiniFilterã®äžè¬çãªçšèªãæ€èšããŠãã ããã
ãã£ã«ã¿ãªã³ã°ã¯ãWindowsãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«ä»å±ã®ãããããã£ã«ã¿ãŒãããŒãžã£ãŒãä»ããŠå®è¡ããããããã£ã«ã¿ãŒãèªã¿èŸŒããšãã«ã®ã¿ã¢ã¯ãã£ãã«ãªããŸãã ãã£ã«ã¿ãŒãããŒãžã£ãŒã¯ããã¡ã€ã«ã·ã¹ãã ã¹ã¿ãã¯ã«çŽæ¥æ¥ç¶ããŸãã ãããã£ã«ã¿ãŒã¯ããã£ã«ã¿ãŒãããŒãžã£ãŒæ©èœã䜿çšããŠå
¥å/åºåæäœã®ããŒã¿ãåŠçããããã«ç»é²ãããŠããããããã¡ã€ã«ã·ã¹ãã ãžã®éæ¥çãªã¢ã¯ã»ã¹ãååŸããŸãã ç»é²ããã³éå§åŸããããã£ã«ã¿ãŒã¯ãæ§æäžã«æå®ãããI / Oæäœã«é¢ããããŒã¿ã®ã»ãããåãåããå¿
èŠã«å¿ããŠãããã®ããŒã¿ãå€æŽã§ããããããã¡ã€ã«ã·ã¹ãã ã®æäœã«åœ±é¿ãäžããŸãã
次ã®å³ã¯ããã£ã«ã¿ãŒãããŒãžã£ãŒã®æ©èœãç°¡åãªåœ¢åŒã§ç€ºããŠããŸãã
èšäºã®æåŸã«ãããªã³ã¯ã䜿çšããŠãMSDN Webãµã€ãã§ãã詳现ãªçè«æ
å ±ãå
¥æã§ããŸãã ååã§ã¯ãããŸãããããã¹ãŠãå解ãããŸãã
ç§ãã¡ã¯éçºã«åãããæºããå¿
èŠãããããã€ãã®åºæ¬çãªæ§é ãæ€èšããŸãã
äžè¬çãªã°ããŒãã«ããŒã¿ã
typedef struct _MINIFILTER { PDRIVER_OBJECT pDriverObject; PFLT_FILTER pFilter; } MINIFILTER, *PMINIFILTER; MINIFILTER fileManager;
ãã®æ§é ã§ã¯ããã©ã€ããŒã®ãªããžã§ã¯ããžã®ãªã³ã¯ãšãã£ã«ã¿ãŒã€ã³ã¹ã¿ã³ã¹ãžã®ãªã³ã¯ãä¿åããŸãã PFLT_FILTERã¯ãããã£ã«ã¿ãŒãäžæã«èå¥ãããã©ã€ããŒã®å
šæéãéããŠäžå®ã®ãŸãŸã§ããããšã«æ³šæããŠãã ããã ãã£ã«ã¿ãªã³ã°ããã»ã¹ãã¢ã¯ãã£ãåãŸãã¯åæ¢ãããšãã«äœ¿çšãããŸãã
ç»é²ãã£ã«ã¿ãŒ
CONST FLT_REGISTRATION FilterRegistration = { sizeof( FLT_REGISTRATION ),
ããã§ã¯ãããã€ãã®ãã£ãŒã«ãã§åæ¢ãã䟡å€ããããŸãã
- ã³ãŒã«ããã¯-åŠçããæ©èœãšæ©èœã決å®ããæ§é ãžã®ãªã³ã¯ã
- FilterUnloadã¯ããã£ã«ã¿ãŒãç¡å¹ã«ãªã£ããšãã«åŒã³åºãããé¢æ°ã§ãã
- FilterLoadã¯ããã£ã«ã¿ãŒãåæåããããšãã«åŒã³åºãããé¢æ°ã§ãã
次ã«ãã³ãŒã«ããã¯ã®æ§é ãæ€èšããŸãã
const FLT_OPERATION_REGISTRATION Callbacks[] = { { IRP_MJ_CREATE, 0, PreFileOperationCallback, PostFileOperationCallback }, { IRP_MJ_OPERATION_END } };
ããã§ã¯ãCreateFileæäœãã€ã³ã¿ãŒã»ããããããšã瀺ããŸãããŸãããã¡ã€ã«ã«å¯Ÿããæäœãå®è¡ãããåãšåŸã«åŒã³åºãããé¢æ°ã瀺ããŸãã
次ã«ããã£ã«ã¿ãŒãåæåãããŠç¡å¹ã«ãªã£ããšãã«åŒã³åºãããé¢æ°ã®ã³ãŒãã瀺ããŸãã
NTSTATUS FilterLoad (IN PCFLT_RELATED_OBJECTS FltObjects, IN FLT_INSTANCE_SETUP_FLAGS Flags, IN DEVICE_TYPE VolumeDeviceType, IN FLT_FILESYSTEM_TYPE VolumeFilesystemType) { if (VolumeDeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) { return STATUS_FLT_DO_NOT_ATTACH; } return STATUS_SUCCESS; } NTSTATUS FilterUnload ( IN FLT_FILTER_UNLOAD_FLAGS Flags ) { return STATUS_SUCCESS; }
ãã¹ãŠãããªãæšæºçãªãããã³ãŒãã«è¿œå ã®ã³ã¡ã³ãã¯å¿
èŠãªããšæããŸãã ç§ãã¡ã®ãã©ã€ããŒã¯ãããã¯ãŒã¯ã§ã¯åäœããªãããšã«æ³šæããŠãã ããã
次ã«ããã©ã€ããŒã®åæåé¢æ°ãèŠãŠã¿ãŸãããã
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath ) { int i; NTSTATUS status; PCHAR ConfigInfo; UNICODE_STRING test; DbgPrint("MiniFilter: Started.");
ãããã£ã«ã¿ãŒã®ç»é²ã¯ãå
¥åã§åä¿¡ããtheRriverObjectãåè¿°ã®FilterRegistrationæ§é ãããã³äœæããããã£ã«ã¿ãŒã€ã³ã¹ã¿ã³ã¹fileManager.pFilterãé
眮ãããå€æ°ãžã®ãªã³ã¯ãæž¡ãFltRegisterFilteré¢æ°ãåŒã³åºãããšã«ãã£ãŠå®è¡ãããŸãã ãã£ã«ã¿ãªã³ã°ããã»ã¹ãéå§ããã«ã¯ãFltStartFilteringé¢æ°ïŒfileManager.pFilterïŒãåŒã³åºãå¿
èŠããããŸãã
ãŸããæ§æãã¡ã€ã«ã¯æ¬¡ã®åŒã³åºãã«ãã£ãŠããŠã³ããŒãããã³åŠçãããããšã«æ³šæããŠãã ããConfigInfo = ReadConfigurationFileïŒïŒ; ããããParseConfigurationFileïŒConfigInfoïŒã
æ§æãã¡ã€ã«ããã®ããŒã¿ã¯ã次ã®æ§é ã»ããã«å€æãããŸãã
typedef struct FILE_REDIRECT_RULE { UNICODE_STRING From; UNICODE_STRING To; struct FILE_REDIRECT_RULE *NextRule; }FileRedirectRule, *PFileRedirectRule; struct PROCESS_CONFIGURATION_RULE { UNICODE_STRING ProcessName; struct FILE_REDIRECT_RULE *Rule; }; typedef struct CONFIGURATION_MAP { struct PROCESS_CONFIGURATION_RULE ProcessRule; struct REDIRECT_MAP *NextItem; }ConfigurationMap ,*PConfigurationMap;
ãããæ§é ã¯CONFIGURATION_MAPã§ãProcessRuleããã»ã¹ã®èª¬æãžã®ãªã³ã¯ãšæ¬¡ã®èŠçŽ ãžã®ãã€ã³ã¿ãŒãæ ŒçŽãããŸãã 次ã«ãPROCESS_CONFIGURATION_RULEã«ã¯ãããã»ã¹åãžã®ãªã³ã¯ãšãI / Oãªãã€ã¬ã¯ãã«ãŒã«æ§é ãžã®ãªã³ã¯ãæ ŒçŽãããŸããããã¯ãREDIRECT_MAPãšåæ§ã«ãªã³ã¯ãªã¹ãã§ãã
ãã©ã€ããŒã®ã¢ã³ããŒãæ©èœãèããŠã¿ãŸããããéåžžã«ç°¡åã§ãã
VOID OnUnload( IN PDRIVER_OBJECT DriverObject ) { FltUnregisterFilter(fileManager.pFilter); FreeConfigInfo(); DbgPrint("MiniFilter: Unloaded"); }
ããã§ã¯ããã£ã«ã¿ãŒã®ç»é²ã解é€ãããã¹ãŠã®æ§ææ§é ã解æŸããŸãã
次ã«ãæãèå³æ·±ãéšåãã€ãŸããå
¥å/åºåæäœã®ãªãã€ã¬ã¯ããåŠçããé¢æ°ã«ç§»ããŸãããã ããªãåçŽãªãã©ã€ããŒããããããPreFileOperationCallbackã§ãããå®è¡ããŸãã
FLT_PREOP_CALLBACK_STATUS PreFileOperationCallback ( __inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID *CompletionContext ) { NTSTATUS status; PFILE_OBJECT FileObject; PFileRedirectRule redirectRuleItem; PFLT_FILE_NAME_INFORMATION pFileNameInformation; PConfigurationMap rule; UNICODE_STRING fullPath; UNICODE_STRING processName; PWCHAR Volume; FLT_PREOP_CALLBACK_STATUS returnStatus = FLT_PREOP_SUCCESS_NO_CALLBACK; if(FLT_IS_FS_FILTER_OPERATION(Data)) { return FLT_PREOP_SUCCESS_NO_CALLBACK; }
äž»ãªå€æ°ã決å®ãããã£ã«ã¿ãªã³ã°æžã¿ã®ãã®ãæ¢ã«åä¿¡ããŠãããã©ããã確èªããŸããåä¿¡æžã¿ã®å Žåã¯ããã®æäœãã¹ãããããå¿
èŠããããŸããããããªããšãåŒã³åºãã®ååž°ãååŸã§ããŸãã
if (FltObjects->FileObject != NULL && Data != NULL) { FileObject = Data->Iopb->TargetFileObject; if(FileObject != NULL && Data->Iopb->MajorFunction == IRP_MJ_CREATE) {
ããã§ã¯ãFilterManagerããåãåã£ãæ§é ã®ããŒã¿ã«ç®ãåããŸãã PFLT_CALLBACK_DATAæ§é -çŸåšã®å
¥å/åºåæäœã«é¢ããããŒã¿ãä¿åããŸããFilterManagerã¯ããã¡ã€ã«ã·ã¹ãã ã«ã¢ã¯ã»ã¹ãããšãã«ãã®æ§é ã®ãã£ãŒã«ãã«ãã£ãŠã¬ã€ããããŸãã ãããã£ãŠããã¡ã€ã«ãŸãã¯ãã£ã¬ã¯ããªã«ã¢ã¯ã»ã¹ãããšãã«Windowsã®åäœãå€æŽããå Žåã¯ãPFLT_CALLBACK_DATAã«ãããåæ ããå¿
èŠããããŸãã å
·äœçã«ã¯ããã£ãŒã«ãData-> Iopb-> TargetFileObjectã«èå³ããããŸããããã䜿çšããŠãçŸåšã®ã»ã¯ã·ã§ã³ã®ãã¡ã€ã«ãžã®ãã¹ãååŸããå¿
èŠã«å¿ããŠåŸã§å€æŽããŠãOSã®åäœãå€æŽã§ããŸãã PCFLT_RELATED_OBJECTS-ãã®I / Oæäœã«é¢é£ä»ãããããªããžã§ã¯ãïŒãã¡ã€ã«ãã»ã¯ã·ã§ã³ãªã©ãžã®ãªã³ã¯ãªã©ïŒãå«ãŸããŸãã å¿
èŠãªæ§é ã®èŠçŽ ãæºããããŠããããšã確èªããŠãã ããã ãŸããå®è¡ããŠããã³ã³ããã¹ãã®é¢æ°ãå®éã«MJ_CREATEã§ããããšã確èªããŸãã
processName.Length = 0; processName.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR); processName.Buffer = ExAllocatePoolWithTag(NonPagedPool, processName.MaximumLength,CURRENT_PROCESS_TAG); RtlZeroMemory(processName.Buffer, processName.MaximumLength); status = GetProcessImageName(&processName);
ã³ãŒãã®ãã®ã»ã¯ã·ã§ã³ã§ã¯ããã¹ãšããã»ã¹åã«ã¡ã¢ãªãå²ãåœãŠãŸãã æååã®ãµã€ãºãæ³åã§ããªãã®ã§ãå¯èœãªéãæ倧ã®WCHARæååãéžæããŸãã ãœãŒã¹ã³ãŒãGetProcessImageNameã¯èæ
®ããŸããã次ã®åœ¢åŒã§ãã¡ã€ã«ãžã®ãã«ãã¹ãè¿ããšããèšããŸããïŒ\ Device \ HarddiskVolume4 \ Windows \ notepad.exeã ã€ãŸããã»ã¯ã·ã§ã³ã§ãããå®éã«ã¯ãã¡ã€ã«ãžã®ãã¹ã§ãã
if(NT_SUCCESS(status)) { if(LoggingEnabled()== 1) { DbgPrint("MiniFilter: Process: %ws", processName.Buffer); } } else { return FLT_PREOP_SUCCESS_NO_CALLBACK; } rule = FindRuleByProcessName(&processName,GetRedirectionMap());
FindRuleByProcessNameé¢æ°ã¯ãæåããå ŽåãçŸåšã®ããã»ã¹ã®ãªãã€ã¬ã¯ãã«ãŒã«ãå«ããªã³ã¯ãªã¹ãã®æåã®èŠçŽ ãè¿ããŸãããã以å€ã®å Žåã¯NULLãè¿ããŸãã
ExFreePool(processName.Buffer); if(rule != NULL){ if(LoggingEnabled() == 1) { DbgPrint("MiniFilter: File name %ws", FileObject->FileName.Buffer); } redirectRuleItem = rule->ProcessRule.Rule;
äžèŠãªã¡ã¢ãªã解æŸããNULLã§ã¯ãªããäœããã®ãªããžã§ã¯ããååŸãããããšã確èªããŸãã redirectRuleItem = rule-> ProcessRule.Rule-ãã®ããã»ã¹ã®æåã®ã«ãŒã«ãžã®ã¢ã¯ã»ã¹ã
while(redirectRuleItem) { if(RtlCompareUnicodeString(&FileObject->FileName ,&redirectRuleItem->From, FALSE) == 0) { status = FltGetFileNameInformation( Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_ALWAYS_ALLOW_CACHE_LOOKUP, &pFileNameInformation );
ãã®ããã»ã¹ã®ãã¹ãŠã®ã«ãŒã«ã«åŸã£ãŠããã»ãŒãžãéå§ããçŸåšã®ãã¡ã€ã«ãžã®ãªã³ã¯ãæ§æã«ãããã®ãšæ¯èŒããŸãã äžèŽããå Žåãããšãã°ãã©ã®ã»ã¯ã·ã§ã³ã«å±ããŠããããªã©ããã¡ã€ã«ã«é¢ããè¿œå æ
å ±ãååŸããããšããŸãã ãããè¡ãã«ã¯ãFltGetFileNameInformationé¢æ°ã䜿çšããŸãã
if(NT_SUCCESS(status)) { fullPath.Length = 0; fullPath.MaximumLength = NTSTRSAFE_UNICODE_STRING_MAX_CCH * sizeof(WCHAR); fullPath.Buffer = ExAllocatePoolWithTag(NonPagedPool, fullPath.MaximumLength, FULL_PATH_TAG); RtlZeroMemory(fullPath.Buffer, fullPath.MaximumLength); Volume = wcssplt(pFileNameInformation->Volume.Buffer, redirectRuleItem->From.Buffer ); RtlAppendUnicodeToString(&fullPath, Volume); RtlAppendUnicodeToString(&fullPath, redirectRuleItem->To.Buffer); ExFreePool(Volume); ExFreePool(FileObject->FileName.Buffer);
ãã¹ãŠãåé¡ãªãå Žåã¯ãã»ã¯ã·ã§ã³ãéžæããŠããæçµè¡ãäœæããŠãã ããã æçµãã¹=çŸåšã®ã»ã¯ã·ã§ã³+ I / OèŠæ±ã®éä¿¡å
ã
FileObject->FileName.Length = fullPath.Length; FileObject->FileName.MaximumLength = fullPath.MaximumLength; FileObject->FileName.Buffer = fullPath.Buffer; Data->Iopb->TargetFileObject->RelatedFileObject = NULL; Data->IoStatus.Information = IO_REPARSE; Data->IoStatus.Status = STATUS_REPARSE; DbgPrint("MiniFilter: Redirect done %ws", fullPath.Buffer); return FLT_PREOP_COMPLETE;
次ã«ããã¡ã€ã«ãããŒãžã£ãŒããã®èŠæ±ãããäžåºŠåŠçããããã«ã·ã¹ãã æ§é ãæ§æããŸãããããã¯å¥ã®æ¹æ³ã§ã®ã¿ã§ãã ãããè¡ãã«ã¯ããã£ãŒã«ãData-> IoStatus.Information = IO_REPARSEããã³Data-> IoStatus.Status = STATUS_REPARSE;ã«ä»¥äžã®å€ãèšå®ãããšãšãã«ããã¡ã€ã«File-> FileName.Buffer = fullPath.Bufferãžã®æ°ãããã¹ãæå®ããããšãéèŠã§ãã é¢æ°ã®çµæãšããŠãFLT_PROP_COMPLETEãè¿ããŸãã
} } redirectRuleItem = redirectRuleItem->NextRule; } } } } return FLT_PREOP_SUCCESS_NO_CALLBACK; }
ãªãã€ã¬ã¯ããªã¹ãã®æ¬¡ã®èŠçŽ ã«ç§»åããããšãå¿ããªãã§ãã ããã çŸåšã®ãã£ã«ã¿ãŒãããŒãžã£ãŒæäœã§äœãããªãå Žåã¯ãFLT_PREOP_SUCCESS_NO_CALLBACKãè¿ããŸãã
çŸæç¹ã§ã¯ãI / Oåå®çŸ©ã¯1ã€ã®ã»ã¯ã·ã§ã³ã®ãã¬ãŒã ã¯ãŒã¯å
ã§ã®ã¿æ©èœããŸããè€æ°ã®ã»ã¯ã·ã§ã³ããµããŒããããªãã·ã§ã³ããããã°ãããããã«æçš¿ããŸãã
ãã®èšäºã®ãœãŒã¹ã«ããäŸã®ããã«ãç¹å¥ã«èšèšãããinfãã¡ã€ã«ã䜿çšããŠããããã£ã«ã¿ãŒãã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã
æ§æãã¡ã€ã«ã®åœ¢åŒã¯æ¬¡ã®ãšããã§ãã
#minifilter config start { #logging : off #process : \Device\HarddiskVolume4\Windows\notepad.exe { #rule : redirect { #from : \test.txt #to : \data\test.txt } #rule : redirect { #from : \ioman.log #to : \IRCCL.ini } } }
ãã¡ã€ã«ã¯Cãã©ã€ãã®ã«ãŒãã«ããå¿
èŠããããååã¯minifilter.confã§ããå¿
èŠããããŸãã
ãã®ããããã¡ã€ã«I / Oãªã¯ãšã¹ãããªãã€ã¬ã¯ãããæ©èœããããŸãããããã«ããã¡ã€ã«ãžã®ã¢ã¯ã»ã¹ãå¶éããã¡ã«ããºã ã¯éåžžã«ç°¡åã§ãã ã¢ã¯ã»ã¹ãæåŠããå¿
èŠããããã¡ã€ã«ãéžæããã·ã¹ãã æ§é Data-> IoStatus.Status = STATUS_ACCESS_DENIED;ãã®ãã£ãŒã«ãã«æ¬¡ã®å€ãæå®ããå¿
èŠããããŸãã é¢æ°ã®çµæãšããŠFLT_PROP_COMPLETEãå¿ããã«è¿ãããã«ããŠãã ããã
ãµãŒãã¹ãéå§ãŸãã¯åæ¢ããã«ã¯ãKMDãããŒãžã£ãŒã䜿çšããŸãã PoolTagã¡ã¢ãªãªãŒã¯ãåæããã«ã¯ã ãããã°ã«ã€ããŠã¯ãDbgViewã䜿çšã§ããŸãããWindows Vista以éã§ã¯ããããã°ã¡ãã»ãŒãžãã¢ã¯ãã£ãã«ããå¿
èŠããããŸããããè¡ãã«ã¯ã次ã®ãã¹ã«DWORDã¬ãžã¹ããªããŒãäœæããŸããHKEY_LOCAL_MACHINE\ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ Debug Print Filter 8ã
64ãããããŒãžã§ã³ã®Windows 7ã§ãã©ã€ããŒãèµ·åããã«ã¯ããã©ã€ããŒçœ²åã®æ€èšŒãç¡å¹ã«ããå¿
èŠããããŸãããããè¡ãã«ã¯ãã³ã³ãã¥ãŒã¿ãŒãåèµ·åããã·ã¹ãã ã®èµ·åæã«F8ãæŒããŠããã©ã€ããŒçœ²å匷å¶ãç¡å¹ã«ãããéžæãããããã©ã€ããŒçœ²å匷å¶ãªãŒããŒã©ã€ãïŒDSEOïŒãŠãŒãã£ãªãã£ã䜿çšããŸãã ãã®ãŠãŒãã£ãªãã£ã䜿çšãããšããã©ã€ããŒããããã°ããããã®ãã¹ãã¢ãŒããã¢ã¯ãã£ãã«ããåœã®èšŒææžã§ç®çã®ãã©ã€ããŒã«çœ²åã§ããŸããããã«ãããæçµçã«åé¡ãªã䜿çšã§ããŸãã
ãã®ã³ã°ãæå¹ãã©ããã«é¢ä¿ãªããDbgViewã§ãµãŒãã¹ãéå§ããåŸãåæ§ã®ãã®ã芳å¯ããå¿
èŠããããŸãã
ãããã£ãŠããã©ã€ããŒã¯DeviceTreeã調ã¹ãŸãã
ã³ãŒãã¯ãŸã ããªãæªå å·¥ã§ãããæ¹åããå¿
èŠããããšä»ãå ããããšãã§ããŸãããå
šäœçã«ã¯åé¡ãªãæ©èœããŸãã å®éãBSODãæã£ãŠããå Žåãããã¯ç§ã®ããã§ã¯ãããŸããïŒã Windows 7 X86ããã³Windows 7 IA64ã§ã®ã¿ãã¹ãæžã¿ã
ãœãŒã¹ãšãŠãŒãã£ãªãã£ãžã®ãªã³ã¯ïŒ
publish.rarèªãã¹ããã®ïŒ- MSDNããã¥ã¡ã³ã
- ãã¡ã€ã«ã·ã¹ãã ãšãã£ã«ã¿ãŒã®ããã°
PSã ç§ã¯ã·ã¹ãã ããã°ã©ãã³ã°ã®å°é家ã§ã¯ãªãããããã®èšäºã¯å®å
šã§ã¯ãªããšäž»åŒµããŸãã 掻åã®æ§è³ªäžãMicrosoft Dynamics CRMïŒ.netãasp.netãªã©ïŒã®éçºã«åŸäºããŠããŸãã
ããªãã®ã³ã¡ã³ããæè¿ããŸãã