首页
社区
课程
招聘
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
2019-4-5 22:03 11164

[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?

2019-4-5 22:03
11164
网上找的要么是wdm的驱动方式来做, 我想用NT的, 就是一开机就加载的, 搜到了minifilter, 但都是禁止文件访问的, 没有只读的例子, 不知道 怎么判断一个路径是U盘里的。
好不容易在github上找到这个代码,尼玛硬生生看不懂啊https://github.com/surajfale/passthrough-minifilter-driver

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

最后于 2019-4-5 23:53 被wumnkx编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (63)
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-7 00:50
2
0
现在已经实现了功能,禁用是没问题的, 只读有点问题, 新建空txt文件可以成功, 写入信息保存时会提示拒绝访问然后弹出另存为, 我想在只读时任何覆盖操作都提示一下就完了该这么做呢? 下面是源码


#include <fltKernel.h>
#include <dontuse.h>
#include <suppress.h>


#pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers")

#define SETTINGS_AUTORUNINF 0x01
#define SETTINGS_EXECUTABLES SETTINGS_AUTORUNINF << 1
#define SETTINGS_BLOCK SETTINGS_AUTORUNINF << 2
#define SETTINGS_READONLY SETTINGS_AUTORUNINF << 3
#define SETTINGS_NOFILEEXECUTE SETTINGS_AUTORUNINF << 4

#define DENY_CREATE                        1
#define DENY_WRITE                        1 << 1
#define DENY_INFORMATHION        1 << 2



PFLT_FILTER Filter;



#define pasthrough_INSTANCE_CONTEXT_TAG 'cIxC'

typedef struct _pasthrough_INSTANCE_CONTEXT {
       BOOLEAN ucFlags;
} pasthrough_INSTANCE_CONTEXT, *Ppasthrough_INSTANCE_CONTEXT;

#define pasthrough_INSTANCE_CONTEXT_SIZE sizeof(pasthrough_INSTANCE_CONTEXT)

NTSTATUS DriverEntry(__in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath);
NTSTATUS pasthroughUnload(__in FLT_FILTER_UNLOAD_FLAGS Flags);
NTSTATUS pasthroughQueryTeardown(__in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags);
FLT_PREOP_CALLBACK_STATUS pasthroughPreCreate(__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID *CompletionContext);
FLT_PREOP_CALLBACK_STATUS pasthroughPreWrite(__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID *CompletionContext);
FLT_PREOP_CALLBACK_STATUS pasthroughPreSetInformation(__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID *CompletionContext);
NTSTATUS pasthroughInstanceSetup(__in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_SETUP_FLAGS Flags, __in DEVICE_TYPE VolumeDeviceType, __in FLT_FILESYSTEM_TYPE VolumeFilesystemType);
VOID ReadRegistrySettings(__in PUNICODE_STRING RegistryPath);
VOID pasthroughContextCleanup(__in PFLT_CONTEXT Context, __in FLT_CONTEXT_TYPE ContextType);
VOID pasthroughInstanceTeardownComplete(__in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_TEARDOWN_FLAGS Flags);



//  Assign text sections for each routine.

#ifdef ALLOC_PRAGMA
       #pragma alloc_text(INIT, DriverEntry)
       #pragma alloc_text(PAGE, pasthroughUnload)
       #pragma alloc_text(PAGE, pasthroughInstanceSetup)
       #pragma alloc_text(PAGE, pasthroughPreCreate)
       #pragma alloc_text(PAGE, pasthroughPreWrite)
       #pragma alloc_text(PAGE, pasthroughPreSetInformation)
       #pragma alloc_text(PAGE, pasthroughContextCleanup)
       #pragma alloc_text(PAGE, pasthroughInstanceTeardownComplete)
#endif

NTSTATUS DriverEntry(__in PDRIVER_OBJECT pDO, __in PUNICODE_STRING pusRegistryPath)
{
       NTSTATUS iNTStatus;

       const FLT_OPERATION_REGISTRATION Callbacks[] = {
               {IRP_MJ_CREATE, 0, pasthroughPreCreate, NULL},
               {IRP_MJ_SET_INFORMATION, 0, pasthroughPreSetInformation, NULL},
               {IRP_MJ_WRITE, 0, pasthroughPreWrite, NULL},
               {IRP_MJ_OPERATION_END}
       };

       const FLT_CONTEXT_REGISTRATION contextRegistration[] = {
               {FLT_INSTANCE_CONTEXT, 0, pasthroughContextCleanup, pasthrough_INSTANCE_CONTEXT_SIZE, pasthrough_INSTANCE_CONTEXT_TAG},
               {FLT_CONTEXT_END}
       };

       const FLT_REGISTRATION FilterRegistration = {
               sizeof(FLT_REGISTRATION),         //  Size
               FLT_REGISTRATION_VERSION,           //  Version
               0,                                  //  Flags
               contextRegistration,                //  Context Registration.
               Callbacks,                          //  Operation callbacks
               pasthroughUnload,                      //  FilterUnload
               pasthroughInstanceSetup,               //  InstanceSetup
               NULL,                             //  InstanceQueryTeardown
               NULL,                             //  InstanceTeardownStart
               pasthroughInstanceTeardownComplete,      //  InstanceTeardownComplete
               NULL,                               //  GenerateFileName
               NULL,                               //  GenerateDestinationFileName
               NULL                                //  NormalizeNameComponent
       };



       iNTStatus = FltRegisterFilter(pDO, &FilterRegistration, &Filter);

       if (!NT_SUCCESS(iNTStatus))
               return iNTStatus;

       iNTStatus = FltStartFiltering(Filter);

       if (NT_SUCCESS(iNTStatus))
               return STATUS_SUCCESS;

       FltUnregisterFilter(Filter);

       return iNTStatus;
}

NTSTATUS pasthroughUnload(__in FLT_FILTER_UNLOAD_FLAGS iFFUF)
{
       UNREFERENCED_PARAMETER(iFFUF);
        
        PAGED_CODE();


       FltUnregisterFilter(Filter);

       return STATUS_SUCCESS;
}

int VolumeToDosName(__in PFLT_VOLUME pFV)
{
       PDEVICE_OBJECT pDO = NULL;
       UNICODE_STRING usDosName;
       NTSTATUS iNTStatus;
       int iReturn = 0;

       iNTStatus = FltGetDiskDeviceObject(pFV, &pDO);
       if (NT_SUCCESS(iNTStatus))
       {
               iNTStatus = IoVolumeDeviceToDosName(pDO, &usDosName);
               if (NT_SUCCESS(iNTStatus))
               {
                       iReturn = RtlUpcaseUnicodeChar(usDosName.Buffer[0]);
                       ExFreePool(usDosName.Buffer);
               }
       }

       return iReturn;
}

NTSTATUS pasthroughInstanceSetup(__in PCFLT_RELATED_OBJECTS pFRO, __in FLT_INSTANCE_SETUP_FLAGS iFISF, __in DEVICE_TYPE iDT, __in FLT_FILESYSTEM_TYPE iFFT)
{
       UCHAR ucBuffer[sizeof(FLT_VOLUME_PROPERTIES)+512];
       PFLT_VOLUME_PROPERTIES pFVP = (PFLT_VOLUME_PROPERTIES)ucBuffer;
       ULONG ulLengthReceived;
       NTSTATUS iNTStatus;
       NTSTATUS iNTStatusReturn;
       Ppasthrough_INSTANCE_CONTEXT pAIC = NULL;
       int iDrive;

       UNREFERENCED_PARAMETER(iFISF);
       UNREFERENCED_PARAMETER(iFFT);

       ulLengthReceived = 0;

       //ReadRegistrySettings(NULL);

       PAGED_CODE();

       iDrive = VolumeToDosName(pFRO->Volume);

       iNTStatus = FltAllocateContext(pFRO->Filter, FLT_INSTANCE_CONTEXT, pasthrough_INSTANCE_CONTEXT_SIZE, NonPagedPool, &pAIC);

       if (!NT_SUCCESS(iNTStatus))
       {
               if (pAIC != NULL)
                       FltReleaseContext(pAIC);
               return STATUS_FLT_DO_NOT_ATTACH;
       }

       
       DbgPrint("pasthrough: pasthroughInstanceSetup iDT: %d", iDT);
                       
       switch(iDT)
         {
                case FILE_DEVICE_DISK_FILE_SYSTEM: 
                       
                       if (NT_SUCCESS(FltGetVolumeProperties(pFRO->Volume, pFVP, sizeof(ucBuffer), &ulLengthReceived)))
                       {
                               DbgPrint("pasthrough: pasthroughInstanceSetup FILE_DEVICE_DISK_FILE_SYSTEM: RealDeviceName: %wZ DeviceCharacteristics: %08x", &pFVP->RealDeviceName, pFVP->DeviceCharacteristics);
                               if (pFVP->DeviceCharacteristics & FILE_REMOVABLE_MEDIA)
                               {
                                       pAIC->ucFlags = TRUE;
                                       iNTStatusReturn = STATUS_SUCCESS;
                                       
                               }
                       }
                       break;

                  default:
                          iNTStatusReturn = STATUS_FLT_DO_NOT_ATTACH;
         }
       
                       
       
       DbgPrint("pasthrough: pasthroughInstanceSetup iNTStatusReturn: %d", iNTStatusReturn);

       iNTStatus = FltSetInstanceContext(pFRO->Instance, FLT_SET_CONTEXT_KEEP_IF_EXISTS, pAIC, NULL);

       if (!NT_SUCCESS(iNTStatus))
       {
               if (pAIC != NULL)
                       FltReleaseContext(pAIC);
               return STATUS_FLT_DO_NOT_ATTACH;
       }

       if (pAIC != NULL)
               FltReleaseContext(pAIC);

       if (NT_SUCCESS(iNTStatusReturn))
       {
               if (ulLengthReceived <= 0)
                       FltGetVolumeProperties(pFRO->Volume, pFVP, sizeof(ucBuffer), &ulLengthReceived);
               DbgPrint("pasthrough: Instance setup iDT: %d RealDeviceName: %wZ DeviceCharacteristics: %08x Dosname: %c", iDT, &pFVP->RealDeviceName, pFVP->DeviceCharacteristics, iDrive);
       }

       return iNTStatusReturn;
}


PKEY_VALUE_PARTIAL_INFORMATION QueryRegistryValue(const wchar_t* regPath, const wchar_t* regKey)
{
       HANDLE KeyHandle = NULL;
    NTSTATUS Status = STATUS_SUCCESS;
    UNICODE_STRING KeyPath;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING SourceKeyName;
    PKEY_VALUE_PARTIAL_INFORMATION AcKeyInfo = NULL;
    KEY_VALUE_PARTIAL_INFORMATION KeyInfo;
    ULONG Length = 0;

       RtlInitUnicodeString(&KeyPath, regPath);
       RtlInitUnicodeString(&SourceKeyName, regKey);
       DbgPrint("pasthrough: KeyPath = %wZ, SourceKeyName = %wZ\n", &KeyPath, &SourceKeyName);
    //初始化OBJECT_ATTRIBUTES结构体
    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyPath,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    //打开注册表键
    Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DbgPrint("pasthrough: Open the Key Handle Faild!! -- %#X\n", Status);
        return AcKeyInfo;
    }

    //第一次读取注册表键值探测数据大小
    Status = ZwQueryValueKey(
        KeyHandle,
        &SourceKeyName,
        KeyValuePartialInformation,
        &KeyInfo,
        sizeof(KEY_VALUE_PARTIAL_INFORMATION),
        &Length);   
    if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL)
    {
        DbgPrint("pasthrough: 读取SystemRoot键值失败!! - %#X\n", Status);
        ZwClose(KeyHandle);
        return AcKeyInfo;
    }

    //根据上面探测的注册表键值大小动态分配内存
    AcKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, Length, "tag2");
    if (NULL == AcKeyInfo)
    {
        DbgPrint("pasthrough: 在分配保存Key键值的内存空间时失败!!");
        ZwClose(KeyHandle);
        Status = STATUS_INSUFFICIENT_RESOURCES;
        return AcKeyInfo;
    }

    //再次读取注册表键值
    Status = ZwQueryValueKey(
    KeyHandle,
    &SourceKeyName,
    KeyValuePartialInformation,
    AcKeyInfo,
    Length,
    &Length);
    if (!NT_SUCCESS(Status))
    {
        DbgPrint("pasthrough: 读取SystemRoot键值失败!! - %#X\n", Status);
        ZwClose(KeyHandle);
        ExFreePool(AcKeyInfo);
        return AcKeyInfo;
    }
       ZwClose(KeyHandle);
       return AcKeyInfo;
}


VOID UnicodeToChar(PUNICODE_STRING dst, char *src)
{
       ANSI_STRING string;
       RtlUnicodeStringToAnsiString(&string,dst, TRUE);
       strcpy(src,string.Buffer);
       RtlFreeAnsiString(&string);
}

int QueryUSBRegInfo(PCFLT_RELATED_OBJECTS pFRO)
{
       int option = 0;
       char VolumeName[2] = {0};
       UNICODE_STRING u;
       char RegVolimeValue[100] = {0};
       PKEY_VALUE_PARTIAL_INFORMATION AcOptionInfo = NULL;
       PULONG pulValue = NULL;
       PKEY_VALUE_PARTIAL_INFORMATION AcKeyInfo = QueryRegistryValue(L"\\Registry\\Machine\\Software\\USBInfo", L"Volume");
       if (NULL == AcKeyInfo) {
               DbgPrint("pasthrough QueryUSBRegInfo AcKeyInfo == NULL");
               return option;
       }
       if (AcKeyInfo->Type != REG_SZ) {
               DbgPrint("pasthrough QueryUSBRegInfo AcKeyInfo->Type != REG_SZ");
               ExFreePool(AcKeyInfo);
               return option;
       }
       
       VolumeName[0] = (char)VolumeToDosName(pFRO->Volume);
       DbgPrint("pasthrough QueryUSBRegInfo VolimeName = %s\n", VolumeName);
       RtlInitUnicodeString(&u, AcKeyInfo->Data);
       DbgPrint("pasthrough QueryUSBRegInfo u = %wZ\n", &u);
       ExFreePool(AcKeyInfo);
       UnicodeToChar(&u, RegVolimeValue);
       DbgPrint("pasthrough QueryUSBRegInfo RegVolimeValue = %s\n", RegVolimeValue);
       if (strstr(RegVolimeValue, VolumeName) == NULL) {
               return option;
       }
       AcOptionInfo = QueryRegistryValue(L"\\Registry\\Machine\\Software\\USBInfo", L"Option");
       if (NULL == AcOptionInfo) {
               DbgPrint("pasthrough QueryUSBRegInfo NULL == AcOptionInfo\n");
               return option;
       }
       if (AcOptionInfo->Type != REG_DWORD || AcOptionInfo->DataLength != sizeof(ULONG)) {
               DbgPrint("pasthrough QueryUSBRegInfo AcOptionInfo type or length error\n");
               ExFreePool(AcOptionInfo);
               return option;
       }
       pulValue = (PULONG) AcOptionInfo->Data;
       option = (int)*pulValue;
       DbgPrint("pasthrough QueryUSBRegInfo option  %d\n", option);
       ExFreePool(AcOptionInfo);
       return option;
}

FLT_PREOP_CALLBACK_STATUS pasthroughPreCreate(__inout PFLT_CALLBACK_DATA pFCD, __in PCFLT_RELATED_OBJECTS pFRO, __deref_out_opt PVOID *ppvCompletionContext)
{
       Ppasthrough_INSTANCE_CONTEXT pAIC = NULL;
       int option;
       int CreateDisposition;
       int IsNewCreate = 0;

       UNREFERENCED_PARAMETER(pFRO);
       UNREFERENCED_PARAMETER(ppvCompletionContext);

       PAGED_CODE();

       option = QueryUSBRegInfo(pFRO);
       CreateDisposition = (pFCD->Iopb->Parameters.Create.Options >> 24) & 0x000000ff;
       IsNewCreate = (CreateDisposition == FILE_CREATE || CreateDisposition == FILE_OPEN_IF || CreateDisposition == FILE_OVERWRITE_IF);

       if ((option & DENY_CREATE) != DENY_CREATE)
               return FLT_PREOP_SUCCESS_NO_CALLBACK;
       else if ((option & DENY_WRITE) == DENY_WRITE) {
               pFCD->IoStatus.Status = IsNewCreate ? STATUS_ACCESS_DENIED : STATUS_MEDIA_WRITE_PROTECTED;
                 pFCD->IoStatus.Information = 0;
                 return FLT_PREOP_COMPLETE;
       }
       else
       {
               DbgPrint("pasthrough pre Create: access denied");
                  
               pFCD->IoStatus.Status = STATUS_ACCESS_DENIED;
               pFCD->IoStatus.Information = 0;

               return FLT_PREOP_COMPLETE;
       }
}

FLT_PREOP_CALLBACK_STATUS pasthroughPreWrite(__inout PFLT_CALLBACK_DATA pFCD, __in PCFLT_RELATED_OBJECTS pFRO, __deref_out_opt PVOID *ppvCompletionContext)
{
       Ppasthrough_INSTANCE_CONTEXT pAIC = NULL;
       int option;

       UNREFERENCED_PARAMETER(pFRO);
       UNREFERENCED_PARAMETER(ppvCompletionContext);

       PAGED_CODE();

       option = QueryUSBRegInfo(pFRO);

       if ((option & DENY_WRITE) != DENY_WRITE)
               return FLT_PREOP_SUCCESS_NO_CALLBACK;
       else
       {
               DbgPrint("pasthrough pre Write: access denied");
                  
               pFCD->IoStatus.Status = STATUS_ACCESS_DENIED;
               pFCD->IoStatus.Information = 0;

               return FLT_PREOP_COMPLETE;
       }
}

FLT_PREOP_CALLBACK_STATUS pasthroughPreSetInformation(__inout PFLT_CALLBACK_DATA pFCD, __in PCFLT_RELATED_OBJECTS pFRO, __deref_out_opt PVOID *ppvCompletionContext)
{
       int option;

       UNREFERENCED_PARAMETER(ppvCompletionContext);

       PAGED_CODE();
    
       option = QueryUSBRegInfo(pFRO);

       if ((option & DENY_INFORMATHION) != DENY_INFORMATHION)
               return FLT_PREOP_SUCCESS_NO_CALLBACK;
       else
       {
               DbgPrint("pasthrough pre SetInformation: access denied");
                  
               pFCD->IoStatus.Status = STATUS_ACCESS_DENIED;
               pFCD->IoStatus.Information = 0;

               return FLT_PREOP_COMPLETE;
       }
}


VOID pasthroughContextCleanup(__in PFLT_CONTEXT pFC, __in FLT_CONTEXT_TYPE pFCT)
{
       Ppasthrough_INSTANCE_CONTEXT pAIC;

       PAGED_CODE();

       if (FLT_INSTANCE_CONTEXT == pFCT)
       {
               pAIC = (Ppasthrough_INSTANCE_CONTEXT) pFC;
               // no memory to release
       }
}

VOID pasthroughInstanceTeardownComplete(__in PCFLT_RELATED_OBJECTS pFRO, __in FLT_INSTANCE_TEARDOWN_FLAGS iFITF)
{
       Ppasthrough_INSTANCE_CONTEXT pAIC;
       NTSTATUS iNTStatus;

       UNREFERENCED_PARAMETER(iFITF);

       PAGED_CODE();

       iNTStatus = FltGetInstanceContext(pFRO->Instance, (PFLT_CONTEXT *)&pAIC);
       if (NT_SUCCESS(iNTStatus))
               FltReleaseContext(pAIC);
}
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-8 00:06
3
0
好了, 只读也搞定了, 通过看日志, 发现在precreate里面CreateDisposition不等于FILE_OPEN就是写入, 于是在这里拦截, 效果很好。
IsWrite = (CreateDisposition != FILE_OPEN)

if ((option & DENY_WRITE) == DENY_WRITE && IsWrite) {
               DbgPrint("pasthrough pre Create: access denied IsWrite = %d, IsExcute = %d\n", IsWrite, IsExcute);
               pFCD->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED;
                 pFCD->IoStatus.Information = 0;
                 return FLT_PREOP_COMPLETE;
       }

我还想禁止执行exe, 但没找到好的办法, 如果有人想到了希望不吝指教, 谢谢!!
雪    币: 407
活跃值: (1622)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Thead 2019-4-8 08:46
4
0
IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-8 11:08
5
0
Thead IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION
感谢大佬, 试了下在这里做可以禁止执行exe!!!
option = QueryUSBRegInfo(pFRO);
       IsExcute = (pFCD->Iopb->Parameters.AcquireForSectionSynchronization.PageProtection == PAGE_EXECUTE);


       if ((option & DENY_EXCUTE) != DENY_EXCUTE || !IsExcute)
               return FLT_PREOP_SUCCESS_NO_CALLBACK;
       else
       {
               DbgPrint("pasthrough pre CreateProcess: access denied");
                  
               pFCD->IoStatus.Status = STATUS_ACCESS_DENIED;
               pFCD->IoStatus.Information = 0;

               return FLT_PREOP_COMPLETE;
       }
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-8 11:10
6
0
Thead IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION
实际测试中发现, 移动硬盘识别出来是硬盘, 还有些手机比如我的小米手机识别的是便携设备,有些识别的是你U盘, 我想对这些设备都做处理,  设备怎么在驱动里面区分呢?
雪    币: 407
活跃值: (1622)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Thead 2019-4-8 13:56
7
0
wumnkx 实际测试中发现, 移动硬盘识别出来是硬盘, 还有些手机比如我的小米手机识别的是便携设备,有些识别的是你U盘, 我想对这些设备都做处理, 设备怎么在驱动里面区分呢?
IOCTL_STORAGE_QUERY_PROPERTY
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-8 16:47
8
0
Thead IOCTL_STORAGE_QUERY_PROPERTY
谢谢大佬!
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-8 23:41
9
0
wumnkx 实际测试中发现, 移动硬盘识别出来是硬盘, 还有些手机比如我的小米手机识别的是便携设备,有些识别的是你U盘, 我想对这些设备都做处理, 设备怎么在驱动里面区分呢?
自己试验了一下, 便携设备在资源管理器里面显示的不是盘符,而是一个设备名称, 在设备管理器里面有个专门的便携设备项, 设备插上电脑时不会触发minifilter的InstanceSetup; 后来查了一下资料, 发现这个设备用的是叫WPD的驱动, 这玩意有人熟悉吗?
雪    币: 60
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
KanXuerr 2019-4-9 09:42
10
0
我也在做类似的功能,请教楼主大大是怎么判断盘符是否是U盘呢?还有QueryRegistryValue(L"\\Registry\\Machine\\Software\\USBInfo", L"Volume");这个注册表路径我用Win7和Win10看了下,好像都不存在呢?
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-9 09:53
11
0
KanXuerr 我也在做类似的功能,请教楼主大大是怎么判断盘符是否是U盘呢?还有QueryRegistryValue(L"\\Registry\\Machine\\Software\\USBInfo&quo ...
这个注册表是我自己写的, 我这样写是为了方便测试, 因为公司电脑USB口封掉了。
判断是U盘可以在instancesetup里面通过卷取到设备对象, 然后取设备的这个属性IOCTL_STORAGE_QUERY_PROPERTY。
现在卡在便携设备这里了, 昨天发现这东西没有加载到文件系统, 使用的用WPD驱动, 有熟悉的人愿意讲讲吗?
NTSTATUS InstanceSetup(__in PCFLT_RELATED_OBJECTS pFRO, __in FLT_INSTANCE_SETUP_FLAGS iFISF, __in DEVICE_TYPE iDT, __in FLT_FILESYSTEM_TYPE iFFT)
{
       PDEVICE_OBJECT DeviceObject;
       NTSTATUS status;
       BYTE busType;

       UNREFERENCED_PARAMETER(iFISF);
       UNREFERENCED_PARAMETER(iFFT);

       //ReadRegistrySettings(NULL);

       PAGED_CODE();

       status = FltGetDiskDeviceObject(pFRO->Volume, &DeviceObject);
       if (!NT_SUCCESS(status))
       {
               return STATUS_UNSUCCESSFUL;
       }

       GetDeviceBusType(DeviceObject, &busType);
       if (busType == 7) {
               // 是U盘或者移动硬盘
       }



NTSTATUS
GetDeviceBusType(
__in PDEVICE_OBJECT Device,
__in __out BYTE* pBusType
)
{
       PIRP Irp;
       KEVENT Event;
       NTSTATUS status;
       IO_STATUS_BLOCK Iosb;
       STORAGE_PROPERTY_QUERY PropQuery;
       PSTORAGE_DEVICE_DESCRIPTOR pDesc;
       PVOID QueryBuffer = NULL;
       ULONG QuerySize = 0x2000;
       char * pDeviceInfo;

       __try
       {
               QueryBuffer = ExAllocatePoolWithTag(NonPagedPool, QuerySize, UIM_USB_POOL_TAG);
               if (!QueryBuffer)
               {
                       status = STATUS_INSUFFICIENT_RESOURCES;
                       __leave;
               }

               memset(&PropQuery, 0, sizeof(PropQuery));
               memset(QueryBuffer, 0, QuerySize);
               PropQuery.PropertyId = StorageDeviceProperty;
               PropQuery.QueryType = PropertyStandardQuery;

               KeInitializeEvent(&Event, NotificationEvent, FALSE);
               //
               //A driver that calls IoBuildDeviceIoControlRequest must not call IoFreeIrp, 
               //because the I/O manager frees these synchronous IRPs after IoCompleteRequest has been called.
               //
               Irp = IoBuildDeviceIoControlRequest(
                       IOCTL_STORAGE_QUERY_PROPERTY,
                       Device,
                       &PropQuery,
                       sizeof(PropQuery),
                       QueryBuffer,
                       QuerySize,
                       FALSE,
                       &Event,
                       &Iosb
                       );

               if (!Irp)
               {
                       status = STATUS_UNSUCCESSFUL;
                       __leave;
               }

               status = IoCallDriver(Device, Irp);

               if (STATUS_PENDING == status)
               {
                       KeWaitForSingleObject(
                               &Event,
                               Executive,
                               KernelMode,
                               FALSE,
                               (PLARGE_INTEGER)NULL
                               );

                       status = Iosb.Status;
               }

               if (!NT_SUCCESS(status))
               {
                       __leave;
               }

               if (!Iosb.Information)
               {
                       status = STATUS_UNSUCCESSFUL;
                       __leave;
               }

               pDesc = (PSTORAGE_DEVICE_DESCRIPTOR)QueryBuffer;

               if (pBusType)
                       *pBusType = (BYTE)pDesc->BusType;
               // 将pid, vid, seq打印出来
               pDeviceInfo = (char*)pDesc;
               DbgPrint("GetDeviceBusType pid: %s, vid: %s, version: %s, seq: %s\n", &pDeviceInfo[pDesc->ProductIdOffset], &pDeviceInfo[pDesc->VendorIdOffset], &pDeviceInfo[pDesc->ProductRevisionOffset], &pDeviceInfo[pDesc->SerialNumberOffset]);
       }
       __finally
       {
               if (QueryBuffer)
                       if (QueryBuffer != NULL)
                       {
                               ExFreePoolWithTag(QueryBuffer, UIM_USB_POOL_TAG);
                               QueryBuffer = NULL;
                       }
       }

       return status;
}
雪    币: 1736
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sylingyy 2019-4-9 10:28
12
0
你需要的是usbstore  filter,而不是minifilter。
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-9 10:46
13
0
sylingyy 你需要的是usbstore filter,而不是minifilter。
便携设备使用的是WPD驱动, 就好比USB鼠标键盘, 不走文件系统, 限制usbstore对他无效, usbstore还是属于文件系统的 
雪    币: 1736
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sylingyy 2019-4-9 15:30
14
0
wumnkx 便携设备使用的是WPD驱动, 就好比USB鼠标键盘, 不走文件系统, 限制usbstore对他无效, usbstore还是属于文件系统的
他说是U盘,这样讲那自己写的文件系统,怎么过滤也是一样无效。
雪    币: 1736
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sylingyy 2019-4-9 15:32
15
0
wumnkx 便携设备使用的是WPD驱动, 就好比USB鼠标键盘, 不走文件系统, 限制usbstore对他无效, usbstore还是属于文件系统的
或许你需要USB CLASS filter,但是下层设备的判断需要自己做。
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-10 10:01
16
0
WPD过滤驱动有方向了, 参照这个上面来做http://www.osronline.com/article.cfm%5earticle=446.htm
雪    币: 56
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_幼儿园的王 2019-4-18 09:16
17
0
楼主。你的UIM_USB_POOL_TAG参数是什么啊
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-18 09:34
18
0
wx_幼儿园的王 楼主。你的UIM_USB_POOL_TAG参数是什么啊
#define UIM_USB_POOL_TAG 'umiD'
雪    币: 75
活跃值: (558)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pccq 2019-4-18 10:12
19
0
wumnkx WPD过滤驱动有方向了, 参照这个上面来做http://www.osronline.com/article.cfm%5earticle=446.htm
之前研究wpd过滤的时候,研究过这个帖子,没有成功,最后用的umdf filter
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-18 14:17
20
0
pccq 之前研究wpd过滤的时候,研究过这个帖子,没有成功,最后用的umdf filter
我用这个帖子做的kmdf upperfilers只能处理DeviceControlCode, 不能细化到操控wpd的内部存储器的文件读写。你用umdf filter可以做到吗?
雪    币: 1773
活跃值: (1718)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
曹操abc 2019-4-18 18:11
21
0
有用
雪    币: 75
活跃值: (558)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pccq 2019-4-18 19:09
22
0
wumnkx 我用这个帖子做的kmdf upperfilers只能处理DeviceControlCode, 不能细化到操控wpd的内部存储器的文件读写。你用umdf filter可以做到吗?
umdf filter可以获取到打开、读写、删除、关闭操作,还有文件名(可以转换成文件路径)和ProcessID
雪    币: 56
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_幼儿园的王 2019-4-18 19:45
23
0
楼主,我写的是sfilter框架的过滤驱动,现在也遇到了禁用便携设备的问题,有什么经验可以跟我交流下吗,我现在还找不到方法
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-18 20:50
24
0
pccq umdf filter可以获取到打开、读写、删除、关闭操作,还有文件名(可以转换成文件路径)和ProcessID
umdf是用的COM形式的接口做的吗? 大哥能否指点一下, 比如参照哪个例子
雪    币: 103
活跃值: (1488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wumnkx 2019-4-18 20:52
25
0
wx_幼儿园的王 楼主,我写的是sfilter框架的过滤驱动,现在也遇到了禁用便携设备的问题,有什么经验可以跟我交流下吗,我现在还找不到方法
本来是打算在驱动层搞, 网上资料太少, 现在打算用组策略搞读写的权限限制, 然后文件审计的还没找到方法。。。
游客
登录 | 注册 方可回帖
返回