使用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
相关推荐
软件黑马王子4 小时前
Unity游戏制作中的C#基础(5)条件语句和循环语句知识点全解析
游戏·unity·c#
shepherd枸杞泡茶4 小时前
第3章 3.3日志 .NET Core日志 NLog使用教程
c#·asp.net·.net·.netcore
庸俗今天不摸鱼7 小时前
Canvas进阶-4、边界检测(流光,鼠标拖尾)
开发语言·前端·javascript·计算机外设
rkmhr_sef8 小时前
Redis 下载与安装 教程 windows版
数据库·windows·redis
@_@哆啦A梦8 小时前
windows怎样查看系统信息(处理器等)
windows
Aimeast10 小时前
关于选择最佳.NET Core SSH服务器库的全面分析
c#·ssh
落落落sss10 小时前
MongoDB
数据库·windows·redis·mongodb·微服务·wpf
bin915311 小时前
DeepSeek 助力 Vue 开发:打造丝滑的 键盘快捷键(Keyboard Shortcuts)
前端·javascript·vue.js·计算机外设·ecmascript·deepseek
蒋劲豪11 小时前
WPF项目暴露WebApi接口;WinForm项目暴露WebApi接口;C#项目暴露WebApi接口;
开发语言·c#·wpf
黄铎彦11 小时前
使用GDI+、文件和目录和打印API,批量将图片按文件名分组打包成PDF
c++·windows·pdf