Windows下内核文件隐藏技术
为防止此代码应用于一些触犯法律方面考虑本篇文章仅讲述基本的逻辑方法完整的代码将不会在文章中展示。首先我们要了解系统或者程序枚举文件的原理它内部基本上就是调用查询API然后在内核中会收到相关请求的IRP。所以我们要实现文件隐藏的话基本上思路是有两个的1、阻断IRP请求不允许查询。这种情况一般是隐藏整个目录使用的而且这种方式波及的范围有点广。2、正常处理IRP请求但是我们需要对返回的结果进行处理即从返回结果中删除我们要隐藏的文件。这种情况类似于hook但是比hook更加的隐蔽、安全。实现文件隐藏我们使用的是MiniFilter这是微软提供给我们的内核驱动框架所以还是非常安全的。逻辑非常简单我们只需要注册 IRP_MJ_DIRECTORY_CONTROL 请求的回调函数处理返回结果即可。一、注册相关回调函数注册回调代码如下CONST FLT_OPERATION_REGISTRATION Callbacks[]{//文件隐藏{IRP_MJ_DIRECTORY_CONTROL,0,NULL,PostDirectoryControl,},{IRP_MJ_OPERATION_END}};二、编写回调函数回调函数的伪代码如下#defineDIR_ENTRY_NEXT_OFFSET(Entry)(*(PULONG)(Entry))#defineDIR_ENTRY_SET_NEXT_OFFSET(Entry,Value)(*(PULONG)(Entry)(Value))FLT_POSTOP_CALLBACK_STATUSPostDirectoryControl(_Inout_ PFLT_CALLBACK_DATA Data,_In_ PCFLT_RELATED_OBJECTS FltObjects,_In_opt_ PVOID CompletionContext,_In_ FLT_POST_OPERATION_FLAGS Flags){ULONG nextOffset0;BOOL removedAllEntriesTRUE;UNICODE_STRING strFilePathName;PFLT_FILE_NAME_INFORMATION nameInfo;PCHAR currentFileInfoNULL;PCHAR blinkFileInfoNULL;PCHAR previousFileInfoNULL;LPWSTR pCurrentDirNULL;UNREFERENCED_PARAMETER(FltObjects);UNREFERENCED_PARAMETER(CompletionContext);UNREFERENCED_PARAMETER(Data);UNREFERENCED_PARAMETER(Flags);if(FltObjectsNULL||FltObjects-FileObjectNULL||Data-Iopb-MinorFunction!IRP_MN_QUERY_DIRECTORY||FlagOn(Flags,FLTFL_POST_OPERATION_DRAINING)){returnFLT_POSTOP_FINISHED_PROCESSING;}if(Data-Iopb-Parameters.DirectoryControl.QueryDirectory.Length0||!NT_SUCCESS(Data-IoStatus.Status)){returnFLT_POSTOP_FINISHED_PROCESSING;}//数据长度ULONG dataLengthData-Iopb-Parameters.DirectoryControl.QueryDirectory.Length;//获取目录/文件的相关数据if(Data-Iopb-Parameters.DirectoryControl.QueryDirectory.MdlAddress!NULL){currentFileInfo(PCHAR)MmGetSystemAddressForMdlSafe(Data-Iopb-Parameters.DirectoryControl.QueryDirectory.MdlAddress,NormalPagePriority);}else{currentFileInfo(PCHAR)Data-Iopb-Parameters.DirectoryControl.QueryDirectory.DirectoryBuffer;}if(currentFileInfoNULL)gotoFINAL;previousFileInfocurrentFileInfo;//保存下来blinkFileInfocurrentFileInfo;ULONG allOffsetLength0;//循环遍历所有的数据while(TRUE){//距离下一个节点的偏移量nextOffsetDIR_ENTRY_NEXT_OFFSET(previousFileInfo);//匹配隐藏文件if(FindHideFile(Data,previousFileInfo,pCurrentDir)){//判断是不是最后一个节点if(nextOffset0){DIR_ENTRY_NEXT_OFFSET(blinkFileInfo)0;}else{DIR_ENTRY_NEXT_OFFSET(blinkFileInfo)nextOffset;FltSetCallbackDataDirty(Data);}}else{removedAllEntriesFALSE;blinkFileInfopreviousFileInfo;}allOffsetLengthnextOffset;previousFileInfonextOffset;if(nextOffset0||allOffsetLengthdataLength)break;}FINAL:if(pCurrentDir){ExFreePoolWithTag(pCurrentDir,MINIFILTER_TAG);pCurrentDirNULL;}returnFLT_POSTOP_FINISHED_PROCESSING;}查找隐藏文件的代码如下部分代码已隐藏以备注代替//查找是否是隐藏文件BOOLFindHideFile(_Inout_ PFLT_CALLBACK_DATA pData,PCHAR pActual,LPWSTR*pCurrentDir){BOOL isRetFALSE;DWORD fileNameLength0;LPCWSTR pFileNameNULL;if(pDataNULL||pActualNULL)gotoFINAL;switch(pData-Iopb-Parameters.DirectoryControl.QueryDirectory.FileInformationClass){caseFileDirectoryInformation:fileNameLength((PFILE_DIRECTORY_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_DIRECTORY_INFORMATION)pActual)-FileName;break;caseFileFullDirectoryInformation:fileNameLength((PFILE_FULL_DIR_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_FULL_DIR_INFORMATION)pActual)-FileName;break;caseFileBothDirectoryInformation:fileNameLength((PFILE_BOTH_DIR_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_BOTH_DIR_INFORMATION)pActual)-FileName;break;caseFileNameInformation:fileNameLength((PFILE_NAMES_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_NAMES_INFORMATION)pActual)-FileName;break;caseFileIdFullDirectoryInformation:fileNameLength((PFILE_ID_FULL_DIR_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_ID_FULL_DIR_INFORMATION)pActual)-FileName;break;caseFileIdBothDirectoryInformation:fileNameLength((PFILE_ID_BOTH_DIR_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_ID_BOTH_DIR_INFORMATION)pActual)-FileName;break;caseFileIdExtdDirectoryInformation:fileNameLength((PFILE_ID_EXTD_DIR_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_ID_EXTD_DIR_INFORMATION)pActual)-FileName;break;caseFileIdGlobalTxDirectoryInformation:fileNameLength((PFILE_ID_GLOBAL_TX_DIR_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_ID_GLOBAL_TX_DIR_INFORMATION)pActual)-FileName;break;caseFileIdExtdBothDirectoryInformation:fileNameLength((PFILE_ID_EXTD_BOTH_DIR_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_ID_EXTD_BOTH_DIR_INFORMATION)pActual)-FileName;break;case79://FileId64ExtdBothDirectoryInformation win11 23H2以后fileNameLength((PFILE_ID_64_EXTD_BOTH_DIR_INFORMATION)pActual)-FileNameLength;pFileName((PFILE_ID_64_EXTD_BOTH_DIR_INFORMATION)pActual)-FileName;break;default:gotoFINAL;}if(fileNameLength0||pFileNameNULL)gotoFINAL;FINAL:returnisRet;}这里对目录/文件信息处理的时候需要根据类型转换相应的结构然后从数据结构中找到对应的目录名/文件名。上述对目录名/文件名的获取应该覆盖了目前大部分的系统起码我测试的win7、win8、win10、win11以及同样内核版本的server系统的x64版本是都没有问题的。OK目前文件隐藏的所有逻辑就已经结束了如果还有不懂MiniFilter框架的后边我可能会出一个MiniFilter的教程或者大家可以去其他的地方先学习一下这个框架。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2594031.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!