首页
社区
课程
招聘
未解决 [求助]minifilter如何获取U盘的VendorID、ProductID?USB过滤驱动如何实现U盘只读,如何在驱动中准确判断是在写文件? 100雪币
发表于: 2025-7-26 11:22 602

未解决 [求助]minifilter如何获取U盘的VendorID、ProductID?USB过滤驱动如何实现U盘只读,如何在驱动中准确判断是在写文件? 100雪币

2025-7-26 11:22
602

本人想做U盘的禁用、只读管控且支持白名单,看论坛里有一种思路是通过minifilter来做,不过需要做U盘白名单(VendorID、ProductID),目前卡在了如何在minifilter获取U盘的VendorID、ProductID,因为目前的尝试,拿到的都是磁盘驱动的设备对象,找不到对应的USB物理设备对象。

另外,也尝试了用USB过滤驱动来做,在处理INTERNAL_DEVICE_CONTORL时通过URB的信息(UrbHeader.Funciton与TransferFlags结合)判断,发现插入U盘后频繁打开文件夹,也会被识别为写,实在没招了,求助大佬。



传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 1755
活跃值: (1526)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
既然有磁盘驱动的设备对象,这样就应该可以,得到的是USB\\VID_1234&PID_1234这样的REG_MULTI_SZ字符串,解析一下就行  
这个没有测试,调用完记得ExFreePool  
```
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSTATUS GetHardwareIdByDiskDevice(
       _In_  PDEVICE_OBJECT DiskDeviceObject,
       _Out_ PVOID*         HardwareId,
       _Out_ ULONG_PTR*     HardwareIdSize
)
{
       NTSTATUS status = STATUS_SUCCESS;

       PDEVICE_OBJECT pPhyDevObj = IoGetDeviceAttachmentBaseRef(DiskDeviceObject);
       if (!pPhyDevObj) {
               return STATUS_NOT_FOUND;
       }

       ULONG ulIdSize = 0;
       status = IoGetDeviceProperty(
               pPhyDevObj,
               DevicePropertyHardwareID,
               0,
               NULL,
               &ulIdSize
       );
       if (status != STATUS_BUFFER_TOO_SMALL) {
               ObDereferenceObject(pPhyDevObj);
               return status;
       }

       PVOID pHardwareId = ExAllocatePool2(POOL_FLAG_NON_PAGED, ulIdSize, "TNCS");
       if (!pHardwareId) {
               ObDereferenceObject(pPhyDevObj);
               return STATUS_INSUFFICIENT_RESOURCES;
       }

       status = IoGetDeviceProperty(
               pPhyDevObj,
               DevicePropertyHardwareID,
               ulIdSize,
               pHardwareId,
               &ulIdSize
       );
       if (!NT_SUCCESS(status)) {
               ExFreePool(pHardwareId);
               ObDereferenceObject(pPhyDevObj);
               return status;
       }

       *HardwareId = pHardwareId;
       *HardwareIdSize = (ULONG_PTR)ulIdSize;
       ObDereferenceObject(pPhyDevObj);
       return status;
}
```
2025-7-31 10:55
0
雪    币: 120
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
TurkeybraNC 既然有磁盘驱动的设备对象,这样就应该可以,得到的是USB\\VID_1234&PID_1234这样的REG_MULTI_SZ字符串,解析一下就行 这个没有测试,调用完记得ExFreePo ...
好的,感谢已经找到可行方式了,目前做了审计日志,发现打开一个文件识别到的动作不准确的问题,比如windows会默认读取"$U盘盘符:\desktop.ini",这个文件明明不存在,还是会被拦住导致我的日志不准确,大佬有思路吗?
2025-8-12 09:38
0
雪    币: 519
活跃值: (580)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
读是Read,Open成功就是存在的。。。open,read,write,close.
2025-8-12 10:56
0
雪    币: 1755
活跃值: (1526)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5

这个应该可以,只是记日志时要小心死锁,三环与零环的通信要采用异步,还有要放行System,csrss.exe之类的系统进程操作

BOOLEAN IsFileExist(
	_In_ PFLT_INSTANCE Instance, 
	_In_ PUNICODE_STRING FilePath
)
{
	OBJECT_ATTRIBUTES oa;
	InitializeObjectAttributes(&oa, FilePath, OBJ_KERNEL_HANDLE, NULL, NULL);

	HANDLE hFile;
	IO_STATUS_BLOCK ioStatus;

	NTSTATUS status = FltCreateFile(
		g_FilterHandle,
		Instance,
		&hFile,
		FILE_READ_ATTRIBUTES,
		&oa,
		&ioStatus,
		0,
		FILE_ATTRIBUTE_NORMAL,
		FILE_SHARE_READ,
		FILE_OPEN,
		FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0,
		IO_IGNORE_SHARE_ACCESS_CHECK
	);

	if (NT_SUCCESS(status)) {
		ZwClose(hFile);
		return TRUE;
	}
	return FALSE;
}

FLT_PREOP_CALLBACK_STATUS PreOperation(
	_Inout_ PFLT_CALLBACK_DATA Data,
	_In_ PCFLT_RELATED_OBJECTS FltObjects,
	_Flt_CompletionContext_Outptr_ PVOID* CompletionContext)
{


	PFLT_FILE_NAME_INFORMATION nameInfo;
	NTSTATUS status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED, &nameInfo);
	if (!NT_SUCCESS(status)) {
		return FLT_PREOP_SUCCESS_NO_CALLBACK;
	}


	BOOLEAN exists = IsFileExist(FltObjects->Instance, &nameInfo->Name);

	if (exists) {
		//记录日志
	}

	FltReleaseFileNameInformation(nameInfo);

	//完成管控操作
}


2025-8-13 20:58
0
游客
登录 | 注册 方可回帖
返回