I am debugging some code that uses a 3rd party 64-bit DLL to access a custom USB device. My environment is Microsoft Visual Studio 2012 on Windows 8.1 x64.
According to an incomplete and unreliable document, the DLL is supposed to issue a USBDEVFS_CONTROL ioctl to read 1 byte from a connected USB device. The definition involves
ctrl.bRequestType = bmRequestType;
ctrl.bRequest = bRequest;
ctrl.wValue = wValue;
ctrl.wIndex = wIndex;
ctrl.data = ByteArray;
ctrl.wLength = 64;
ctrl.timeout = 1000;
Here bmRequestType, bRequest, wValue, and wIndex are constants provided by the device manufacturer, and ByteArray is a uint8_t[64] buffer that contains the specific command.
The DLL accepts application-specific parameters, packs them into the ByteArray, and calls ksproxy.ax->Kernelbase.dll->ntdll.dll. The last disassembly I can see in user mode, is
mov r10,rcx
mov eax,47h
syscall
ret
With step-by-step debugger, I can easily see that the ByteArray is constructed exactly as it is supposed to be, according to the document. But I cannot find the usbdevfs_ctrltransfer structure, or its Windows equivalent.
Specifically, we suspect that the value of wIndex, specified in the document, applies to an older version of hardware, and that the Windows DLL actually uses 0x0400 instead of 0x0402.
Any hint (including hardware or software USB sniffers, emulators, etc.) how we can try to verify this unsigned short will be greatly appreciated.
Update
Reading https://reverseengineering.stackexchange.com/questions/2416/how-to-reverse-engineer-simple-usb-device-windows-linux and https://reverseengineering.stackexchange.com/questions/1786/usb-dongle-traffic-monitoring. It looks like these tools are not compatible with Windows 8.1 x64.
While working on the Xbox OS and peripherals, we always used the CATC Chief USB capture hardware, which works as a man-in-the-middle device (it looks like it has been superseded by the Teledyne LeCroy protocol analyzers).
The traffic capture capabilities were indispensable in diagnosing hardware and software errors (bulk, HID, isoch).
Sample capture view (from the manual):
Related
How is linux cdc_ecm driver related to rndis protocol? Is cdc_ecm based on rndis specification from microsoft in any way?
From this wiki page https://en.wikipedia.org/wiki/RNDIS
The USB Implementers Forum (USB-IF) defines at least three non-proprietary USB communications device class (USB CDC) protocols with comparable "virtual Ethernet" functionality; one of them (CDC-ECM) predates RNDIS and is widely used for interoperability with non-Microsoft operating systems, but does not work with Windows.
seems cdc_ecm to be based on microsoft rndis.
CDC-ECM is a standard that was created by USB-IF. It's not related to RNDIS at all. As your quote says, it predates RNDIS. This means it was created before RNDIS existed, so it couldn't be based on RNDIS unless a time machine enters the picture. And if you look at the protocol, it's clearly different.
CDC-ECM works out of the box on Linux hosts, MacOS, ChromeOS, and certain (mainly Samsung) Android phones.
Microsoft decided to create a new Ethernet on USB protocol instead of using the standard that already existed (CDC-ECM). That's just how Microsoft is. So they created RNDIS which isn't a standard and wasn't published. It's a hack based on NDIS, which is an old DOS and Windows 3.11 era network protocol from Microsoft. That's also just how Microsoft is. They like to base stuff on top of older MS software, which is based on even older MS software, going all the way back to DOS. That makes it really complex and hard for anyone else to be compatible with.
Microsoft doesn't include CDC-ECM drivers in Windows, but does have RNDIS drivers.
One can't get Windows to load the included RNDIS drivers, without a INF file, using just the vendor and product ID, device class, etc. There is a non-standard USB device identification descriptor that Microsoft created (see the pattern here) that must be used to identify a RNDIS device to Windows so it will load the generic driver.
Linux has a CDC-ECM / RNDIS combo gadget that is useful for wider compatibility. This appears as a two function USB device. One function is RNDIS and Windows will use this. The other function is CDC-ECM and everyone else will use that. It's not "ECM with RNDIS support". It's two different functions, only one of which can be used at once, that are both created by the same gadget.
What is The Interrupt for User input and output in Console Window?
Hello I'm trying to learn Assembly Language, I know that in MS-DOS Operating System, the .COM programs were Supported, and were loaded into memory at 100h, isn't it? And the first 1k bytes were the IVT or Interrupt vector table, it is a list of interrupts, isn't it?? So in MS-DOS if we want to Ask an input from the user we first Move 01 to AH register like MOV ah, 01 and call the Interrupt INT 21h, I don't know if this is gonna work on DOS or not, I never tried the DOS virtual machine or something Similar Applications, i don't want the DOS program I just want a Console Window for Asking a user for Input...
I have just stepped into Assembly programming and found no Complete tutorials on Windows, Or not just One which Shows the use of Interrupts, Everywhere MASM is used with windows.inc libs, and the C standard libs, i don't wanna waste my time learning them, As after learning Assembly programming i Want to learn Writing Booting Programs, Which doesn't Sticks to one Operating system, And the reason i want to use Interrupts is just for learning purpose, Meaning this is just to learn Assembly language, Currently i know very less instructions like MOV ADD SUB INC INT & DEC And know nothing or very less about Registers, So with these limited Capability i cannot write Boot Programs, and for this reason im trying to learn or Practice assembly on Windows but with interrupts, and thus does not want to use those Predefined libraries in my Applications, and want to Only use Interrupts from IVTs and shift to BIOS interrupts, for Boot Programs.
I heard on a forum that Microsoft hides its Windows IVTs from the public as they want their APIs to become popular, Is this true? Thus this means there is no way i can use interrupts to handle I/O in Windows?? because there is no such Documentary on it, if No Kindly Post it with An Example for NASM, and Please Refer to any Online/Offline guide, and my last request please Tell me how can i Convert MASM written souce code for NASM, i mean what is the difference between them, In Short, i have Two requests and One Question as follows:
1. Q1: What is the Interrupt for Console I/O in Windows?
2. R1: Please share any Good tutorials on Assembly for windows Especially on using Interrupts just like TutorialsPoint but Its for Linux and I want for Windows.
And the Last One...
3. R2: How is MASM's input file source code different from NASM one?? I mean How much and where can i find difference writing source code for them, As many tutorials said that Many MASM programs wont run in NASM...
Thanks in Advance!!
And the first 1k bytes were the IVT or Interrupt vector table ...
Modern CPUs have two (in the case of 64-bit CPUs even three) operating modes: The "real mode" and the "protected mode".
When the CPU starts up and in MS-DOS the CPU runs in "real mode". When Windows is running the CPU runs in "protected mode". In this mode the interrupt system works completely different than in "real mode".
It is not possible to access the IVT directly and it is not possible to access memory belonging to a task from another task.
What is the Interrupt for Console I/O in Windows?
Windows NT, 32-bit, used interrupt 1Eh. However other Windows versions (Windows 9x for example) used another method of entering the operating system.
As far as I know 64-bit versions of Windows also do not use interrupts.
No Windows program (with exception of the old 16-bit Windows programs) is using interrupts directly.
hides its Windows IVTs from the public as they want their APIs to become popular, Is this true?
They hide the interrupt numbers because they are only available in some Windows versions.
The only possibility to write a program that works on all Windows versions currently in use is to use the Windows APIs.
i don't wanna waste my time learning them
In this case don't waste your time writing Assembler programs for Windows! Doing so only makes sense if you are interested in compiler development.
Use some virtual machine tool (Bochs, VMware, ...) and start writing "booting programs" NOW or use an MS-DOS emulator and write Assembler programs for MS-DOS.
The only use of Assembler programs for Windows is that the 32-bit assembler is a bit easier to learn than the 16-bit assembler (which is required for MS-DOS and "booting programs") so writing Assembler programs for Windows may be good for learning purposes...
Essentially, I want to know how to access the raw byte code sent by a USB device at a given port using C++ on windows. Specifically, I am trying to write a program to interface with an IR receiver. (Yes I have tried using other software, EventGhost, IRSS, etc.)
I have Visual Studio Ultimate if that helps with anything.
Thanks in advance.
I am trying to complete the picture of how the PC and the OS interacts together. And I am at point, where I am little out of guess when it comes to device drivers.
Please, don´t write things like its too complicated, or you don´t need to know when using high programming laguage and winapi functions. I want to know, it´s for study purposes.
So, the very basic structure of how OS and PC (by PC I mean of course HW) is how I see it is that all other than direct CPU commands, which can CPU do on itself (arithmetic operation, its registers access and memory access) must pass thru OS. Mainly becouse from ring level 3 you cannot use in and out intructions which are used for acesing other HW. I know that there is MMIO,but it must be set by port comunication first.
It was not like this all the time. Even I am bit young to remember MSDOS, I know you could access HW directly, becouse there ws no limitation, no ring mode. So you could to write string to diplay use wheather DOS function, or directly acess video card memory and write it by yourself.
But as OS developed, there is no longer this possibility. But it is fine, since OS now handles all the HW comunication, and frankly it more convinient and much more safe (I would say the only option) in multitasking environment. So nowdays you instead of using int instructions to use BIOS mapped function or DOS function you call dll which internally than handles everything you don´t need to know about.
I understand this. I also undrstand that device drivers is the piece of code that runs in ring level 0, so it can do all the HW interactions. But what I don´t understand is connection between OS and device driver. Let´s take a example - I want to make a sound card make a sound. So I call windows API to acess sound card, but what happens than? Does windows call device drivers to do so?
But if it does call device driver, does it mean, that all device drivers which can be called by winAPI function, must have routines named in some specific way? I mean, when I have new sound card, must its drivers have functions named same as the old one? So Windows can actually call the same function from its perspective? But if Windows have predefined sets of functions requored by device drivers, that it cannot use new drivers that doesent existed before last version of OS came out.
Please, help me understand this mess. I am really getting mad. Thanks.
A Windows device driver is a bit like a DLL: except that instead of an application dynamic linking/loading it, it's the O/S that dynamic links/loads it.
Registry entries tell the O/S what device drivers exist (so that the O/S knows which device drivers to dynamic-link/load).
The device drivers run in ring 0. In ring zero, they (device drivers) don't have access to (can't link to or use) Windows APIs: instead they have access to various NT kernel APIs.
But if it does call device driver, does it mean, that all device drivers which can be called by winAPI function, must have routines named in some specific way? I mean, when I have new sound card, must its drivers have functions named same as the old one? So Windows can actually call the same function from its perspective?
Basically yes. All the device drivers within a given type or class (e.g. all video drivers, or all disk drivers) have a similar API, which is invoked by the O/S (and/or invoked by higher-level drivers, for example disk drivers are used/invoked by file system drivers).
The Windows Device Driver Kit defines the various APIs and includes sample drivers for the various types of device.
But if Windows have predefined sets of functions requored by device drivers, that it cannot use new drivers that doesent existed before last version of OS came out.
The O/S is dynamic-linking to the device driver functions: because device driver APIs are predefined, device drivers are interchangeable as far as the O/S is concerned; new device drivers can be written, provided they support (are backward-compatible with) the standard device driver API.
The dynamic-linking mechanism is very similar to the way in which COM objects or C++ classes implement any predefined pure-abstract interface: a header file in the DDK declares the pure-abstract interface (like virtual functions), device drivers implement these functions, and the O/S loads the drivers and invokes these functions.
The basics:
Please note that this explanation is simplified and sometime only true for most cases and not all.
Most HW devices you will ever encounter will have these basic operations:
Write to memory(or Registers) on them.
Read from memory(or Registers) on them.
This is enough to control the HW, to give it the data it needs, and to get the data you want from it.
These memory areas are mapped by the BIOS and/or the OS to the Physical memory range on your PC (which may in turn be accessed by your driver.)
So we now have two operations READ and WRITE that the device driver knows to do.
In addition, the driver can read and write in a manner that does not involve the cpu. This is called Direct Memory Access (DMA) and usually performed by your HW.
The last type of operation is called INTERRUPTS and is meant for your HW to notify your driver of something that just happend. This is usually done by the HW interrupting the CPU and calling your driver to perform some operation in high priority. For example: an image is ready in the HW to be read by the driver.
This may not be considered to be directly programming related but I am at a loss to know where else to ask. I have tried looking at a variety of websites but so far Google has not been my friend.
I am having trouble finding out whether I need to write my own device driver for the various windows/linux/mac platforms that the device I am developing may be connected to, or whether the functionality is provided by the standard drivers.
My device is a USB CDC (communications device) that appears as a COM: port. It also includes a battery charger that will, once the device has been enumerated require the full 5 unit load (500mA) supply current that can be drawn from the USB connector. My problem is that if the USB driver in the host decides that it cannot deliver the full supply current then it should fail to enumerate the device.
If, as a fallback, I provide a second configuration set that only allows the device to draw 1 unit load from the interface connector will the standard drivers enumerate the device using this configuration.
You need to write a .inf file for Windows that ties up your device VID and PID with the system usbser.sys. Mine looks like this (Replace YourCompany as necessary, put in your VID and PID (in hex), and change the DriverVer line to whatever date and version you want):
; -----------------------------------------------------------------------------
; XP/2000 USB Comms Port Setup
; -----------------------------------------------------------------------------
[Version]
DriverVer=12/03/2008,1.0.0000.0000
Signature="$Windows NT$"
Class=Ports
ClassGUID={4d36e978-e325-11ce-bfc1-08002be10318}
Provider=%YourCompany%
[DestinationDirs]
DefaultDestDir=10,system32\drivers
DriverCopyFiles=12
[ControlFlags]
ExcludeFromSelect = *
[Manufacturer]
%YourCOmpany%=YourCompanySerialPort
[YourCompanySerialPort]
%YourCompanyUSBSerialPort%=YOURCOMPANYUSB,USB\VID_1234&PID_ABCD
;
; Win 2000/XP
;
[YOURCOMPANYUSB]
Include=mdmcpq.inf
CopyFiles=FakeModemCopyFileSection
[YOURCOMPANYUSB.HW]
AddReg=YOURCOMPANYUSBAddReg.HW
[YOURCOMPANYUSBAddReg.HW]
HKR,,DevLoader,0,*ntkern
HKR,,NTMPDriver,,"usbser.sys"
[YOURCOMPANYUSB.Services]
AddService=usbser, 0x00000002, FuncDrv_Service_Inst
[FuncDrv_Service_Inst]
DisplayName=%USBFilterString%
ServiceType= 1
StartType = 3
ErrorControl = 0
ServiceBinary = %12%\usbser.sys
[Strings]
YourCompany="YourCompany"
YourCompanySerialPort="Your Company USB Serial Port"
USBFilterString = "USB Serial Service"
Note this works with 32 bit OSs only. It also works with Vista although the file header doesn't say so!
Be aware that some versions of usbser.sys have significant problems, including bluescreening, for example when transferring packets that are exact multiples of 64 bytes. If you're using XP SP2 or previous then install hotfix KB943198. XP SP3 and Vista are fine.
For the Mac you simply need to report your device class correctly and the driver scan picks up the correct drivers. (Windows ignores the device class which is why you need to supply the .inf file).
EDIT: Sorry, I should have been clearer. This will not fail to enumerate if it can't draw the full load - I'm not sure that's possible.
You are correct on the driver question. When the device is plugged in and goes through the enumeration process it is required to stay < 100mA. The host will interrogate and determine the configuration(s). If there are more than one which support different power levels, then the driver will need to decide to select the appropriate configuration. If there is only high-power and it is not available, then it will not enumerate the device. In general, the standard driver doing CDC wouldn't be aware of the different device level configurations that would possible and so would require some degree of customization to handle them.
I am not sure about power question but ther is pleanty CDC drivers (or I think there is) so you could use one. For the power question, the solution with many configuration is probably good one, I have never encountered this in work (I have USB analyzer) but at home sometimes when I have 3 or more different devices that requires power from USB I got failed enumeration. I supose this is operating system choice if it can't supply power to new device it cut's it off (sensible choice as it can't power it). This is my gues rather checking USB standart.
If your device reports a device ID that the host OS already supports,
then they won't need a driver.
You may need to impersonate an existing USB uart. Data sheets are readily available.
(But I figure you already knew that.)
I'm not sure that the host OS will honour your multi-configuration idea.
But give it a punt so we all know!
If your device is connecting as USB CDC-ACM device to the windows desktop host, the windows desktop already provides the driver usbser.sys. But there are some some issues in windows Vista. You just need the inf to install the usbser.sys on desktop. For WinCE you do not have the driver and for you need to write or get one from any third party vendor. Here is one
http://www.em.avant-garde-lab.com/Products.html
If your device specifies itself as self powered in its device descriptor then the host would rely on the devices self power capability. You can check at usb.org for details.
Thanks.