编写一个侦听USB端口的小型实用工具,需要建议 [英] Writing a small utility tool that listens on USB ports, need advice

查看:51
本文介绍了编写一个侦听USB端口的小型实用工具,需要建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个可以循环工作的硬件.它带有专有的软件工具,使用户可以通过USB从PC对其进行控制.用户定义每个周期多长时间.在每个周期的开始,软件工具都会通过USB快速向硬件发出一系列命令,然后进入空闲模式,等待下一个周期.

还有第二个硬件需要与第一个同步.基本上,当将上述一系列命令发布给硬件#1时,硬件#2也应这样做.

硬件#2随附API和SDK,以及其他功能.硬件#1没有-只有此工具可用来定义您的周期长短.

鉴于所有这些,已确定实现此目的的最简单方法是侦听硬件#1使用的USB端口,以便每次检测到硬件#2上的流量时,都会发出其指令.我已经在硬件#1的USB端口上使用了一个监视应用程序,它的流量看起来非常简单:在一个周期的开始,它是连续快速且短暂的数据包,直到下一个周期才开始.

该想法是编写一个基于Windows的小型实用程序,该应用程序将侦听硬件#1的USB端口,并在每次检测到周期时向硬件#2发出API调用.理想情况下,它应该是.NET应用程序,因为就编写Windows代码而言,我最熟悉它.

困难的部分是编写用于侦听硬件#1的USB端口的代码.另外,我一直都无法访问硬件#1,因此我使用普通的USB键盘和鼠标作为其替代品.目前的目标是仅检测键盘或鼠标USB端口上的流量.

到目前为止,我已经尝试了两个在Web上找到的库-LibUsbDotNet和Usb.Net.我无法通过两者之一实现目标.

我甚至无法让Usb.Net读取数据包...

并且LibUsbDotNet似乎劫持了流量-因此,如果我在记事本或Word中的键盘上键入内容,则字母不会出现在此处,而我的应用程序会成功读取数据包.将拦截的数据包写回端口没有帮助.

这是我与LibUsbDotNet一起使用的代码.这基本上是图书馆的示例,经过略微修改后可以与我的键盘一起使用.

 //1118 =供应商ID,1872 =产品IDUsbDeviceFinder MyUsbFinder =新的UsbDeviceFinder(1118,1872);ErrorCode ec = ErrorCode.None;尝试{//找到并打开USB设备.MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);//如果设备已打开并准备就绪如果(MyUsbDevice == null)抛出新的Exception(找不到设备.");//如果这是一个完整"的USB设备(libusb-win32,linux libusb-1.0)//它公开了IUsbDevice接口.如果不是(WinUSB)//'wholeUsbDevice'变量将为null,表示这是//设备的接口;它不需要或不支持//配置和接口选择.IUsbDevice wholeUsbDevice = MyUsbDevice作为IUsbDevice;如果(!ReferenceEquals(wholeUsbDevice,null)){//这是一个完整"的USB设备.在可以使用之前,//必须选择所需的配置和接口.//选择配置#1wholeUsbDevice.SetConfiguration(1);//声明接口#0.wholeUsbDevice.ClaimInterface(0);}//打开读取端点1.UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);//键盘以大小为8的数据包进行通信byte [] readBuffer =新的byte [8];while(ec == ErrorCode.None){int bytesRead;//如果设备在最近5秒钟内未发送数据,//会发生超时错误(ec = IoTimedOut).ec = reader.Read(readBuffer,5000,out bytesRead);如果(bytesRead == 0)抛出新的Exception(string.Format("{0}:No more bytes!",ec));Console.WriteLine("{0}读取的字节",bytesRead);//将输出写入控制台.foreach(readBuffer中的字节b)Console.Write("{0}",b);Console.WriteLine();}Console.WriteLine("\ r \ n完成!\ r \ n");}抓住(前例外){Console.WriteLine();Console.WriteLine((ec!= ErrorCode.None?ec +:":String.Empty)+ ex.Message);}最后{如果(MyUsbDevice!= null){如果(MyUsbDevice.IsOpen){//如果这是一个完整"的USB设备(libusb-win32,linux libusb-1.0)//它公开了IUsbDevice接口.如果不是(WinUSB)//'wholeUsbDevice'变量将为null,表示这是//设备的接口;它不需要或不支持//配置和接口选择.IUsbDevice wholeUsbDevice = MyUsbDevice作为IUsbDevice;如果(!ReferenceEquals(wholeUsbDevice,null)){//释放接口#0.wholeUsbDevice.ReleaseInterface(0);}MyUsbDevice.Close();}MyUsbDevice = null;//释放USB资源UsbDevice.Exit();}//等待用户输入Console.ReadKey();} 

我该如何修改它,以使其不截取数据包,而只是在将它们传递到其预期的目的地时对其进行检测?

Usb.Net或LibUsbDotNet欢迎提供任何建议.或者,也许是另一个更适合我需求的图书馆?

解决方案

与实际的端到端USB设备控件相比,USB流量嗅探并不常见,因此可用于帮助此类事情的库数量有点在地面上稀薄.您可能需要做一些调整以适应可用的选项.

一种简单易懂的方法是

使用这种方法的主要问题是必须实现Pcap数据格式,我强烈怀疑您最终将不得不自己做,因为 do 的所有Pcap解析实现都存在(包括(.NET专用)都是针对(再次)使用Pcap捕获网络数据的情况.

但是,在您惊慌失措之前,我建议将其作为可能可行的解决方案,因为 entire 格式的文档似乎可以同时适用于位A4页面(我在打印预览中进行了检查:D): https://desowin.org/usbpcap/captureformat.html -此外,在 https://wiki.wireshark上,还有官方的Pcap格式参考也显然不是特别密集.​​.org/Development/LibpcapFileFormat (由USBPcap网站链接).

您可以使用USBPcap从文件中输出测试数据,然后花时间反复进行正确的文件解析.

同样,您也可以访问设备并保存一些流量转储,以便以后按自己的速度进行解析,我怀疑这可能非常实用.

我发现了几个(略微旋转:))C#链接,可帮助您定向编写自己的Pcap解析器: https://github.com/ryrychj/PcapngUtils https://formats.kaitai.io/pcap/csharp.html .


在搜索的同时,我也偶然发现了其他几条线索.

第一个是 https://sourceforge.net/projects/usbsnoop/发现已移至 https://github.com/SnoopWare/usbsnoop/.实际上,这很有趣,因为它实现了自己的内核驱动程序来进行捕获.我很高兴发现了这一点-Server 2003之前的Windows不支持USB嗅探,但是它可以追溯到Windows 2000(当然,也可以追溯到Windows 10),即使它与Windows 2000一样,也很有趣.琐事.(我曾经想在设备和某些旧软件之间进行自己的USB嗅探,并认为Win2K VM将是最轻便的方式,直到我了解到这种限制为止.)前端用户界面似乎不支持记录文件.

发生的另一件有趣的事情是找到 https://www.codeproject.com/Questions/204396/USB-Sniffer-protocol -第3个帖子引发了投诉您为什么要回答这个问题,这个帖子已有两年历史了",其中包含指向不再解析的域的链接.Web存档仅在

尽管我认为以上两种都在C中.

I have a piece of hardware that works in cycles. It comes with a proprietary software tool that lets user control it from PC via USB. User defines how long each cycle is. At the beginning of each cycle the software tool rapidly issues a series of commands to the hardware via USB and then goes into the idle mode, awaiting next cycle.

There's a second piece of hardware that needs to be synched with the first one. Basically, when the aforementioned series of commands is issued to hardware #1, hardware #2 should do its thing too.

Hardware #2 comes with API and SDK and whatnot. Hardware #1 does not - there's only this tool where you can define how long your cycle will be.

In view of all this, it's been decided that the easiest way to achieve this will be by listening on USB port that hardware #1 uses so that each time traffic on it is detected hardware #2 is issued its directives too. I've used a monitoring app on hardware #1's USB port and its traffic looks pretty simple: it's a rapid and short succession of packets at the very beginning of a cycle and then nothing until the next cycle.

The idea is to write a small Windows-based utility app that will listen on hardware #1's USB port and issue an API call to hardware #2 every time it detects a cycle. Ideally, it should be a .NET app, cause I'm familiar it with the most, as far as writing Windows-code goes.

The difficult part is writing the code for listening on hardware #1's USB port. Also, I don't have access to hardware #1 at all times, so I use plain USB keyboard and mouse as its substitutes. At this point the goal is to simply detect traffic on keyboard or mouse USB ports.

So far I have attempted two libraries I found on the web - LibUsbDotNet and Usb.Net. I haven't been able to achieve the goal with either of the two.

I can't get Usb.Net to even read the packets...

And LibUsbDotNet seems to hijack the traffic - so if I type on a keyboard in a notepad or Word, letters don't appear there, while my app successfully reads the packets. Writing intercepted packets back to the port doesn't help.

Here's the code that I use with LibUsbDotNet. It's basically library's example, slightly modified to work with my keyboard.

// 1118 = Vendor Id, 1872 = Product Id
UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(1118, 1872);

ErrorCode ec = ErrorCode.None;

try
{
    // Find and open the usb device.
    MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);

    // If the device is open and ready
    if (MyUsbDevice == null) throw new Exception("Device Not Found.");

    // If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
    // it exposes an IUsbDevice interface. If not (WinUSB) the 
    // 'wholeUsbDevice' variable will be null indicating this is 
    // an interface of a device; it does not require or support 
    // configuration and interface selection.
    IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
    if (!ReferenceEquals(wholeUsbDevice, null))
    {
        // This is a "whole" USB device. Before it can be used, 
        // the desired configuration and interface must be selected.

        // Select config #1
        wholeUsbDevice.SetConfiguration(1);

        // Claim interface #0.
        wholeUsbDevice.ClaimInterface(0);
    }

    // open read endpoint 1.
    UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);

    // keyboard communicates in packets of size 8
    byte[] readBuffer = new byte[8];
    while (ec == ErrorCode.None)
    {
        int bytesRead;

        // If the device hasn't sent data in the last 5 seconds,
        // a timeout error (ec = IoTimedOut) will occur. 
        ec = reader.Read(readBuffer, 5000, out bytesRead);

        if (bytesRead == 0) throw new Exception(string.Format("{0}:No more bytes!", ec));
        Console.WriteLine("{0} bytes read", bytesRead);

        // Write that output to the console.
        foreach (byte b in readBuffer) Console.Write("{0} ", b);
        Console.WriteLine();
    }

    Console.WriteLine("\r\nDone!\r\n");
}
catch (Exception ex)
{
    Console.WriteLine();
    Console.WriteLine((ec != ErrorCode.None? ec + ":" : String.Empty) + ex.Message);
}
finally
{
    if (MyUsbDevice != null)
    {
        if (MyUsbDevice.IsOpen)
        {
            // If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
            // it exposes an IUsbDevice interface. If not (WinUSB) the 
            // 'wholeUsbDevice' variable will be null indicating this is 
            // an interface of a device; it does not require or support 
            // configuration and interface selection.
            IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
            if (!ReferenceEquals(wholeUsbDevice, null))
            {
                // Release interface #0.
                wholeUsbDevice.ReleaseInterface(0);
            }

            MyUsbDevice.Close();
        }
        MyUsbDevice = null;

        // Free usb resources
        UsbDevice.Exit();

    }

    // Wait for user input..
    Console.ReadKey();
}

How do I modify this so that it doesn't intercept the packets but simply detects them while letting them pass through to their intended destination?

Any advice is welcome with either Usb.Net or LibUsbDotNet. Or, perhaps, a different library that better suits my needs?

解决方案

USB traffic sniffing is less common than actual end-to-end USB device control, so the quantity of libraries available to help with this sort of thing is a bit thin on the ground. You're probably going to have to do a bit of adapting to what options are available.

One straightforward-looking approach is https://desowin.org/usbpcap/: the commandline version can output in real time to stdout, as shown in the screenshot below (from the linked page):

The significant catch with this approach would be the requirement to implement the Pcap data format, which I strongly suspect you will end up having to do yourself as all the Pcap parsing implementations that do exist (including for .NET) are all for the (again) more-popular case scenario of using Pcap to capture network data.

However, before you freak out, I am suggesting this as a potentially-viable solution because the entire format documentation seems to fit onto two-and-a-tiny-bit A4 pages (I checked with print preview :D): https://desowin.org/usbpcap/captureformat.html - and furthermore, the official Pcap format reference at https://wiki.wireshark.org/Development/LibpcapFileFormat (linked to by the USBPcap site) is also distinctly not especially dense.

You could use USBPcap to output test data from a file, then just spend time iterating on parsing the file correctly.

In the same vein you could also get access to the device and save a few traffic dumps for later parsing at your own pace, which I suspect may be very practical.

I found a couple of (slightly-bitrotted :) ) C# links that may serve to help get oriented with writing your own Pcap parser: https://github.com/ryrychj/PcapngUtils and https://formats.kaitai.io/pcap/csharp.html.


While searching I also stumbled on a couple other leads.

The first was https://sourceforge.net/projects/usbsnoop/, which I found had moved over to https://github.com/SnoopWare/usbsnoop/. This is actually really interesting, as it implements its own kernel driver to do capture. I am kind of glad I found this - Windows before Server 2003 doesn't have USB sniffing support but this works as far back as Windows 2000 (and as recently as Windows 10, of course), which is fun to know even if just as trivia. (I once wanted to do some USB sniffing of my own between a device and some old software, and thought a Win2K VM would be the most lightweight way to do it until I learned about the limitation.) Maybe not so practical for your purposes; the frontend UI doesn't appear to support logging to files.

The other amusing thing that happened was finding https://www.codeproject.com/Questions/204396/USB-Sniffer-protocol - Post 3 generated the complaint "why are you answering this, this post is two years old", included a link to a domain that no longer resolves. The Web Archive has only one copy of the linked page over at http://web.archive.org/web/20140127164835/www.tellmeword.com/dh9ic/usb_sniffer_(source_code) - and the downloads (the Mirror ones) got archived too! Ha! I have no idea if they are useful or if the techniques they use are deprecated etc.

Both the above are in C though I think.

这篇关于编写一个侦听USB端口的小型实用工具,需要建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆