Monthly Archives: December 2015

Cracking the code: reverse engineering the AlcaTech BPM Studio controller

The recent demise of my old workshop PC has spurred me into action. Back in the halcyon days of the late 90s and early 2000s, I used to DJ a bit. I was an early adopter of computer-based DJ technology. In those days it was still fairly unusual to have music in MP3 format – the iPod wasn’t released until late 2001 – never mind being able to actually DJ with it. At the time I found a product from a German company which did exactly what I wanted: it was a combination of hardware and software called BPM Studio which meant I could use MP3 files as if they were a professional CD player: cueing them, pitch-shifting, mixing and so on. The hardware is a solidly-built control panel which connects to the PC, on which runs some software which does all the audio processing.

Img_1278

So why has the failure of my old workshop machine reminded me of this? Because, once upon a time, it was my media PC, and it ran the DJ software. The software and hardware is now 15 years old, and it shows: the controller connects using a serial port (when did you last see a PC with one of those?) and the software has…wait for it…a dongle! Yes, just like in the bad old days, it has a device which plugs into the parallel port on the PC, and if it’s not found, the software won’t run. Parallel ports, especially, are a dying breed today, so the chances of being able to use this controller and software in the future fade as PC technology moves on.

The BPM Studio package was expensive, and the controller is quite nice and robustly built, so I’d like to be able to preserve it and, if possible, use it with more modern software. The trouble is, its interface to the PC is proprietary, unsupported by any other software, and I couldn’t find any documentation on it. There was only one way forward to protect my investment: hack it.

The first step was to have a look at what was going on on the serial connection, and what baud rate was in use. I put a little breakout adapter in the serial cable (this one, in fact, modified a bit) so I could examine the data.

IMG_1283

First thing was to figure out the baud rate. Set the scope to trigger on the rising edge and play with the timebase a bit and soon we can see the start bit of each byte:

Img_1282

That’s definitely 19200 baud. Nice and standard. So I started my handy hdump2 software, which displays two streams of data side by side so it’s possible to see what came from where and when, and hoped to see something which made sense: a recognisable packet format, perhaps, or at least consistent data. What I got instead was this:

bpmstudio-startup

The left column is data from the PC, and the right column is data from the controller. It’s clear there’s a conversation going on, but it looks encrypted to me. There are no obvious packets, no start or end markers, nothing clearly related to what’s going on. I played around pressing buttons on both the controller and PC, and lots of data flowed but nothing made any sense. No readable track names for the displays, no recognisably similar data when I pressed the same button numerous times.

Why on earth would anyone encrypt the connection between the PC and a controller like this? Only the designers know, but I guess it’s part of the same mindset that required a hardware dongle to run the software. A fear of piracy, probably.

Interestingly, if the PC and controller are separated, they each send out  a burst of data once a second. The PC sends bursts of 4 bytes, and the controller sends bursts of 12 bytes. Each of them follows a fixed pattern from startup. The PC sends:

9c 94 dc 0e
56 1e 97 95
ad f8 87 4a
dc bc f0 37
32 44 bd a1

and so on. The controller sends:

f0 99 d0 af 3b 2f c8 5b 21 3c 4f d4
44 95 ac e1 d9 76 2a 58 bf 1e 52 52
34 e7 1a 93 ce b1 97 3e a4 f9 01 37
d3 f3 94 c1 32 57 31 a7 9a 6c 83 68
84 ae d1 f6 e7 c1 c8 5d e2 e4 46 36

and so on. I can’t see an obvious relationship between them. What I can see from the conversation dump above is that the controller seems to restart its sequence when it sees the data from the PC, but with some subtle differences.

If I was a proper mathematician, I’d spend more time trying to work out what the code was. Being an engineer, I thought I’d take it apart and have a look inside.

Img_1285

There’s more to it than I thought. This predates the days of powerful PIC and AVR microcontrollers, and actually has separate chips for its CPU, ROM and RAM. That’s good news for anyone interested in reverse engineering it. The CPU is a Siemens/Infineon 80C166:

Img_1287

and there’s a 29F010 (128 KByte) ROM connected to it, presumably holding the software:

Img_1288

There’s also a 32K RAM chip, which is more than I’d expect. I just hope the software isn’t doing something horrible like decrypting itself into RAM and running from there.

The good news is that documentation for the 80C166 is freely available, as is a disassembler, ADIS16X. And I’ve just ordered a PLCC32 adapter so that the ROM, once I’ve desoldered it, will fit my EPROM programmer. Watch this space.

Advertisements

Modifying libmodbus for asynchronous operation

I’m working on a project at the moment which has to connect to some industrial control equipment. The communications protocol in use is Modbus, or to be more precise its Modbus TCP variant. Working with this protocol is made much easier by the convenient libmodbus, a free and open-source software library which handles the communications and data formatting. The library is included with Debian Linux, the platform on which I’m writing the software.

modbus_logo

Convenient as it is, libmodbus is written with the assumption that communications are synchronous: that it’s OK to request some data and wait for the response. For example, fetching some data from a Modbus device looks like this (in abbreviated C):

uint16_t registers[5];
modbus_t *mb = modbus_new_tcp("192.168.1.20", 1502);
modbus_connect(mb);
modbus_read_registers(mb, 0, 5, registers);
modbus_close(mb);

The code above fetches the contents of registers 0-5 from the Modbus device at IP address 192.168.1.20, port 1502. It’s delightfully simple. My problem is that each of the network operations: modbus_connect(), modbus_read_registers() and modbus_close() could take some time, if the network is congested or unreliable or if the device is busy doing something else.

My software needs to handle various types of communication from different sources on the network, so hanging around while any of them completes isn’t acceptable. It’s OK to wait for data – that’s just life – but being unresponsive to other things while that data is arriving just won’t do.

Another project I worked on last year used D-Bus communications which faces exactly the same problem. It’s intended for relatively complex software systems where many things could be going on at the same time. The authors of D-Bus have thought of this, and made it easy to use asynchronously. Rather than asking for some data and simply being unable to do anything else until it arrives, asynchronous operation allows the program to request some data, get on with something else, and be informed when the data is ready. The same applies to other operations which may take some time.

At the core of asynchronous operation is the run loop. Rather than the program being a step-by-step series of synchronous operations like the example above, it has a loop which sits waiting for any new activity, and then triggers any actions which need to deal with that activity. For example, in pseudo-C again:

initialise_everything();
while(1)
  run_loop();

run_loop() {
  if(nothing_happening())
    sleep_for_a_moment();
  switch(what_happened()) {
    case network_connection_succeeded:
      start_sending_data();
    case data_sent:
      start_receiving_data();
    case data_received:
      notify_application();
    case error:
      /* handle error */
    }
}

This structure means that lots of operations can be outstanding, and whichever needs attention first can get that attention without waiting for any of the others. It’s more complex but much more powerful.

My application is interested in network data from various places, and Linux (as well as many other operating systems) provides some handy operating system services that make asynchronous operation straightforward, with a little thought. The most important is select().

The select() system call allows a program to wait until something happens to any of a list of file descriptors, each of which can represent a hardware device, a network connection, or various other things. It also allows a timeout, so if nothing happens for a moment, the program can do other things, then call select() again without missing anything.

The D-Bus library has two important interfaces which make it possible to base the applications run loop around select():

  • D-Bus will tell the application each time it is interested in a new file descriptor, or it is no longer interested in a file descriptor. This is known as adding or removing a watch.
  • D-Bus provides a function which can be called whenever one of the file descriptors is indicated by select().

That’s basically it. It means that D-Bus can get on with whatever networking complexity it likes without occupying my application any more than it has to. Sauce for the goose is sauce for the gander, so this model should fit my Modbus application too.

Since libmodbus is open source, I was able to modify it to support this method of operation. Most of the required code was already in there, but I had to create new functions which called it in particular ways, and add new data to the modbus_t structure to keep track of what operations were outstanding. The new asynchronous way of working looks like this, in rather abbreviated form:

modbus_t *mb = modbus_new_tcp("192.168.1.20",1502);

modbus_set_connected_cb(mb, &connect_callback);
modbus_set_read_cb(mb, &read_callback);
modbus_set_add_watch_cb(mb, &add_watch_callback);
modbus_set_remove_watch_cb(mb, &remove_watch_callback);

modbus_connect_async(mb);
while(1)
  run_loop();

void connect_callback(int failure) {
  if(!failure)
    modbus_read_registers_async(mb, 0, 5, registers);
}

void read_callback(int failure) {
  if(!failure)
    /* we got the data we asked for */
}

void add_watch_callback(int fd, int flags) {
  /* add fd to our list of file descriptors */
}

void remove_watch_callback(int fd, int flags) {
  /* remove fd from our list of file descriptors */
}

void run_loop() {
  if(select(list_of_file_descriptors))
    modbus_selected(fd, flags);
}

I’ve left lots of detail out here, but the sequence of operations looks like this:

  • the application informs libmodbus about the various functions which should be called when things happen: a connection succeeds, data is received, a new watch is to be added, a watch is to be removed.
  • the application asks libmodbus to start a connection, but asynchronously using libmodbus_connect_async().
  • the application then just sits in the run loop.
  • libmodbus call the application back through add_watch_callback(), adding a watch on the socket it will use for the connection. It then asks the operating system to make the connection.
  • when the connection completes, select() will return its file descriptor, and the run loop will call libmodbus via modbus_selected()
  • libmodbus now checks that the connection was successful, and calls the application through connect_callback().
  • The application can now request data using modbus_read_registers_async().
  • While requesting the data, libmodbus will almost certainly use add_watch_callback() to inform the run loop that it should keep an eye out for the data.
  • When data arrives, which may happen in several small chunks, the run loop will call modbus_selected().
  • libmodbus can assemble and check the received data. When it has arrived succesfully, or failed terminally, it will call the application back through read_callback().
  • The application can now work with the received data.

While all this is going on, the application can be doing other things: handling other network connections, processing data, or even handling other Modbus connections.

The modifications, after some development and debugging time, work very nicely. After more testing, they’ll almost certainly make it into the final application, and I’d like to contribute them back to the open source community so that other developers can use Modbus asynchronously too.

Recovering Windows XP from a corrupted registry

In the workshop at home I have a terribly old PC. It’s got an AMD Athlon XP CPU at a blistering 1.48GHz, and runs Windows XP. It’s mostly just got on with the jobs I ask of it (although its power supply has featured in the blog before) but in the last week it’s failed twice. I suspect there’s a hardware problem, given that the machine is approaching its 15th birthday.

Img_1229

The symptoms have been that the machine would be working normally and then the screen would go black, with no response from the keyboard or mouse and no disk activity. Pressing the PC’s reset button brought it to life again. but with the dreaded message, “Windows could not start because the following file is missing or corrupt: \WINDOWS\SYSTEM32\CONFIG\SYSTEM”.

A quick web search revealed the official repair procedure from Microsoft: How to recover from a corrupted registry that prevents Windows XP from starting. The procedure looks like this:

  • Boot the machine using the XP install CD and enter the recovery console
  • Copy the five registry hives (system, software, sam, security and default) from \WINDOWS\SYSTEM32\CONFIG into a backup location
  • Copy default registry hives from \WINDOWS\REPAIR in their place
  • Boot into Windows and use the desktop to copy backup registry hives created by System Restore into a temporary location
  • Reboot into the recovery console again
  • Copy the backup registry hives into \WINDOWS\SYSTEM32\CONFIG
  • Reboot into Windows again (yawn)
  • Use the System Restore utility to restore the system to the most recent restore point.

I did this the first time, and it turned out to be an awful lot of fiddling around just to restore a backup of five files. One problem is that installing the default registry hives and booting Windows makes a mess of the user profiles, which is why the later system restore is required. As far as I can see, Microsoft recommend this procedure simply to avoid people having to dig around in the filesystem at the recovery console.

The next time the same fault occurred, I decided to try a short cut. This is what I did.

  • Boot the machine using the XP install CD and enter the recovery console.
  • Copy the corrupt registry hive (system) from \WINDOWS\SYSTEM32\CONFIG into a backup location, just in case
  • Still in the recovery console, find the most recent backup created by System Restore
  • Copy the system registry hive from there into \WINDOWS\SYSTEM32\CONFIG
  • Reboot into Windows and start working again.

The tricky part about this is that the system restore folder names are really long and unpleasant to type, and the recovery console doesn’t have command completion. However, you only have to do it once.

First, find the most recent _restore folder in \System Volume Information:

Img_1230

Then, the most recent RPxxx folder inside there:

Img_1231

That folder will contain a ‘snapshot’ folder, inside which are the registry backups. Copy the relevant one into \WINDOWS\SYSTEM32\CONFIG. Note that the filenames are different:

Img_1234

Type ‘exit’ to reboot, and that’s it. Job done. It worked for me: a ginormous download that Firefox had been working on continued exactly where it left off, and I’m typing this on the very same machine.

It would probably be possible to do exactly the same process using a bootable Linux CD, too, as long as it was capable of reading and writing NTFS filesystems in a trustworthy way.

Incidentally, all this is only possible because XP automagically saves backups of important things using System Restore. Say what you like about Microsoft, but that’s a really useful feature.