Skip to content

Instantly share code, notes, and snippets.

@antoinevg
Created August 29, 2024 13:42
Show Gist options
  • Save antoinevg/635a614288aedd346b3d0de90f503512 to your computer and use it in GitHub Desktop.
Save antoinevg/635a614288aedd346b3d0de90f503512 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# pylint: disable=unused-wildcard-import, wildcard-import
#
# This file is part of Facedancer.
#
import logging
from facedancer import *
from facedancer import main
from facedancer.classes import USBDeviceClass
from usb_protocol.emitters.descriptors.microsoft10 import MicrosoftOS10DescriptorCollection
from usb_protocol.types.descriptors.microsoft10 import RegistryTypes
@use_inner_classes_automatically
class WCIDDevice(USBDevice):
"""USB Device For testing WCID descriptors."""
vendor_id : int = 0x1209
product_id : int = 0x0006
device_revision : int = 0x0000
device_class : int = 0
product_string : str = "WCID Test Device"
manufacturer_string : str = "Facedancer"
serial_number_string : str = "AAAA"
msft_vendor_code = 0xee
msft_string_number = 0xee
device_speed : DeviceSpeed = DeviceSpeed.FULL
class Configuration0(USBConfiguration):
# Device class 0 indicates that this is a composite device and that the
# host should look in the interface descriptors for class information.
# We have two interfaces which Windows should present to the user as two
# separate devices.
class Interface0(USBInterface):
number : int = 0
class_number : int = USBDeviceClass.VENDOR_SPECIFIC
interface_string : str = "WCID Test Interface 0"
class Interface1(USBInterface):
number : int = 1
class_number : int = USBDeviceClass.VENDOR_SPECIFIC
interface_string : str = "WCID Test Interface 1"
@vendor_request_handler(condition=lambda r: r.number == WCIDDevice.msft_vendor_code, direction=USBDirection.IN)
@to_device
def handle_feature_request(self: USBDevice, request: USBControlRequest):
"""Handle requests for OS Feature Descriptors"""
wIndex_list = [x[0] for x in list(self.msft_descriptors)]
if request.index in wIndex_list:
location = wIndex_list.index(request.index)
request.reply(list(list(self.msft_descriptors)[location][1]))
else:
request.stall()
def __post_init__(self):
super().__post_init__()
# OS String Descriptor tells Windows the vendor request number needed
# to retrieve the OS Feature Descriptors.
self.strings.add_string("MSFT100" + chr(self.msft_vendor_code), index=self.msft_string_number)
# OS Feature Descriptors.
self.msft_descriptors = MicrosoftOS10DescriptorCollection()
# Extended Compat ID OS Feature Descriptor indicates that the
# interfaces are compatible with WinUSB.
with self.msft_descriptors.ExtendedCompatIDDescriptor() as c:
with c.Function() as f:
f.bFirstInterfaceNumber = 0
f.compatibleID = 'WINUSB'
with c.Function() as f:
f.bFirstInterfaceNumber = 1
f.compatibleID = 'WINUSB'
# Extended Properties OS Feature Descriptor contains the GUID for the
# WinUSB driver.
with self.msft_descriptors.ExtendedPropertiesDescriptor() as d:
with d.Property() as p:
p.dwPropertyDataType = RegistryTypes.REG_SZ
p.PropertyName = "DeviceInterfaceGUID"
p.PropertyData = "{88bae032-5a81-49f0-bc3d-a4ff138216d6}"
main(WCIDDevice)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment