使用C#禁止Windows系统插入U盘(除鼠标键盘以外的USB设备)

试用网上成品的禁用U盘的相关软件,发现使用固态硬盘改装的U盘以及手机等设备,无法被禁止,无奈下,自己使用C#手搓了一个。

基本逻辑:

  • 开机自启;
  • 启动时,修改注册表,禁止系统插入USB存储设备
  • 监听系统的USB插入事件
    • 判断系统插入USB设备的类型;
    • 如果系统注册表被篡改,并插入非法设备,则立刻重启系统;

Demo1.0主要代码如下:

csharp 复制代码
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management;
using System.Security.AccessControl;
using System.Security.Principal;
using System.ServiceProcess;

namespace ListeningUSB
{
    partial class Service1 : ServiceBase
    {
        private string logFilePath;
        private ManagementEventWatcher watcher;
        public Service1()
        {
            InitializeComponent();
            logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "secrecy.log");
        }

        protected override void OnStart(string[] args)
        {
            // 重构注册表
            // 3:表示手动启动,通常用于设备驱动,即启用 USB 功能;
            // 4:表示禁用启动,此设置会禁用 USB 存储设备,插入 U 盘等设备时将无法使用;
            // 0:表示自动启动。
            string[] services = { "USBSTOR", "cdrom", "UASPStor", "WUDFWpdMtp", "WINUSB", "usbprint", "usbscan", "aicusbwifi", "RtlWlanu", "BTHUSB" };
            foreach (string item in services)
            {
                string keyPath = $"SYSTEM\\CurrentControlSet\\Services\\{item}";
                int startValue = GetRegistryValue(keyPath);
                if (startValue != 4)
                {
                    SetUSBStorPermissions(keyPath, 4);
                }
            }
            StartListeningForUSBInsertion();
        }

        protected override void OnStop()
        {
            if (watcher != null)
            {
                watcher.Stop();
                watcher.Dispose();
            }
        }

        private void StartListeningForUSBInsertion()
        {
            // 检查日志文件是否存在
            CheckAndCreateFile(logFilePath);
            string query = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBControllerDevice'";
            watcher = new ManagementEventWatcher(new WqlEventQuery(query));
            watcher.EventArrived += new EventArrivedEventHandler(USBInserted);
            watcher.Start();
            WriteLog("-------------开始异常设备检测---------------");
        }

        private void USBInserted(object sender, EventArrivedEventArgs e)
        {
            if (JudgeUSBStatus(out string deviceInfo))
            {
                WriteLog($"检测到异常 USB 设备插入,设备信息: {deviceInfo}");
                using (Process process = new Process())
                {
                    process.StartInfo = startInfo;
                    process.Start();
                }
            }
        }


        // 检查日志文件是否存在
        static void CheckAndCreateFile(string filePath)
        {
            if (!File.Exists(filePath))
            {
                using (File.Create(filePath)) { }
            }
        }

        // 关机
        ProcessStartInfo startInfo = new ProcessStartInfo
        {
            FileName = "shutdown.exe",
            Arguments = "/s /f /t 0",
            UseShellExecute = false
        };

        private bool JudgeUSBStatus(out string deviceInfo)
        {
            deviceInfo = string.Empty;
            var serviceList = new[] { "disk", "wudfwpdmtp", "usbstor", "cdrom", "uaspstor", "usbprint", "rtlwlanu", "aicusbwifi", "usbscan" };
            bool status = false;

            try
            {
                using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE 'USB%'"))
                {
                    var usbDevices = searcher.Get();
                    foreach (ManagementObject usbDevice in usbDevices)
                    {
                        var service = usbDevice["Service"]?.ToString().ToLower();
                        if (service != null && serviceList.Contains(service))
                        {
                            status = true;
                            deviceInfo =  usbDevice.ToString();
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WriteLog($"Error: {ex.Message}");
            }

            return status;
        }

        private void WriteLog(string message)
        {
            using (StreamWriter writer = new StreamWriter(logFilePath, true))
            {
                writer.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}: {message}");
            }
        }


        static int GetRegistryValue(string keyPath)
        {
            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyPath))
                {
                    if (key != null)
                    {
                        object value = key.GetValue("Start");
                        if (value is int)
                        {
                            return (int)value;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error getting registry value: {e.Message}");
            }
            return -1;
        }

        static void SetUSBStorPermissions(string keyPath, int value)
        {
            try
            {
                using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyPath, RegistryKeyPermissionCheck.ReadWriteSubTree))
                {
                    if (key != null)
                    {
                        // 获取当前注册表项的 ACL 信息
                        RegistrySecurity securityDescriptor = key.GetAccessControl();
                        RegistryAccessRule everyoneRule = new RegistryAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                                                                                RegistryRights.FullControl,
                                                                                AccessControlType.Allow);

                        securityDescriptor.AddAccessRule(everyoneRule);
                        key.SetAccessControl(securityDescriptor);

                        // 修改 USBSTOR 注册表项的 Start 值为 4
                        key.SetValue("Start", value, RegistryValueKind.DWord);

                        // 将 USBSTOR 注册表项权限设置为所有人仅可读
                        securityDescriptor = key.GetAccessControl();
                        securityDescriptor.RemoveAccessRuleSpecific(everyoneRule);
                        key.SetAccessControl(securityDescriptor);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"Error setting registry permissions: {e.Message}");
            }
        }
    }
}

打包后,软件约12KB,使用下面的CMD命令,将exe加入系统的开机自启即可;

bash 复制代码
# 加入开机自启服务
sc create secrecy  binPath= "C:\Windows\System32\secrecy.exe" displayname="secrecy" description="This is a service that monitors whether the system has inserted an abnormal USB device."
# 删除该服务
sc delete secrecy
相关推荐
m0_6569747443 分钟前
C#中的集合类及其使用
开发语言·c#
九鼎科技-Leo1 小时前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
Mac新人3 小时前
又发现了Mac妙控鼠标的新使用方法
计算机外设
九鼎科技-Leo3 小时前
什么是 ASP.NET Core?与 ASP.NET MVC 有什么区别?
windows·后端·c#·asp.net·mvc·.net
.net开发3 小时前
WPF怎么通过RestSharp向后端发请求
前端·c#·.net·wpf
小乖兽技术3 小时前
C#与C++交互开发系列(二十):跨进程通信之共享内存(Shared Memory)
c++·c#·交互·ipc
幼儿园园霸柒柒4 小时前
第七章: 7.3求一个3*3的整型矩阵对角线元素之和
c语言·c++·算法·矩阵·c#·1024程序员节
平凡シンプル6 小时前
C# EF 使用
c#
丁德双7 小时前
winform 加载 office excel 插入QRCode图片如何设定位置
c#·excel
黎明晓月7 小时前
Java之字符串分割转换List
java·windows·list