 Hi guys, so I'm Dan Wetherill again. Call me Doctor if you want, I didn't put it on this one. This is the danger of thinking up two AMF camp talk proposals off the top of your head and thinking they won't like both of those. And then here we are. So basically this talk is not, I'm no expert in hacking USB devices. I'm not some kind of wizard hacker or anything. I designed cameras for a living, come on, it's totally different. I feel like you often notice that there are these amazing people who have these super skills in something like writing kernel drivers or whatever and you think it would take me five years to learn how to do that. And I thought it was the same with reverse engineering random USB devices. It turns out it's much easier than you think it is, or at least it's much easier than I thought it was going to be. And so I'm going to share some of my experiences and try and encourage everybody to hack random rubbish Chinese USB devices you can buy off eBay. So a lot of people have turned up. So maybe this will narrow it down a bit. Why would you want to hack random USB devices? For me because I only use reasonable operating systems. And well, I don't know if the account risk OS is reasonable. But for example, I buy this USB missile launcher. Brilliant. Plug it in. Oh, not natively supported in the Linux. And it comes with some random rubbishy MFC control in the first designed in Windows 95. So that's unfortunate. It would be nice to be able to fire USB missiles how I want to do it. The reason you should know about USB as a hacker on computer stuff in my opinion is that everything is USB nowadays. And we can argue about whether it's a good thing or not, but it is. So if you have this mental block about looking at USB devices and how they work and what the data is, then you're going to have difficulty hacking a lot of devices and it's a real problem. This talk is a basic overview of how USB works from a layman's perspective. I do programming. I'm not a programmer. How to get started reverse engineering USB devices, simply simple ones. And how to get started. I'm not going to talk you all the way through it. Writing user space, driver code in Linux and also SX. And Windows. You can live USB works on Windows. It's not so pleasant there. But nearly every USB device you buy is supported on Windows, right? If you buy a USB device and it's not supported on Windows, the manufacturer has some serious questions to answer. So what this is not is like how to reverse engineer a serial stream format. So like, you know, once I can communicate with the device and it uses some ridiculous encrypted serial protocol. How do you sort that out? I mean, that's like that is that is elite stuff. I have no idea how it works. It's not how to write something for some super complicated, super fast, super high speed USB device, which is really difficult. Luckily, USB audio interfaces are class based. That's fine. And it's also not like a super deep look into how USB works because it's actually very complicated. It's also not about USB 3 because USB 3 changes quite a few things. So what is USB universal serial bus clues in the name? It to my mind and nothing none of this is official, right? But to my mind, it's basically a replacement for you arts and serial ports. And by replacement, I mean it's something that computer manufacturers put on there because it had a lot of it has a lot of new features and you can do a lot of stuff with it that were quite difficult with old style serial ports. It's faster than a serial port, but it doesn't have to be. There's no reason in principle you couldn't build an RS232 interface that worked at 50 megabits. The error correction would be pretty awful, but you could do it maybe. The problem with that is that for us as people wanting to actually look at our hardware and roughly know how it works, especially for me as a hardware guy, not a software person, is that you arts and serial is extremely convenient to hack. If you have an oscilloscope or a logic analyzer, you can reverse engineer the entire protocol layer of a serial device simply because you just put your probe on, right? Work out the board rate by counting how fast the pulses are, set another computer to that board rate, and it will talk to you, right? Serial device doesn't have any kind of, oh no, sorry sir, can't talk to you. A USB device doesn't. That's the main problem I found when starting to hack. The problem with a serial port is that you have to agree the board rate first. Nowadays, most serial devices are 115-200 board, but they aren't all, and you have to know that. If you set your receiving serial port to the wrong board rate or the wrong stop bit or whatever, wrong parity, what you get will be at best garbage at worst nothing. So that's one downside by which I mean really serial devices, RS232 devices and such, are not self-describing in any meaningful way. There is no way for the device to tell the host how fast it should be or what parameters I should use. And there's no easy device multiplexing. If I plug two serial devices onto the same serial port, unless they are specifically designed to be used that way and have some kind of arbitration scheme on the bus, you're just like driving two trains in opposite directions into each other, right? It's not going to work. USB obviously does. So USB, basically what is it? It's basically a differential pair, data plus data minus, for data signaling. USB 3 has other pairs as well. We won't get into that as I said. It's a fast differential pair, but it's literally just a pair of wires for data, just like a UART, except not just like a UART. But UART is one for transmit that way, one for transmit that way. USB is a differential pair which is half duplex, so a USB line can only ever transmit either that way or that way. At one time. But it's just a single data pair. The devices are connected in what's called a tiered start-upology, so you have one at the sensor and you plug several into that and you can plug several into that. And interestingly, this is one important thing I found about USB. All communications in USB, except for USB 3, are initiated by the host, right? Even if you have something like a mouse or keyboard, I'm going to hopefully show you this later, where you would expect that when I press the button on the keyboard, it's sending a signal to the computer, no, what's actually happening, because USB has this thing where we have a host and a device. Other class, working class, right? There is always a host and there is always a device. A device cannot do anything on its own, it has to be told what to do. Read into that what you like. But even on a keyboard, what is happening is the host is asking the keyboard, has he pressed the button yet? Has he or she pressed the button yet? And the keyboard says yes, it's Q or no, right? So that's basically how it works. USB devices are, to some extent, self-describing. So if I plug a keyboard into a USB port, the host knows that it's a keyboard, because the keyboard has told it that it's a keyboard, right? So there are these various terms used in relation to USB, low speed or full speed. Nowadays, there's no such thing as low speed USB devices anymore, really, but full speed USB means USB 1.1. That's in Linux, controlled by a driver called HCI. High speed is USB 2. That's EHCI, and super speed is USB 3, which is XHCI. The electrical interface, as I say, it looks very simple there. It's just a differential pair, and so you could look at that on a scope. It's not super-fast, you don't need to look at it, but the packet format is incredibly complicated. What I'm going to try and say to you guys today is that, luckily, it doesn't matter that the packet format is incredibly complicated because that is the bit that everyone agrees on. So when you're reverse-engineering something, what you're trying to find is the bit that everyone doesn't agree on, the bit that's vendor-specific or to do with that device. I wanted to spend a bit of time to kind of put this in perspective doing the VHS versus Betamax versus Firewire, because I think it's actually a very good analogy. USB is a tiered star configuration. Firewire was a tree configuration. If you've ever seen a Firewire device, most of them have two ports on, and that's because Firewire can be a tree configuration, you can daisy-chain them. USB, you can't. USB, as I said, the host initiates all communications. With Firewire, any node can initiate a communication. So with a Firewire device, like a DV camera, for example, Firewire is ideally suited to streaming video because your device can say, here's some video, have it, right? USB, that can't happen. USB can supply power. Brilliant. 5 volts, 500 mA. Firewire, if you implement the full spec, I've not tested a Firewire device for this, but it's 30 volts at 3 amps. So, yes. USB protocol is implemented in Thailand Software. Firewire is implemented in a nice, expensive, fast ASIC. It can do DMA transfers into your CPU, so there's a hideous security risk with Firewire, right? If you don't have that configured properly, someone can just plug a Firewire device into your Firewire controller and do DMAs straight into your CPU. So it's not great. USB is kind of packet-based, and Firewire is kind of stream-based. Those are the technical differences. But basically, why don't we have Firewire anymore? Anyone want to shout out? It's expensive, right? Why is it expensive? Exactly, right? So, to me, it's not like the VHS Betamax, because it wasn't decided by the Los Angeles entertainment industry, but it's like VHS Betamax in the sense that in some things, and for some applications, Firewire, you look at the spec and how it works, it's much better suited. If I want streaming data, it's not a question that Firewire was a better spec. Unfortunately, you had to pay licenses for every chip, and you had to have the chip. Unlucky Firewire. You will still find it in aircraft avionics buses, actually. So that was VHS Betamax. This is just a totally unsuitable comparison, but it's kind of interesting to me. Again, I say I'm not a software guy, so shoot me. USB has this hosting device thing, but it sends packets. It sends an thing called UBS, which is a USB request buffer. But Ethernet is also packets, right? USB, you can tear a load of devices together, and each device gets an address, gets a place you can look at it and point to it. Ethernet doesn't do that, of course, but Ethernet just has MAC addresses and Ethernet frames, but you can stick Novell IPX on top of your Ethernet, and give everything an address you can talk to it. USB, that address is baked in, right? The order you plug the device in, that's the order it gets the address. Ethernet, you can build whatever protocol you like on top of it, TCP, UDP, all this stuff. Wrote ARP request or whatever. USB has predefined what we call transfer types. In USB 2, there are basically three types. There are control, sorry, four types. There are control requests, bulk requests, isochronous requests and interrupt requests, and we'll talk about that in a bit, but there's not this whole you can build whatever kind of streaming protocol you want on top of USB. It's not like that. It's very different to Ethernet in that way, but it's the same in one sense, and that is, well, it's the same in two important senses. One is that it's kind of got the notion of a packet, so USB data moves around in lumps packets. The other thing is that you can use Wireshark and if you're going to take away five words from this talk, is that you can use Wireshark on USB. Or is that six words? I don't know. So, a USB device. If you buy a USB device, a well-designed USB device which almost doesn't exist, it has these various things that are in the standard called configurations, interfaces and endpoints, and it's kind of a hierarchy like this. This is all a very useful website called linux-usb.org which is useful if you want to know about USB, but if you want to write a USB driver, I suggest don't use it because that's how to write kernel drivers which is a bit different to what we're going to talk about. Configuration is an arrangement of interfaces. Most devices, by which I mean anything you want to attempt to hack as your first USB device have one. So, it's not too much of a problem, but a configuration could be, for example, I have a camera, that is also a USB Missile Launcher, but it can only do one at a time. Find me one and I'll believe it, more than one configuration. Only one configuration can be active at a time. So, what happens is you plug a device in, it describes itself to you and you say to it, give me configuration one almost always you'll say give me configuration one because there will only be one and it says, very well sir, here we go, here is configuration one. That configuration will give you a list of interfaces, mostly one interface, although things like multi sort of devices which do more than one thing might have two. So, for example, an FT-2232 USB to serial converter has two interfaces for the two separate serial ports. The most important unit of this is that bottom level, which is called endpoints. Endpoints are basically things that you can point at and either send data to or receive data from. And again, in contrast to network, sort of ethernet type networking, an endpoint can only receive or transmit, logically, right? So, if I have a device which receives data and transmits data, it must have two endpoints, one for in, one for out, at least two. Furthermore, an endpoint can only do one type of transfer, and we're about to talk about that, but I said there were several types of transfer. How does a USB device self-describe? It uses a thing called a descriptor. That's, you know, kind of an obvious name, but basically what happens is your host can request a descriptor through endpoint zero. All devices have an endpoint zero, which just means the thing you ask for descriptors rather than the thing that actually does any work. So, basically, if we're in Linux, for example, my friend is LSUSB. I type LSUSB, it tells me about USB devices. As you can see, I have a few interesting devices in this, one, for example, Ericsson Business Mobile Network, so I have a one card in this laptop, and that's connected over the USB device, USB bus. What we're going to look at today, because I haven't got the camera working, is the Logitech Ink Unifying Receiver. The interesting thing to look at this is if you look at that Logitech Ink line, the second line from the bottom there, on the left it's got bus 002 device 009. So, the bus number is determined by which USB bus chip is connected to, so that's a physical location. The device is assigned by the software stack and there's no specified order, but in Linux it is almost always assigned in plugging in order, so device 10 is the one you plugged in after device 9, right? Etc. Those are in decimal, obviously, because none of them are above 10, so it wouldn't matter anyway, but the interesting thing next it gives you the ID. These two numbers, for the Logitech it's 046D colon C52B, that number is obviously in hex. Quite often you come across with only digits, so you don't know, but those are called the ID vendor and the ID product. So, all Logitech devices will have 046D and this particular product will have C52B. Now, the reason I'm emphasizing this is that those two numbers are very important, because it is how the USB stack in your operating system decides what driver to load and how to talk to the device. If you do LSUSB-V you get quite a lot more information. So, this Logitech receiver, for example, we can see ID vendor's Logitech unifying receiver. Then it gives us a configuration descriptor. How much power it can use. That's not accurate. That's just how much power that can be programmed in by the manufacturer, so you can believe it or not. Now, next I'm going to talk about the class there, human interface device, protocol, keyboard, but basically this descriptor tells you how the device describes itself. It's got an endpoint there, endpoint 2 in, so that's where the input comes in. It's got another endpoint, endpoint 3, et cetera, et cetera. So, that's your basic tool for looking at USB devices in Linux. That's an example of what descriptor looks like. So, I said that endpoints do transfers, or you transfer to and from them. Each endpoint can only have one type of transfer, and there are four types of transfers. Interrupt transfers, which are guaranteed amount of bandwidth and reliable. So, the USB protocol has this very complicated negotiation of how much bandwidth something is using, has very complicated error checking, none of which I'm going into or I'm going to go into, but it's there. So, if you're designing your own USB device, do not, but a CRC in your data field is just wasted, right? Like the USB stack does all that for you if you use bulk transfers. But anyway, we've got interrupt transfers, which are like kind of keyboards and mice and gamepads and stuff, where you're going to pull it very often, it's going to tell you events. You have isochronous transfers, which are they are, they're not interrupt transfers, and since you're not going to pull them so often, they're going to have bigger amounts of data. And there is no error correction. It's kind of like UDP packets in a sort of way to me as the layman. And as the live USB driver writer, that's all you need to know. Very rarely will you be able to successfully write an isochronous driver with live USB, so no need to worry about it. It's too time sensitive. Control transfers and bulk transfers are generally what we're going to talk about, because that's what your normal off-the-shelf random Chinese device, which they've just slapped together for $10, actually uses to move data around, right? The control transfers are things like turn this light on, turn this light off via a missile. Bulk transfers are things like I'm sending you a picture, I've taken a picture, here's a load of serial data, here is the program to cut out laser cutter thing with. Each endpoint on this sports one transfer try it. Interrupt transfer is a misnomer USB can't do interrupts unlike Firewire. But, yes, interrupt means I am pulling you and asking you, so it's actually not interrupt, it's actually pulling. Okay, but it's called an interrupt anyway. The pulling rate is entirely up to the OS, so yeah. All clear? Great. One of the best things about USB is that it has these things called device classes, so I said those descriptors. There are a set of agreed on device classes, meaning a lot of universal serial buses universal, it's going to be used for a lot of standard things. So they all sat down and agreed on a lot of these, you can see they have to go into hex, so there's more than 10, right? Zero unspecified. Great, that's the worst one, you don't want one of those. Okay, so we have things like audio, keyboards, HID. HID is a bit random because HID means human interface device, which can mean keyboard or mouse, or it can mean just device that will spit some random data out of me that I don't know how it looks, like a steam controller, for example. I should have brought that along actually. Anyway, this is all fine. If your device is any one of these classes, you do not need to worry about anything I'm about to tell you. Anything, because some smart, clever and brilliant guy at Linux kernel has written a driver that exposes it into the Linux file system somehow. Even if it's just a HID device, it'll be in the file system. You do not need to worry about this. What you do need to worry about where we proceed is that bottom one, vendor specific, right? Meaning any other. And at this point, when you can buy USB coffee warmer or like a, you know, USB Kenwood mixer or whatever, that is becoming a very large amount of things, which will never be USB. There will never be, like, you know, kitchen equipment, USB device class. So don't worry about it. So basically what I'm about to tell you is what you do when you want to make a USB device work that has a vendor specific class code. In Linux, the USB stack looks like this. There's a HCD which is a human control device driver stack which talks directly to the hardware. There's a set, a layer of things called USB core services which are in the kernel and very scary and don't mess with them. And then there are sets of class drivers which are in user space but they talk directly to the kernel. So things like webcams and stuff like that, UVC video and all that stuff is all at that level. On the other side there's a thing called USB DevFS, which is a bit in the proc file system exposed to you which you can directly pork and prod USB devices with. And what we're going to talk about is, so in the old days, if you wanted to write a USB driver in, you could either write it in kernel space, scary, or you could write it in user space, not so scary but you have to mess around with this file system layer. There's now a thing called libUSB, which is what we're going to talk about and that's how it works. There are two scenarios now. You have a USB device which is vendor specific and you're going to have to mess around with it to make it work in any meaningful way. There are two choices, either we do write a driver or we do not. There is no try. So to write a driver you should really only consider if it's vendor specific. It's not vendor specific, it should be done by the class driver and if it's not, complain to your local Linux kernel hacker. The case for this is when it likely does simple control transfers, your USB missile launches right, that is probably just control transfers. So telling it to turn left and right that'll be very simple. We'll go through that. Or it does basic bulk transfers and we'll get into this later. Things like USB temperature loggers, your USB smart energy meter or whatever, likely are doing bulk transfers to spit a load of data at you that you could have just as easily done over a serial port. Those are the cases. Or that's true but the software you've got that's working is just totally rubbish and the definition of unacceptable to me includes only works on windows obviously. Or works on wine but it was written in windows 95 or you have to use lab view or my half-baked GUI will be better than their half-baked GUI but I would caution you that that's never true. No matter how bad theirs is if you don't spend a lot of time when yours will be worse. When not to do it is if it's actually just a serial device or CDC device or TMC which is test measurement class which they should use more but they don't. In those cases you should just talk to it as though it's a serial device. That's what the USB stack will handle all that for you and then you just have to reverse engineer the actual serial protocol. We're back in the old days. Or if you have something that's super fast there's time guaranteed, the error checking is going to be too slow it's going to drop a load of packets on the floor if you do it through user space needs a lot of isochronous transfers you're going to have to write a kernel driver because you have no idea how to do that so that's that or you can't be bothered but the point of this talk is that for something that simple you should be bothered because it's easy and I'm going to show you how five simple steps no actually three steps but I'm going to flash them out one get the device working in a virtual machine I use virtual box okay shoot me whatever whatever you want that has USB device passed through two you can use wire shark to sniff USB packets I can't stress that enough so we don't even have to plug in the oscilloscope right you get the device working in your virtual machine the virtual machine thinks it's talking to the USB device you are sat over here you can plug in wire shark to grab the packets off that USB bus right and display them to you in a format that you can look at and once you can look at the packets and you see I don't mean look at in the sense of here's all this random error correction stuff I mean look at as in tell me exactly what it's actually doing and once you can do that you can start to reverse engineer it three write a program using LibUSB or PiUSB which on Linux is a wrapper for LibUSB very nice one to drive the device however you want right so step one LSUSB I've told you that already that is the first thing you need to do once you want to reverse engineer device is not what it's ID vendor and ID product is and those numbers you can get from LSUSB right step two Udev marvelous everyone written Udev rules before yeah not quite as bad as it seems right nine times out of ten the Udev rule you will want to write is something like this one subsystem double equal USB that says if the device is USB device aturas ID vendor is the vendor aturas ID product is the product now we know which device it is and then you say mode single equals zero six six six give me right access to it and read access to it group equal users now if you use an operating system like Ubuntu or something which is not SUSE which is or Debian which is the only two I know about really then this might be slightly different but that's how you do it so don't be afraid of Udev rules it's actually not too bad and of course the ArchWiki has a page on it once you've written a new Udev rule no one saw my password there right of course not once you've written a Udev rule you have to reload Udev which on SUSE you do like that Udev ADM control dash dash reload dash rules so that's step two two fifth of the way there now step three is a bit more involved step three I have the camera over there I was going to show you that I reverse engineered a few months ago but I can't find a 12 volt power supply so I did have one but I've lost it so I'm going to show you how to reverse engineer a USB keyboard which already works but I give you the steps use virtual box use virtual box to install Windows ouch this might hit me with a you must upgrade to Windows 10 message in which case I apologize in advance uh we're going to watch Windows boot up now no we're not really um so what we are I'm going to talk over it though uh you you you boot up Windows and you need to install the if you're using virtual box you need to install the extension package from uh from the thing from the uh the website but what you can do with this is you can use this button at the bottom USB pass through to pass through a USB device to the virtual machine what that means is is that at the level of the USB stack it will just be giving the packet straight to the virtual machine so the virtual machine isn't like being it isn't being interpreted the virtual machine sees it as USB now this doesn't work so well for graphics cards as anyone has attempted to game on uh Windows through Linux with GPU pass through will tell you um but it works incredibly well for USB devices and specifically for USB two devices USB three doesn't quite work properly um so if I just click that this uh notice I'm pressing a button on this keyboard uh hang on I'm pressing a button on this keyboard is not being accepted by the terminal anymore because this keyboard is now connected to the windows virtual machine uh at this point I would say that you um install the rubbishy vendor software I was about to show you one of the most that is literally the first time I've ever seen this message I'm quite annoyed um yes I was literally about to show you one of the most ridiculously disgusting vendor GUIs for anything ever invented uh which was the uh the other I'm going to show you it anyway just yeah yeah yeah I mean uh it's not that bad but I mean I've seen worse but come on like here we go here we go that's probably not even going to load no nope yeah all right you can tell I don't boot this virtual machine up that often other than to other than to mess around with USB devices it's coming it's coming come on windows oh hello look so what it does is it pops up a dialog box saying another application is still running please reinstall um I trust you it's pretty bad it's called A plus interactive software come on um anyway the point is that this keyboard which wasn't working in the terminal before is also not working now um hang on shouldn't switch devices in the last last minute in the demo oh no it's coming ah look at it it's so bad what is this so it seems like I haven't installed the USB logitech driver on windows I do apologize but anyway the point is that when you click this button live demos never work right so I'm not going to apologize too profusely about it oh devices ready here we go the next part of the demonstration is still doable um please have mercy look so point number one is you can use wire shark in USB packets point number two is never use windows right um but the point is that if you fiddle around with this for a bit I promise you like super pinky promise that you can get a USB device pass through working and windows will think it is connected to that device and it will work as if it's on windows right and then what I did with that camera over there as you plugged it in you make it work as if it's on windows you run your rubbishy A plus uh interactive software and uh then your device is now working in windows it doesn't know that you're about to spy on it which is our next step for which luckily I don't need windows anymore I I'm sorry about that I had to change devices at the last minute and uh that didn't work but that's basically the idea is get it running through USB pass through in a virtual machine step step four the fun and interesting and good part which will work I promise is use wire shark so install wire shark shark using apt get it whatever it is you use um or zipper for us susa fork and then step one mod probe usb mon so wire shark have written a kernel module called usb mon which essentially goes into the uh the the linux kernel stack plugs in a module which listens to all usb traffic and gives you access to it in wire shark right so step one mod probe usb mon right I am not a hacker but start wire shark ask for the root password because you know it's important um so if you've been to many reverse engineering talks about network stuff you'll have seen slash be familiar with wire shark um but once you've mod probed that usb mon I click here to start a new uh a new packet capture oh no I click here to select an interface um and you see I've got these interfaces usb mon one usb mon two and usb mon three those correspond to usb buses in my system so I go back to my trusty uh ls usb I am going to look at our logitech unifying receiver which is on bus 002 which means I want usb mon two start now see what this is telling me this is telling I'm sorry I don't know how to make the text any bigger in that but you can sort of see what's happening is usb packets are coming in we have a keyboard connected the keyboard uh what's happening here is the host is asking for usb interrupt in packets and the keyboard is sending it usb interrupt in packets saying no I haven't pressed the key oh now you've pressed the key now you've pressed a different key now you've pressed another key right um the problem is if you have 10 usb devices connected on that bus they will all come through usb mon you can use the wire shark filtering rules what I tend to do is this one um I look up the address logitech unifying receiver is device 11 and then just keep on even working come on everything is going wrong like the batteries are not even I tested this literally 20 minutes ago not like an hour and 20 minutes ago but come on man you should never do this oh hello okay but you see now it's a different usb device so I have to look again so now it is device 12 on bus 2 man this is like a good this is a good session right uh thank you so so what's happening is our wire shark is asking for interrupts from the keyboard the keyboard is mostly saying no no no no but what you can notice is that it's not quite polling it's not quite time polling what's happening is you can set a time out for how long the response is so the host has to initiate communications but it can say send me a reply uh you have up to 10 seconds to do so or something like that so what's happening is the host is getting the response from the keyboard and immediately sending out another interrupt packet right and that's how multi key press keyboards works it'll send one interrupt packet containing multiple key information uh right but you can see what's happened there is the keyboard just replied and interrupt um so once you have your filter set up which I've now wrecked because I was typing stuff um let's look at a packet right so I'm looking at this packet this packet have highlighted here is the host saying to the device send me an interrupt in if you expand that bottom bit there you can see this is the important bit the first thing you need to know when reverse engineering write your own USB devices is what endpoints do what as you can see in this keyboard it says here endpoint 0x 8 3 direction in now endpoints are numbered systematically so 0x 8 3 is always an in endpoint doing uh interrupt transfers and that's part of that how it works so so um but 0x 8 that means uh interrupt in uh or in that means in sorry and the three might just is just a third end point um so this keyboard inexplicably has three endpoints probably because one's the mouse and one's a keyboard and then it has the another one for some reason um so that's so when you write your notebook down how I'm going to reverse engineer this USB device you basically play with the device through either your windows virtual machine or the buttons or whatever on this you watch what happens in the USB logs you need to know what endpoints do what so 0x 8 3 is where my data is coming from the keyboard and then you see the reply to this packet which uh Wireshark can tell us all you're interested in in the reply normally is that bottom bit which is called the left over capture data which is how much data we got back and what was it so we have binary data there none of it's principal so that's printable characters on the right but to 0 0 0 0 0 0 and then the fun begins right I've got you to this stage and then you work out what your device is doing obviously you have a brain and know something about the device for example I'm going to talk you through several USB devices I reverse engineered using only this technique of just looking at what the data is what endpoints is going in and how we got around working out what the data actually was so this thing this thing is an other media CP one five five terror of classroom kids all over the world presumably it's actually quite useful I picked mine up for 40 pounds discovered it only had that hideous a plus other media GUI on windows and Ubuntu support for Ubuntu 9.04 only yes it had its own kernel module compiled against kernel 2.6 point whatever it was nothing else but luckily this camera although it's a camera and I said we shouldn't really do cameras in user space because cameras are shooting images it's very low frame rate and what it's actually doing is it is compressing the thing to a fully formed JPEG inside the camera and it dumps it to you over a bulk endpoint as literally the contents of a JPEG file and you can tell that because the bulk data in there just says JFIF which is a JPEG header at the start of it right so actually within about I mean it was overall getting the holding to work was quite difficult because it has a weird thing about how it splits the data up into packets but getting to the stage of I know roughly how this device work took me about 15 minutes in Wireshark because every time a picture is coming in I get this thing that has a steaming JPEG header in plain text in the bulk transfer and at that point we know how it works right so then you do things like what happens when I click start oh it sends this control that control and the other control so then I write my Python script to send those three controls see if it starts capturing it does okay there we go right and I look at the windows capture utility and I see what happens what the images come back in oh it's just raw JPEGs in bulk transfer write a Python script that grabs those bulk transfers and cut it straight out to a dot JPEG file that's the picture okay that's I mean and it turns out that that's actually quite a complicated USB device it has like 150 control control packets it can zoom in it can turn the lights on and off it can focus it can freeze frame all this stuff and all you do is you just click the button in the windows software one USB packet comes in we know what it is it's that simple so I wish I could show you that but maybe I'll find a 12 volt adapter tomorrow and you can come and watch if you want some more advice on this okay here's another one I had interesting with recently this is a new port 2936R unless you're really in the business of measuring absolute radiometry on detectors you won't be interested in spending five and a half grand on one of these but there's kind of an interesting point to make here that this has a smoking gun on the back panel where a USB plug right next to a serial plug okay now in the manual they'll give you the serial commands um so unless they're very very like under under occupied and have a load of engineers with a lot of spare time they are not going to seriously properly design all the hundreds of functions in this device as a proper USB device they are just going to have a USB serial link which sends the serial commands over it this is very common the problem with this particular device and about a hundred others I could name most of which are scientific or medical instrumentation is that rather than doing the sensible thing of admitting that and giving you a USB serial adapter they still do their vendor specific thing and give you a crappy DLL that just has two functions in which basically just send data over the USB bulk endpoint this is extremely common and probably it's how a lot of these type of device temperature logging humidity logging all the kind of data loggers actually work they should just be USB to serial converters but they aren't but actually they are all they do is send you serial data as if they had a serial port over a bulk endpoint that is a huge number of devices and this one was exactly like that thanks there are actually specific classes for this TTY class USB device class which is like your serial proper USB to serial converters and TMC class which is test measurement class this is a test and measurement instrument it should be a USB TMC class it isn't because they are convinced that them giving you a 4k Windows DLL gives them some massive value add but it doesn't anyway what I'm saying is especially if you have a device that also has a serial port that is 99% certainly what it's going to do this you have never seen because there are only 10 in the world they are built in a shed in Northampton there's no price because it depends on you know how many holidays they want to take that year but interestingly even super idiotic bespoke stuff like this that costs in excess of 70 grand per unit is based on really really rubbish little Chinese chips that they've imported right and those little Chinese chips are based on this is very similar to like the FX2 chip actually it's not the FX2 chip because of course it isn't but it's like the FX2 chip less said about doing this the better this took me months of my life and then didn't get it finished but I was still using the same technique and I got it almost work so like that's I overstepped with this one but still however exotic, esoteric and stupid your device is it's probably pretty easy to reverse engineer this one wasn't quite that easy but most of it I had a couple of other notable examples did I not even put the laser cutter in oh there it is laser cutter we have MK Hackspace and LS3020 Chinese laser cutter which is a thing of beauty we bought it from Reading I believe now I noticed I looked up because of course it only works on Windows in software that's basically in Chinese but with English characters and like I which is you know not offensive I mean like I would find it offensive to have to translate all my software into foreign language right because people can't be bothered to learn mine so I don't blame the Chinese for that please don't get me wrong I'm just saying it's pretty bad to use so I looked on the internet for people who tried to reverse engineer this and I noticed that the incredible guys at London Hackspace had done some effort in reverse engineering this this software inexplicably also uses a hardware iLockDongle right so you have like a five grand laser cutter this software is useless without a laser cutter and yet you still you also need a little iLockDongle great now those what the guys there had done is attempted to like convince to hack to crack the software basically like binary reverse the software and convince it to launch without the iLockDongle that would be step one but it turns out that if you just plug this thing in through Wireshark and print something out I didn't have the laser turned on because this would have cost a lot in Perspex but it just literally sends a string of what is almost unadulterated normal HPGL plotting language over a USB bulk endpoint and the printer then cuts that out what an amazing world we live in right so the software on the computer is not even driving the motors it just sends it a literal plain text string in HPGL plotting language the difficulty is it's not quite in HPGL plotting language and that's taken us a while but like that again to get to that stage was about half an hour's work in Wireshark by that stage we knew that it was basically you could send it HPGL strings and that's a fairly standard plotting language right it's similar to Gerber not quite the same so I wouldn't say we've totally reversed engineered this but we're at a stage where if you wanted me to cut out a hexagon using only a Python script on Linux I could do it right so good the last thing I'm going to talk about is a brief introduction to LibUSB so LibUSB is a C library I'm personally more of a C++ person but you can very easily write your RAII nice little classes around it it's kind of set up that way actually Python has two sets of bindings so LibUSB one is a C types binding which is just the C API in Python I recommend you don't use that this thing called PyUSB which has more Pythonic way of doing it let's see if this clicking this link works so LibUSB for those has exceptionally good documentation you're really getting started it has two separate APIs LibUSB it has a synchronous API and the asynchronous API now doing asynchronous programming in C is a tad annoying the synchronous one will work for a lot of things your USB missile launcher only almost certainly can use the synchronous API which is very simple and the synchronous API consists of three calls that's it you have to do a couple of calls to initialize the library you go through the tutorial it tells you that you get a thing called a context which you do for a lot of these C type libraries so you get a context, you open a device there's a nice function called open device by vid and pid which it says not to use in real code but I do and it's fine the only disadvantage if you have like five layers of codes plugged in it will always give you the first one big disadvantage well it might be one day but anyway so there's a nice little function somewhere else called find by d that opens the device gives you a handle once you get that handle there's these three functions they're just normal C functions they're not hideously nasty allocate your own memory and you know clench for a segfault kind of stuff it's it's like you give it the device handle you give it the the request type which is in in the control request once something is a control request it has a number called the request type and each separate function of the device will have a different request type so for example your usb missile launcher will have left right up down fire and those will be five different request types wire shark tells you those and you know the request type is this so you press left on the thing wire shark will tell you what left is etc etc so if you wanted to do that one call live usb device live usb control transfer you give it the handle request type the request which is the data associated with the request which sometimes is no data at all and and there's a thing called the value in the index which are not used very often by most devices but those are like sub requests so like you can have huge like hierarchies of functions in some devices the camera for example has a lot of them and you can give it this pointer to a data which you've allocated actually so this is why I like doing it in C++ because you can just wrap this up in a you know using a standard vector or something but that is the reply and put the data in there and so these are not too difficult to use there's a huge suite of examples on the live usb website and the pie usb website pie usb is is simpler if you're python guy I guess but I often like I like to write stuff like this in C++ because or C because then I can always C types it into python or you know every language has a C foreign function interface just about unless it's something really kind of look look I wouldn't use a language it doesn't have a C foreign function it's okay so so like you know I would say that if you're going to write something like I'm going to write live usb missile launcher and publish it to the community it should probably be written in C in live usb but you know you do whatever you like but what I'm saying is there's these three calls live usb control transfer live usb bulk transfer and live usb interrupt transfer I'm not that hard to get your head around they're not any harder than the open cv c api and remember that was awful but those three calls just do transfers each called as a transfer this is the synchronous api so it blocks there's an asynchronous api it's a bit more complicated where you have callbacks but underneath this is implemented using their own asynchronous api so I would recommend that you just start off with the three live usb synchronous calls if you're reverse engineering usb device use wire shark find out what the control transfers and the bulk transfers are write it down notebook is help a notebook is helpful and then use these three calls and just type the calls in order it will blast them out the usb bus in order live usb handles all the details of the usb stack the descriptors configuration everything like that it's all handled for you and you only need these three calls and so you can write 100 line c program we'll do that I will show you my camera program I don't have the camera plugged in so I can't actually demonstrate that it actually works but it does this is in the pie usb rather than so this is how I wrote the basic script for capturing from that camera over there just the python class and you see this is using pie usb there's this nice call here usb.co.find that just I said I've worked I know what the id vendor id product is I give it that it gives me back an open device job done no worries I worked out what the endpoints were from from wire shark 88 and 82 and I discovered that broadly speaking it did three different sort of kinds of requests these three control transfers and to start capturing I just do this control transfer and like that's how simple the code is it's just do a dot control transfer to this point with this value and also this function called get bulk image transfer which is a little bit more complicated but not too much it just uses three usb bulk in calls and that just dumps out a jpeg image from the camera and this took me about two days of effort to write and that included learning how to use wire shark so you know if I can do it everyone can and so I'll leave you on that please go it buy all the rubbish chinese usb devices that you're interested in and hack together programs on linux using live usb to make them work because they can be done and even I can do it so thanks very much