监控USB设备插拔
发布日期:2021-06-29 01:28:04 浏览次数:2 分类:技术文章

本文共 8993 字,大约阅读时间需要 29 分钟。

UKey加密中设计到USB设备. 因UKEy是用来加密和执行PC与项目间通信加密的介质.从作用范围来讲不是传统意义上U盘作为存储介质来使用.其实熟悉网银驱动DR应该了解.在网银系统安全上一个最基本需求就是动态即时监控通信PC驱动以及设备列表通信变化.当然包括我们加密存储介质在PC上USB插拔.

思路一.在WinFrom中通过拦截Windows 消息机制来实现. 类似定义MEssageForm窗体. 假如用鼠标左击一下窗体, 系统会收到一条 WM_LBUTTONDOWN 消息;当鼠标抬起, 系统又会收到 WM_LBUTTONUP 消息.系统收到消息后, 会告诉窗体发生的事情, 然后窗体再做出反应; 当然窗体能否做出反应要看窗体是否有相应的响应代码. 同样也可以把USB设备插拔事件通过重写窗体方法拦截并处理.

首先引入命名空间:

1:  using System.Management;
2:  using System.Threading;
3:  using System.Security.Permissions;

定义Device Management Event的枚举:

1:    public enum DeviceEvent : int
2:          {
3:              DBT_CONFIGCHANGECANCELED = 0x0019,
4:              DBT_CONFIGCHANGED=0x0018,
5:              DBT_CUSTOMEVENT=0x8006,
6:              DBT_DEVICEARRIVAL=0x8000,//USB Insert DEvice Statu
7:              DBT_DEVICEQUERYREMOVE=0x8001,
8:              DBT_DEVICEQUERYREMOVEFAILED=0x8002,
9:              DBT_DEVICEREMOVEPENDING=0x8003,//USB Revoing.
10:              DBT_DEVICEREMOVECOMPLETE=0x8004,//USB Remove Completed
11:              DBT_DEVICETYPESPECIFIC=0x8005,
12:              DBT_DEVNODES_CHANGED=0x0007,//Device List _Changed
13:              DBT_QUERYCHANGECONFIG=0x0017,
14:              DBT_USERDEFINED=0xFFFF
15:          }

其中涉及到USB设备插拔的是DEVICEREMOVEPENDING/DEVICEREMOVECOMPLETE[删除]  DEVICEARRIVAL[插入设备]  重写WinFProc实现窗体上对Windows MEssage进行拦截并重新处理:

1:        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
2:          protected override void WndProc(ref Message m)
3:          {
4:              base.WndProc(ref m);
5:              DeviceEvent lEvent;
6:
7:              lEvent = (DeviceEvent)m.WParam.ToInt32();
8:              switch (lEvent)
9:              {
10:                  case DeviceEvent.DBT_DEVICEARRIVAL://[Insert]
11:                      this.CheckDeviceStatus_Lable.BackColor = Color.Green;
12:                      this.CheckDeviceStatus_Lable.Text = "----Connection Device!----";
13:                      MessageBox.Show("Just Insert At Moment !", "Insert");
14:                      break;
15:                  case DeviceEvent.DBT_DEVICEREMOVECOMPLETE://[REmove]
16:                      this.CheckDeviceStatus_Lable.BackColor = Color.Red;
17:                      this.CheckDeviceStatus_Lable.Text = "------No Connection------";
18:                      MessageBox.Show("Remove Complete At Moment!", "Remove");
19:                      break;
20:                  case DeviceEvent.DBT_DEVNODES_CHANGED://[Device List Have Changed]
21:                      MessageBox.Show("Device List have been Changed!");
22:                      break;
23:                  default:
24:                      break;
25:              }
26:          }

首先USB在进行插拔即时如果没有存储介质即Disk或是无驱动的方式可能不能触发DeviceEvent.DBT_DEVICEREMOVECOMPLETE 和 DeviceEvent.DBT_DEVICEARRIVAL插把事件. 但是一点是可以确认的是.PC端只要接受USB设备.PC识别之后设备列表肯定会发生变化. 如果不是加密Key. u盘的 盘符方式存在Disk存储介质.则没有问题.

当然需要移植这种基于From窗体系统Message拦截方法时发现这种可重用性就不高.换一种思路采用Windows底层方式WMI实现.

WMI以CIMOM为基础,CIMOM即对象管理器[Common Information Model Object Manager],是一个描述操作系统构成单元的对象数据库,为MMC和提供了一个访问操作系统构成单元的公共接口。有了WMI,和脚本程序访问操作系统的不同部分时不需要使用不同的API;相反,操作系统的不同部分都可以插入WMI,工具软件和WMI可以方便地读写WMI.

WMI 可以产生的系统级事件的一些更有用。 每当创建 WMI 类的新实例 ; 例如对于激发称为 __instancecreationevent 事件__instancedeletionevent 时将触发一个实例将被删除.  当然USB插拔时同样获得这个系统事件:

1:    public void ControlUSBConnectionStatu()
2:          {
3:              ManagementEventWatcher getEventWatcher = null;
4:              WqlEventQuery getEventQuery = null;
5:   
6:              ManagementOperationObserver getObserver = new ManagementOperationObserver();
7:   
8:              //Bind to Loacl Machine and Watch the PortConnection
9:              ManagementScope getScope = new ManagementScope("root\\CIMV2");
10:              getScope.Options.EnablePrivileges = true;//set requeired
11:   
12:              try
13:              {
14:                  getEventQuery = new WqlEventQuery();
15:                  getEventQuery.EventClassName = "__InstanceOperationEvent";
16:                  getEventQuery.WithinInterval = new TimeSpan(0, 0, 0, 1);
17:                  getEventQuery.Condition = @"TargetInstance ISA 'Win32_DiskDrive' ";
//[Disk must have DiskDrive fuck ]
 
20:                  //Event Watcher [Test Event and semd informatio to this message and create new informtion .]
21:                  getEventWatcher = new ManagementEventWatcher(getEventQuery);
22:                  getEventWatcher.EventArrived += new EventArrivedEventHandler(getEventWatcher_EventArrived);
23:                  getEventWatcher.Start();//Start Watch Event
 
25:              }
26:              catch (Exception se)
27:              { }
28:              finally
29:              {
30:                  // getEventWatcher.Stop();
31:              }
32:          }

当发生USB插拔并成功监听到事件时处理方法:

1:   void getEventWatcher_EventArrived(object sender, EventArrivedEventArgs e)
2:          {
3:              ManagementBaseObject getBaseObject = (ManagementBaseObject)e.NewEvent;
4:              if ((getBaseObject.ClassPath.ClassName == "__InstanceCreationEvent"))
5:              {
6:                  //Usb Inserted
7:                  MessageBox.Show("USB Disk Inserted!");
8:              }
9:              else
10:              {
11:                  //Usb Removed
12:                  MessageBox.Show("USB Device Removed!");
13:              }
14:          }

如上在定义时设置一个Condition[条件]:存在Disk Driver 磁盘驱动.如果类似某些UKey不存在磁盘驱动同时也无存储介质 经过测试你会发现.加密的UKey插入 如上的WMI监听事件并不能扑捉到USB插拔. 但是针对这种方式我们还有一种更为彻底的方式就是USB插拔唯一可以确定在PC识别必然变化的因素是系统设备列表发生更新.

WMI处理监听:

1:         /// 
2:          /// 监听USB Device设备插拔事件 完整操作.
3:          /// WMI Handle Event Change Device List chenkai
4:          /// 
5:          public void RegisterDeviceWMIEventStatu()
6:          {
7:              try
8:              {
9:                  //Device List HAve Changed  And Send Message
10:                  WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent");
11:                  ManagementEventWatcher watcher = new ManagementEventWatcher(query);
12:                  watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
13:                  watcher.Start();  // Start listening for events
14:              }
15:              catch (Exception se)
16:              { }
17:          }

WMI监听处理函数:

1:   void watcher_EventArrived(object sender, EventArrivedEventArgs e)
2:          {
3:              string geteventtype = e.NewEvent.GetPropertyValue("EventType").ToString();
4:              ManagementBaseObject getEventObject = (ManagementBaseObject)e.NewEvent;
5:   
6:              if (getEventObject != null)
7:              {
8:                  //close Operator
9:                  this.CloseDeviceEqument();
10:              }
11:          }

其实这依然还是一种折中办法.因为导致PC端设备列表发生变化的因素有很多.如何判定是USB口发生设备变化.WMI依然没有让我们失望:

1:    //WMI Control The USB Device Change Statu And Send Message to When IT‘s Changed/
2:          public void ControlUSBDeviceSTatu()
3:          {
4:              try
5:              {
6:                  WqlEventQuery query = new WqlEventQuery("select * from Win32_VolumeChangeEvent");
7:                  ManagementEventWatcher getwatcher = new ManagementEventWatcher(query);
8:                  getwatcher.EventArrived += new EventArrivedEventHandler(getwatcher_EventArrived);
9:                  getwatcher.Start();
10:              }
11:              catch (Exception se)
12:              { }
13:          }

WMI在USB事情处理函数:

2:          void getwatcher_EventArrived(object sender, EventArrivedEventArgs e)
3:          {
4:              MessageBox.Show(e.NewEvent.GetText(TextFormat.Mof).ToString());
5:          }

这样来一来就可以清晰判定USB在插拔时所发生在系统PC端的变化通知给应用程序来进行处理.如何获得当前PC端 USB Driver列表.经过几番测试找到一种很好的方式获取全部的USB Driver信息:

1:   //Get ALL USB DRiver And Driver Property Fuck this shit。chenkai
2:          public static string[] AllInformation()
3:          {
4:              StringCollection propNames = new StringCollection();
5:              ManagementClass driveClass = new ManagementClass("Win32_USBController");
6:              PropertyDataCollection props = driveClass.Properties;
7:              foreach (PropertyData driveProperty in props)
8:                  propNames.Add(driveProperty.Name);
 
12:              int idx = 0;
13:              ManagementObjectCollection drives = driveClass.GetInstances();
14:              string _s = string.Empty;
15:              List
harddisk = new List
();
16:   
17:              foreach (ManagementObject drv in drives)
18:              {
19:                  idx++;
20:                  _s = string.Format(" USB Driver({0}) Properties ", idx);
21:                  harddisk.Add(_s);
22:                  foreach (string strProp in propNames)
23:                  {
24:                      _s = string.Format("Property: {0}, Value: {1}", strProp, drv[strProp]);
25:                      harddisk.Add(_s);
26:                  }
27:              }
28:              string[] _ss = harddisk.ToArray();
29:              return _ss;
30:          }

WMI的更多体现是对Windows 交互中进一步封装和管理.

Can考资料:

转载地址:https://blog.csdn.net/yu704645129/article/details/40339469 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:VOID和PVOID
下一篇:通俗易懂的USB协议详解(转载)

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月16日 23时48分57秒