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

news2024/11/23 20:06:18

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

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

Demo1.0主要代码如下:

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加入系统的开机自启即可;
在这里插入图片描述

# 加入开机自启服务
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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2036463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

字符串函数!!!(续)(C语言)

一. strtok函数的使用 继续上次的学习,今天我们来认识一个新的函数strtok,它的原型是char* strtok(char* str,const char* sep),sep参数指向了一个字符串,定义了用作分隔符的字符合集,第一个参数指定⼀个字符串&#…

DataStream API的Joining操作

目录 Window Join Tumbling Window Join Sliding Window Join Session Window Join Interval Join Window CoGroup Window Join 窗口连接(window join)将两个流的元素连接在一起,这两个流共享一个公共键,并且位于同一窗口。…

从老旧到智慧病房,全视通智慧病房方案减轻医护工作负担

传统的老旧病房面临着诸多挑战。例如,患者风险信息的管理仍依赖于手写记录和人工核查;病房呼叫系统仅支持基本的点对点呼叫,缺乏与其它系统的集成能力;信息传递主要依靠医护人员口头传达;护理信息管理分散且不连贯&…

JavaEE-多线程

前情提要:本文内容过多,建议搭配目录食用,想看哪里点哪里~ PC端目录 手机端目录 话不多说,我们正式开始~~ 目录 多线程的概念进程和线程的区别和联系:使用Java代码进行多线程编程Thread类中的方法和属性线程的核心操作1. 启动…

【mamba学习】(一)SSM原理与说明

mamba输入输出实现与transformer几乎完全一样的功能,但速度和内存占用具有很大优势。对比transformer,transformer存在记忆有限的情况,如果输入或者预测的序列过长可能导致爆炸(非线性),而mamba不存在这种情…

物理网卡MAC修改器v3.0-直接修改网卡内部硬件MAC地址,重装系统不变!

直接在操作系统里就能修改网卡硬件mac地址,刷新网卡mac序列号硬件码机器码,电脑主板集成网卡,pcie网卡,usb有线网卡,usb无线网卡,英特尔网卡,瑞昱网卡全支持! 一键修改mac&#xff0…

百问网全志系列开发板音频ALSA配置步骤详解

8 ALSA 8.1 音频相关概念 ​ 音频信号是一种连续变化的模拟信号,但计算机只能处理和记录二进制的数字信号,由自然音源得到的音频信号必须经过一定的变换,成为数字音频信号之后,才能送到计算机中作进一步的处理。 ​ 数字音频系…

MySQL本地Windows安装

下载MySQL 官网:MySQL 下载完成后文件 安装类型 选择功能 功能过滤筛选,系统为64位操作系统,所以选【64-bit】,32位可选【32.bit】 下方勾选后自动检查安装环境,如果提示缺少运行库,请先安装VC_redist.x64。…

【Dash】plotly.express 气泡图

一、More about Visualization The Dash Core Compnents module dash.dcc includes a componenet called Graph. Graph renders interactive data visualizations using the open source plotly.js javaScript graphing library.Plotly.js supports over 35 chart types and …

数据结构 之 二叉树功能的代码实现

文章目录 二叉搜索树搜索删除节点二叉树的遍历 代码实现 二叉搜索树 无序树的查找,就是整个遍历,所以时间复杂度为O(N)。为了优化无序查找的时间复杂度,我们把树进行排序,这里引入了二叉搜索树。 二叉搜索树是一个有序树&#xf…

vue el-select下拉框在弹框里面错位,

1&#xff1a;原因是因为 底层滚动条滚动的问题。 2&#xff1a;解决方案 加上这个属性 :popper-append-to-body"false" 和样式 <el-select:popper-append-to-body"false"> </el-select><style> .el-select .el-select-dropdown {t…

数据埋点系列 4|数据分析与可视化:从数据到洞察

在前面的文章中,我们讨论了数据埋点的基础知识、技术实现以及数据质量保证。现在,我们拥有了高质量的数据,是时候深入挖掘这些数据的价值了。本文将带你探索如何通过数据分析和可视化,将原始数据转化为有价值的业务洞察。 目录 1. 数据分析基础1.1 描述性统计1.2 推断统计1.3 相…

Haproxy的配置详解与使用

一、haproxy简介 HAProxy是一个使用C语言编写的自由及开放源代码软件&#xff0c;其提供高可用性、负载均衡&#xff0c;以及基于TCP和HTTP的应用程序代理。 HAProxy特别适用于那些负载特大的web站点&#xff0c;这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬…

uniapp实现自定义弹窗组件,支持富文本传入内容

1.首先安装vuex 通过此命令安装 ​​npm install vuex --save​​ 创建initModal.js import Vuex from vuex // 自定义弹窗 export default function initModal (v) {// 挂在store到全局Vue原型上v.prototype.$modalStore new Vuex.Store({state: {show: false,title: 标题,c…

【人工智能】深入理解自监督学习中的表征学习与对比学习

我的主页&#xff1a;2的n次方_ 1. 自监督学习 1.1 自监督学习的概念 自监督学习是一种无需大规模标注数据的学习方法&#xff0c;通过构造代理任务&#xff0c;模型可以从数据本身获取监督信号&#xff0c;从而学习有用的特征表征。 1.2 自监督学习的背景与重要性 在当今大…

【C++进阶学习】第十三弹——C++智能指针的深入解析

前言&#xff1a; 在C编程中&#xff0c;内存管理是至关重要的一个环节。传统的手动内存管理方式容易导致内存泄漏、悬挂指针等问题。为了解决这些问题&#xff0c;C引入了智能指针。本文将详细讲解C中智能指针的概念、种类、使用方法以及注意事项。 目录 一、引言 二、智能指…

链表---数据结构-黑马

链表 定义 链表是数据元素的线性集合&#xff0c;其每个元素都指向下一个元素&#xff0c;元素存储上是不连续的。 分类 单向链表&#xff0c;每个元素只知道自己的下一个元素是谁。 双向链表&#xff0c;每个元素知道自己的上一个元素和下一个元素。 循环链表&#xff0c;…

分布式锁:Mysql实现,Redis实现,Zookeeper实现

目录 前置知识 Mysql实现分布式锁 1.get_lock函数 Java代码实现&#xff1a; 2.for update尾缀 Java代码实现&#xff1a; 3.自己定义锁表 Java代码实现&#xff1a; 4.时间戳列实现乐观锁 Java代码实现&#xff1a; Redis实现分布式锁 Zookeeper实现分布式锁&#…

Oracle搭建一主两备dataguard环境的详细步骤

​ 上一篇文章介绍了Oracle一主两备的DG环境&#xff0c;如何进行switchover切换&#xff0c;也许你会问Oracle一主两备dataguard环境要怎么搭建&#xff0c;本篇文章将为你讲述一主两备dataguard详细搭建步骤。 环境说明 主机名IP地址db_unique_name数据库角色ora11g10.10.1…

驱动数智化升级,AI大模型准备好了吗?

大数据产业创新服务媒体 ——聚焦数据 改变商业 AI大模型的快速崛起&#xff0c;为企业带来了前所未有的变革机遇。从自然语言处理到图像识别&#xff0c;从精准营销到智能制造&#xff0c;AI大模型正逐步渗透到各行各业的核心业务中。然而&#xff0c;随着技术的不断演进&…