使用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
相关推荐
Clockwiseee3 小时前
php伪协议
windows·安全·web安全·网络安全
ThreeYear_s4 小时前
基于FPGA 的4位密码锁 矩阵键盘 数码管显示 报警仿真
fpga开发·矩阵·计算机外设
向宇it4 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
唐宋元明清21884 小时前
.NET 阻止系统睡眠/息屏
windows·电源
向宇it5 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
yylの博客6 小时前
Windows通过git-bash安装zsh
windows·git·bash·zsh
进击的code7 小时前
windows 下使用WLS2 编译aosp Android14并刷机到pixle 5a
windows
不知火猪7 小时前
最新雷蛇鼠标键盘驱动Razer Synapse 4(雷云) 下载与安装
计算机外设·驱动·雷云·雷蛇驱动
坐井观老天10 小时前
在C#中使用资源保存图像和文本和其他数据并在运行时加载
开发语言·c#
染指111010 小时前
50.第二阶段x86游戏实战2-lua获取本地寻路,跨地图寻路和获取当前地图id
c++·windows·lua·游戏安全·反游戏外挂·游戏逆向·luastudio