TippingPoint Digital Vaccine Laboratories
DID YOU KNOW... The DVLabs research team discovered 10 unique Adobe Shockwave vulnerabilities during October and November of 2010.

Python Interfacing a USB Missile Launcher

I watch Woot on pretty much a daily basis and as a result I frequently end up purchasing toys that I really don't need. Most recently I picked up this silly pair of USB Missile Launchers for just under 40$ shipped:



I finally found some free time yesterday to open up the package and plug them in. The hardware is coupled with a simple GUI controller written in Delphi (MissileLauncher.exe) and a USB Human Interface Device (HID) interface written in C++ (USBHID.dll). The toys lost their allure within minutes of harassing my team with a barrage of soft missile shots. That same night I thought I would be able to extend the fun factor by coding up a programmatic interface to the launchers in Python. This blog is about that process.

It's obvious that the bundled DLL is the glue between the GUI and the USB interface. Throwing USBHID.dll into the IDA Pro Disassembler and examining the exports reveals 7 entries, the most interesting sounding of which is OpenHID(). Examining the imports shows dependencies on the Microsoft system DLLs HID.dll and SetupAPI.dll. USBHID.dll is basically a simplified wrapper on top of the Microsoft API. The next step is to take a look at how it is referenced from the GUI. Loading MissileLauncher.exe into IDA and examining the imports unfortunately shows no reference to USBHID.dll. The library and function pointers must be resolved dynamically via LoadLibrary() and GetProcAddress(). Time to examine some cross-references. Hit 'Shift-F12' to pull up the strings window then 'Alt+t' to search for USBHID.dll, enter to follow and you find:
.data:0048790C     LibFileName db 'USBHID.dll',0
Hit 'x' to pull up the cross-references to the string and you come across the following snippet of code:
.text:00403830 030     xor edx, edx
.text:00403832 030     mov dword_48E510, edx
.text:00403838 030     mov ecx, [ebp+table]
.text:0040383B 030     mov dword ptr [ecx+74h], 0FFFFFFFFh
.text:00403842 030     push offset LibFileName      ; "USBHID.dll"
.text:00403847 034     call LoadLibraryA
.text:0040384C 030     mov dword_48E514, eax
.text:00403851 030     cmp dword_48E514, 0
.text:00403858 030     jz  short loc_40386F
.text:0040385A 030     push offset ProcName         ; "OpenHID"
.text:0040385F 034     push dword_48E514            ; hModule
.text:00403865 038     call GetProcAddress
.text:0040386A 030     mov dword_48E510, eax
So we have EDX=0 at the top, moved into a global DWORD variable @48E510. Next we see the address of our string being pushed to LoadLibrary() and subsequently the return value transferred from EAX into a global DWORD variable @48E514, this is the handle to the loaded DLL. An error check is made to ensure the library exists then the resolved handle and the string "OpenHID", the relevant function to resolve, is pushed to GetProcAddress(). The resolved function pointer is transferred from EAX into a global DWORD variable @48E510. We can press 'n' on both of these global variables to rename them to say 'h_USBHID' and 'OpenHID' respectively. Now let's find out where OpenHID is called from, again examine cross-references by hitting 'x' when the cursor is on top of 'OpenHID'. There are 4 references. Two references from the above snippet which are assigning the variable and two CALL references from the function @00403B64. Here is the first:
.text:00403B64 000     push ebp
.text:00403B65 004     mov ebp, esp
.text:00403B67 004     mov eax, [ebp+arg_0]
.text:00403B6A 004     cmp dword ptr [eax+74h], 0FFFFFFFFh
.text:00403B6E 004     jnz short loc_403B88
.text:00403B70 004     push 1
.text:00403B72 008     push 701h
.text:00403B77 00C     push 0A81h
.text:00403B7C 010     call OpenHID
.text:00403B82 004     mov edx, [ebp+arg_0]
.text:00403B85 004     mov [edx+74h], eax
.text:00403B88
.text:00403B88     loc_403B88:        
OpenHID() takes three arguments and is being called here like so:
if (eax74 == 0x0FFFFFFFF)
{
    eax74 = OpenHID(0x0A81, 0x0701, 1);
}
The first argument is the HID Vendor ID (VID), 0x0A81. The second argument is the HID Product ID (PID), 0x0701. The code here opens a handle to the USB Missile Launcher HID if it hasn't already been done. Just a few lines later in the deadlisting we see a WriteFile() operation on the opened handle:
.text:00403B88 004     mov ecx, [ebp+arg_0]
.text:00403B8B 004     mov byte ptr [ecx+46h], 0
.text:00403B8F 004     mov eax, [ebp+arg_0]
.text:00403B92 004     mov edx, [eax+68h]
.text:00403B95 004     or  byte ptr [edx], 40h
.text:00403B98 004     push 0                       ; lpOverlapped
.text:00403B9A 008     mov ecx, [ebp+arg_0]
.text:00403B9D 008     add ecx, 6Ch
.text:00403BA0 008     push ecx                     ; lpNumberOfBytesWritten
.text:00403BA1 00C     push 2                       ; nNumberOfBytesToWrite
.text:00403BA3 010     mov eax, [ebp+arg_0]
.text:00403BA6 010     add eax, 45h
.text:00403BA9 010     push eax                     ; lpBuffer
.text:00403BAA 014     mov edx, [ebp+arg_0]
.text:00403BAD 014     push dword ptr [edx+74h]     ; hFile
.text:00403BB0 018     call WriteFile
The function we are examining takes a single argument, which is a pointer to a structure which contains the data to be written at offset 0x45. The length of the data is 2, the value of the nNumberOfBytesToWrite argument to WriteFile(). At this point we know that we can easily open a handle to the USB Missile Launcher via USBHID.OpenHID() and then we can use WriteFile() to write data to it and likely ReadFile() to read data back. The next step is to figure out the protocol and there are a number of ways we can go about doing this. One method is to use USB sniffing software such as  SniffUSB. Here is a screenshot of SniffUSB in action:



Note that in this screenshot I've already installed the filter control on the HID specific to the USB Missile Launcher. The red arrows highlight the VID/PID values we found earlier within MissileLauncher.exe from the call to OpenHID(). Another way to determine which VID/PID combination maps to the specific HID you are looking for is to unplug the device, hit refresh, then plug it back, hit refresh and see what new row pops up. Once the filter control is installed on your target HID, you must unplug/replug to activate it then you can start interacting with the MissileLauncher.exe GUI and examine the data going across from the UsbSnoop.log file in your Windows directory.

I took a different approach. I decided to 'sniff' the protocol via debugger hooks on ReadFile() / WriteFile(). Load MissileLauncher.exe into OllyDbg and hit F9 to let the program run and the GUI start. Once the GUI is running pull up the modules list with 'Alt-e', select kernel32 and hit 'Ctrl-n' to pull up its list of contained names. Start typing out "writefile" to pull up the appropriate entry then hit 'Shift-F4' to set a condition log breakpoint. A dialogue box appears, for the row labeled "Log function arguments", select the "Always" column radio control. This is a pretty neat feature of OllyDbg by the way, it won't work for any API, just the ones OllyDbg knows about. Repeat the process for "readfile". Hit 'Alt+l' to bring up the log window then hit a button in the MissileLauncher.exe GUI and you should receive log output resembling the following:
7C810E17   CALL to WriteFile from MissileL.00403BB0
             hFile = 000001A8 (window)
             Buffer = 00B6395D
             nBytesToWrite = 2
             pBytesWritten = 00B63984
             pOverlapped = NULL
7C810E17   CALL to WriteFile from MissileL.00404248
             hFile = 000001A8 (window)
             Buffer = 00B6395D
             nBytesToWrite = 2
             pBytesWritten = 00B63984
             pOverlapped = NULL
7C801812   CALL to ReadFile from MissileL.00404265
             hFile = 000001A8 (window)
             Buffer = 00B63954
             BytesToRead = 2
             pBytesRead = 00B63984
             pOverlapped = NULL
7C810E17   CALL to WriteFile from MissileL.004042D0
             hFile = 000001A8 (window)
             Buffer = 00B6395D
             nBytesToWrite = 2
             pBytesWritten = 00B63984
             pOverlapped = NULL
7C810E17   CALL to WriteFile from MissileL.00404316
             hFile = 000001A8 (window)
             Buffer = 00B6395D
             nBytesToWrite = 2
             pBytesWritten = 00B63984
             pOverlapped = NULL
7C801812   CALL to ReadFile from MissileL.0040433A
             hFile = 000001A8 (window)
             Buffer = 00B63954
             BytesToRead = 2
             pBytesRead = 00B63984
             pOverlapped = NULL
7C810E17   CALL to WriteFile from MissileL.00404357
             hFile = 000001A8 (window)
             Buffer = 00B6395D
             nBytesToWrite = 2
             pBytesWritten = 00B63984
             pOverlapped = NULL
7C801812   CALL to ReadFile from MissileL.00404374
             hFile = 000001A8 (window)
             Buffer = 00B63954
             BytesToRead = 2
             pBytesRead = 00B63984
             pOverlapped = NULL
7C810E17   CALL to WriteFile from MissileL.0040453F
             hFile = 000001A8 (window)
             Buffer = 00B6395D
             nBytesToWrite = 2
             pBytesWritten = 00B63984
             pOverlapped = NULL
Let's take this one step further and extract the 2-byte data value being written to the HID handle by extending the conditional log breakpoint on WriteFile. Press 'Alt+b' to bring up the breakpoints window, next drag out the 'Address' column with the mouse to reveal the DLL and API names in addition to the address (there is a lot of "hidden" data like this in various OllyDbg columns). Right click the breakpoint for WriteFile and select "Edit condition", the dialogue from earlier should pop back up. In the second row, for explanation put something like "buffer" and for expression enter "word ptr [[esp+8]]", this will dereference and display the 2-bytes being written from the second argument of WriteFile(). Next for the row that reads "Log value of expression", select the "Always" column radio control. Now when we interact with the MissileLauncher.exe GUI we should get log entries like this in addition to the ReadFile() / WriteFile() call / argument logs:
7C810E17     COND: buffer = 4000
7C810E17     COND: buffer = 4000
7C810E17     COND: buffer = 0800
7C810E17     COND: buffer = 4000
7C810E17     COND: buffer = 4000
7C810E17     COND: buffer = 2000
There are two steps left for decoding the protocol now. One we have to hit each button in the MissileLauncher.exe GUI and take note of the data being written to the HID handle and two, we have to pay attention to the order of reads and writes on the handle and mimick it in our own program. Running through these steps we can conclude the following protocol (from my finished Python script, to be linked later):
self.cmd_map    = \
{
    "down"  : 0x01,
    "up"    : 0x02,
    "left"  : 0x04,
    "right" : 0x08,
    "fire"  : 0x10,
    "stop"  : 0x20,
    "start" : 0x40,
}
The 'start' and 'stop' commands are control codes for putting the device into and out of action. Taking note of the read / write order we conclude the following general pattern:
  1. write(start)
  2. read()
  3. write(command)
  4. loop write(start) / read() while we want command to execute
  5. write(stop)
No we're ready to start coding some Python. We'll rely on the ctypes library to call USBHID.OpenHID(), kernel32.ReadFile() and kernel32.WriteFile(). The kernel32 routines are exposed through ctypes.windll, for OpenHID() we can load the library and call the function like so:
self.hid        = ctypes.WinDLL(r"C:\Program Files\USB Missile Launcher\usbhid.dll")
self.launcher   = self.hid.OpenHID(0x0a81, 0x701, 1)
The various commands being written to the HID handle must be in the appropriate endianess (thanks Aaron) and stored in a ctypes string buffer, like so:
start   = ctypes.create_string_buffer(struct.pack(">h", self.cmd_map["start"]))
command = ctypes.create_string_buffer(struct.pack(">h", self.cmd_map[cmd.lower()]))
stop    = ctypes.create_string_buffer(struct.pack(">h", self.cmd_map["stop"]))
The rest is up to your imagination. You can download my code, ped_missile.py, which implements a class for controlling the USB Missile Launcher as well as exposes three interfaces on top of that class. A command line interface, a socket server (protected by a password hardcoded on line 264) and a simple web interface. The web interface is fun for usage through the iPhone in conjunction with the 8$ application AirCam from Senstic.

One interesting thing is that we have a lot more granular control of the turret movement now then we did with the original GUI. I wrote two simple loops to count the number of possible horizontal and vertical ticks and the results were 947 horizontal and 91 vertical versus 54 and 10 from the original GUI respectively. Granular control allows you to slowly and quietly reposition the turret for stealthy attacks. I also started writing a class function missile.reset() to center the device automatically but haven't finished it quite yet. Take a look at the source for further information. Everything should be fairly self explanatory.

I'll conclude with an action video put together with the help of my teammates Aaron, Ali, Cameron and Cody:

Tags:
Published On: 2009-02-12 13:39:18

Comments post a comment

  1. Matthias Vallentin commented on 2009-02-13 @ 11:23

    Very nice reverse engineering approach! This device seems to catch the interest of many folks :-)

    I wrote a similar article some time ago:
    http://matthias.vallentin.cc/2007/04/writing-a-linux-kernel-driver-for-an-unknown-usb-device/

  2. halsten commented on 2009-02-13 @ 15:42

    Interesting stuff Pedram. Thanks for sharing that. However, the Arabic letters that were written above the count-down timer really didn't mean much, not to mention that they were written wrong too. But, still it was fun to watch.

    Regards,
    halsten

  3. Ashnod commented on 2009-02-13 @ 16:49

    Hi I have one of these USB Launchers and an iPhone. I was wondering if you would release the code used for this. ^_^

  4. Jeeves commented on 2009-02-13 @ 21:13

    It would be cool to use the tilt sensor in the iPhone to control the pan/tilt of it and use the webcam output as well.

  5. mindoverflow commented on 2009-02-14 @ 11:02

    Nice work mates.

    Why those arabic letters ? are they required for the project ?

  6. James commented on 2009-02-14 @ 12:17

    I have some bad news for you:
    http://web.archive.org/web/20060820072349/http://scott.weston.id.au/software/pymissile-20060126/

  7. Pedram Amini commented on 2009-02-14 @ 12:30

    @halsten / @mindoverflow: The Arabic letter countdown thing was just for comedic value. I found that SWF somewhere on the internet some time ago.

    @Ashnod: The code is released (http://dvlabs.tippingpoint.com/pub/pamini/ped_missile.py)

    @James: I figured I wasn't the first to do this. The purpose of the blog entry was more from the tutorial stance than anything.

  8. Arabic Anonymous commented on 2009-02-14 @ 15:30

    The arabic letters you used do not make sense.
    You cannot just join them: there are rules as to what shape to use for each letter (each letter may have multiple "shapes" depending on its location in the word).

    My .02 dirhams

  9. James commented on 2009-02-14 @ 21:46

    You may have figured, but slashdot seems to regard your work as original, especially woolpert, heh.

  10. TheSchwartz commented on 2009-02-14 @ 22:36

    Any chance the iPhone app will be put up on the iTunes app store? I'd like to try it but not sure how to manually install it on a non hacked iPhone.

  11. Stian Skjelstad commented on 2009-02-15 @ 04:03

    Yes, there exists multiple reverse-engineered apps for linux, bsd etc for this already. Hey you can even use the native HID driver in linux and have a very small app in user-space and you are done (which is what the windows driver do). But that is not the point of this article either. The point of this article is to show how you can start on reverse engineer a simple driver, and play around with it.

  12. Misterfixit commented on 2009-02-15 @ 08:03

    Lovely work. Clever. Nice to see that this will work with few modifications for an actual sabotage or terrorist device. Granularity is fine, actually, but we can point and shoot curare-coated broadpoint crossbow arrows from a remote device to silently kill someone out to 25 meters by using this exact same device, specially modified with a camera tripod mount. Web cam hooked up to it also helps to do the aim and after-action report on effectiveness of killing device. Thank you for your clever work! Shazaam Sh'ahmat!

  13. Anonymous commented on 2009-02-15 @ 09:01

    Isn't thus just reinventing the wheel? An iphone interface (a web interface just like shown) for these missile launchers has existed for a good while now, with examples of it also paired to a webcam. I have also coded a non-web iphone native app that does all of this too.. the trouble is in getting iphone users, who are not particularly tech savy, able to configure the system

  14. Pedram Amini commented on 2009-02-15 @ 09:02

    @TheSchwartz: The iPhone interface is simply through the browser. No app required. It's all in the linked script ped_missile.py. This really was a quick and dirty hack.

  15. Anonymous commented on 2009-02-15 @ 17:43

    It's a shame that it takes ~5 seconds between pushing the fire button and the actual launch. Not to mention the incredible noise of preparing to launch. I wish there was some way you could pump it in advance and then firing would be without delay.

  16. JD commented on 2009-02-16 @ 15:41

    Heh, I'm actually working on Windows controls for this in C++. Quite interesting.

    @Anonymous: There is a way to prime the launcher. It's actually implemented in the SharpLauncher version.

  17. Pedram Amini commented on 2009-02-16 @ 20:56

    @JD: What's the SharpLauncher version?

  18. JD commented on 2009-02-17 @ 02:48

    Sorry if I was unclear. By SharpLauncher version (of missile launcher drivers) I just meant the SharpLauncher program here: http://abmason.wordpress.com/software-projects/sharprocket/ . It's a C# based gui program that works for these missile launchers. There are control codes returned from the launcher depending on status (all the way right, etc) including one labeled DonePriming, if memory serves.

  19. Arabic letters commented on 2009-02-24 @ 00:12

    :)
    the arabic letters do mean something but they were written backwards :)

    what they mean is .."Egyptian authorities started"

    I figured you might copied it from a news site or something, anyways great stuff and good luck :)


Links To This Post

  1. Acquiring Target… Launch!
    linked on 2009-02-20 @ 11:29 Show Comment

    ... what about something a little more interactive…say… a missile launcher, perhaps? That’s right. A team member from DVLabs has taken a USB nerf-style missile launcher and created a program that increases the granular control enabling the user to “slowly and quietly reposition the turret for stealthy attacks.” (http://dvlabs.tippingpoint.com/blog/2009/02/12/python-interfacing-a-usb-missile-launcher) What next, wireless control?

  2. Missile launcher, iPhone interface - Hack a Day
    linked on 2009-02-13 @ 15:22 Show Comment

    [Pedram] Sent us his USB missile launcher interface project. He happened to have some of the USB missile launchers lying around. having lost their initial draw, he wanted to do something to spice it up. He wrote an interface in python so he could control the launcher via his iPhone. We don’t see how this is any different than controlling them by the computer, but he seems to have put a decent amount of work into it.

  3. Pilotare un lancia missili USB con l’iPhone
    linked on 2009-02-18 @ 03:54 Show Comment

    L’interfaccia scritta in Python la potete trovare qua.

  4. News for Geek » Missile launcher, iPhone interface
    linked on 2009-02-14 @ 00:10 Show Comment

    [Pedram] Sent us his USB missile launcher interface project. He happened to have some of the USB missile launchers lying around. having lost their initial draw, he wanted to do something to spice it up. He wrote an interface in python so he could control the launcher via his iPhone. We don’t see ...

  5. DVLabs Missle Command | Videos [Comedy] | Watch Funny Videos, Funny Quotes, WTF Humor, Comedy, LOLCats Videos, Video humor »
    linked on 2009-02-14 @ 20:12 Show Comment

    http://dvlabs.tippingpoint.com/blog/2009/02/12/python-interfacing-a-usb-missile-launcher

  6. iPhone Controlled USB Missile Launcher | Hack N Mod
    linked on 2009-02-14 @ 15:02 Show Comment

    iPhone Controlled USB Missile Launcher By hacking the fantastic USB missile launcher, this modder can control his missile attacks remotely with his iPhone.  The video above demonstrates the fuctionality and you can learn more about the project and see the C++ code.

  7. Things that were not immediately obvious to me » Blog Archive » Python Puzzle
    linked on 2009-02-18 @ 22:11 Show Comment

    Pedram Amini has got a pretty neat post up on reverse engineering the protocol for a USB device. If you haven’t seen it yet (it was linked from Slashdot) it’s worth reading. However, he includes some Python code which features a puzzling (to me, anyway) idiom, which took me a while to figure out.

  8. Lazamisiles para el iPhone/iPod Touch « iSuriv’s Weblog
    linked on 2009-03-16 @ 19:13 Show Comment

    Fuente DVLabs

  9. Programador hackea juguete electrónico para controlarlo desde un iPhone | R1CHARD >>> Hacking my minD
    linked on 2009-03-10 @ 17:10 Show Comment

    Amini modificó los lenguajes originales Delphi y C++ de los lanzamisiles y reprogramó su interfaz en código Python. Todos los detalles del proceso aparecen en el blog de la compañía explicados por el propio personaje.

  10. Un programador hackea un tanque lanzamisiles para controlarlo desde el iPhone | tuexperto.com
    linked on 2009-03-10 @ 09:26 Show Comment

    Amini modificó los lenguajes originales Delphi y C++ de los lanzamisiles y reprogramó su interfaz en código Python. Todos los detalles del proceso aparecen en el blog de la compañía explicados por el propio personaje.

  11. Un programador hackea un tanque lanzamisiles para controlarlo desde el iPhone - Gratis Programas, Descarga Freeware, Warez Full, Noticias
    linked on 2009-03-10 @ 15:23 Show Comment

    Amini modificó los lenguajes originales Delphi y C++ de los lanzamisiles y reprogramó su interfaz en código Python. Todos los detalles del proceso aparecen en el blog de la compañía explicados por el propio personaje.

  12. iPhone USB Missile Launcher | T3ch Today
    linked on 2009-03-01 @ 22:56 Show Comment

    We’ve all seen that awesome USB missile launcher from ThinkGeek.com. Now if you’ve got an iPhone, you can remotely control your USB missile launcher. Read the full instructions and grab the source code. Share and Enjoy:


Trackback