I've sunk countless hours looking for a way to emulate USB devices in software under Windows. Two years ago there were many different ways. Today there are zero ways that I know of, apparently all removed within the last two years by an astounding tragic coincidence.
- There are two versions of the USB/IP drivers. The initial version has a bug where disconnection of a device causes a blue screen. This version is signed by ReactOS, and so you can install this version's drivers without needing to jump through any hoops under Windows. Then there's a patched version that does not cause the bluescreen. Great! Except that this version is not signed by ReactOS. Okay, maybe we can get ReactOS to sign it -- nope, they discontinued their driver signing program because of new regulations by Microsoft put in place within the last year (https://www.reactos.org/wiki/Driver_Signing). You can also no longer install unsigned drivers on Windows 10 by putting your machine into test mode. This capability was silently removed by Microsoft within the last year. You can still put your device into test mode, but the driver signing checker will still block installation. This is a damn shame because USB/IP is a great project, and it even has a signed driver but the patched version of the driver is not signed. This is infinitely frustrating.
- Kernel mode drivers for Windows now have to go through this signing process (https://docs.microsoft.com/en-us/windows-hardware/drivers/in...) as of last year. As mentioned before, this is why ReactOS discontinued their driver signing program as it's too difficult to meet these new requirements.
I have read every forum post, stack overflow post, Windows technical docs, everything I could possibly find for a way to do stable, pure software emulation of USB devices on Windows. They all evaporated within the last year or two. So frustrating as I really really want to build out something but there's simply no way to do it.
At this point I have resorted to attempting to hook every Windows system call related to USB device initialization and spoofing them but have been met with no success thus far.
I should note that the reason I want to do this in software is because I want to distribute the end result to a relatively large amount of potential users as GPL'd software. For this reason hardware emulation or patching / downgrading Windows isn't an option sadly.
It's hard to know, as you don't mention what physical USB device you're trying to circumvent, but virtualization has come a long way, especially if you take advantage of PCI pass-through. One approach, then, is to run Linux as the host OS, fake the USB device on Linux (hell, the Linux kernel has USB/IP support), and pass that into a virtualized Windows instance, which will just see a regular USB device.
This is an option I hadn't thought of, but the typical end user won't want to do this or know how as it's a gaming peripheral. I can't be more specific as there are some legal barriers I'm sorting out right now.
Myself and a friend needed to do something somewhat similar to get an emulation/mocking framework[1] for Corsair Utility Engine. Our hack was to run the Windows driver in a VM, run the framework in Linux, then pass through the virtual USB device to Windows.
If it's an input device for Windows games, without revealing the device, why does it have to go through the USB stack? Basically all games on Windows use DirectX, specifically its DirectInput libraries. (It's been a while, so they've probably been renamed, but the point remains that USB isn't necessary for all input devices, though it is up the application as to what it'll take.) Many emulators are more flexible; might take a look there, and if not, there's also Bluetooth - do the fakery in hardware.
Because the software controller uses Windows system calls (SetupAPI & DeviceIoControl()) and not DirectInput. Can't do it in hardware for the reasons I mentioned in the op.
Ugh, drivers and signing is such a mess right now.
I have before me two tablets. Both running W10 home, both using the same Intel Atom internals. But apparently one is running a the 32-bit version and the other the 64-bit version.
And lo and behold, the 32-bit version has a problem with the latest sd reader driver that MS pushes, so that it fails to see the inserted card. But the very same card, and the very same driver version, and the very same windows updates, works just fine with 64-bit.
At this point in time i wonder if i should either go back to nature or switch every PC-like product in this house to a BSD, because F Apple for their silo, F MS for their back and forth Q&A, and F the Linux "community" with their constant music chair-ing.
Then there's a patched version that does not cause the bluescreen. Great! Except that you can no longer install unsigned drivers on Windows 10 by putting your machine into test mode.
Patching out the signing check itself may not be too difficult... and if the file the signing check is in is also signed and verified by something else, then patch that... it's patches all the way down.
I remember doing this with Vista a long time ago. When the signing check fails it fails with a very distinctive error code/message, so I searched for that in all system files and went "down the rabbit hole" of patching out a few checks. I don't remember the details but there was less than a dozen bytes that needed to be changed. Previous cracking experience certainly helps. ;-)
Yeah but I want to distribute the result to users and patching driver signing checks out of their Windows installs is not an option. You are right though.
Instead of patching out one approach could be to add your own certificate to Microsoft's to allow yourself to sign your own drivers. but not nefarious actors.
Thanks for the links! Definitely interesting, and kind of annoying how hard it seems to be now :(
Would running a VM on top of windows and passing the device through to that be an option given your use-case? Could then run *nix or similar in there, and avoid the windows driver hell.
I want to distribute the end result to a large amount of users, and asking them to do things like downgrade Windows or put their device in test mode (which doesn't even work anymore) is too much overhead.
To elaborate on this section:
http://devalias.net/devalias/2018/05/13/usb-reverse-engineer...
- There are two versions of the USB/IP drivers. The initial version has a bug where disconnection of a device causes a blue screen. This version is signed by ReactOS, and so you can install this version's drivers without needing to jump through any hoops under Windows. Then there's a patched version that does not cause the bluescreen. Great! Except that this version is not signed by ReactOS. Okay, maybe we can get ReactOS to sign it -- nope, they discontinued their driver signing program because of new regulations by Microsoft put in place within the last year (https://www.reactos.org/wiki/Driver_Signing). You can also no longer install unsigned drivers on Windows 10 by putting your machine into test mode. This capability was silently removed by Microsoft within the last year. You can still put your device into test mode, but the driver signing checker will still block installation. This is a damn shame because USB/IP is a great project, and it even has a signed driver but the patched version of the driver is not signed. This is infinitely frustrating.
- Microsoft used to have this perfect thing called UDE (https://docs.microsoft.com/en-us/windows-hardware/drivers/us...). They removed it last year.
- Kernel mode drivers for Windows now have to go through this signing process (https://docs.microsoft.com/en-us/windows-hardware/drivers/in...) as of last year. As mentioned before, this is why ReactOS discontinued their driver signing program as it's too difficult to meet these new requirements.
I have read every forum post, stack overflow post, Windows technical docs, everything I could possibly find for a way to do stable, pure software emulation of USB devices on Windows. They all evaporated within the last year or two. So frustrating as I really really want to build out something but there's simply no way to do it.
At this point I have resorted to attempting to hook every Windows system call related to USB device initialization and spoofing them but have been met with no success thus far.
I should note that the reason I want to do this in software is because I want to distribute the end result to a relatively large amount of potential users as GPL'd software. For this reason hardware emulation or patching / downgrading Windows isn't an option sadly.
Does anyone know of something I missed?