使用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 小时前
ubuntu+windows双系统切换后蓝牙设备无法连接
windows·ubuntu
向宇it7 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
九鼎科技-Leo8 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
Heaphaestus,RC9 小时前
【Unity3D】获取 GameObject 的完整层级结构
unity·c#
baivfhpwxf20239 小时前
C# 5000 转16进制 字节(激光器串口通讯生成指定格式命令)
开发语言·c#
直裾9 小时前
Scala全文单词统计
开发语言·c#·scala
Yang.9910 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
我不瘦但很逗10 小时前
Windows下使用DBeaver连接云数据库(MySQL)
数据库·windows
ZwaterZ10 小时前
vue el-table表格点击某行触发事件&&操作栏点击和row-click冲突问题
前端·vue.js·elementui·c#·vue
ashane131411 小时前
Java list
java·windows·list