Tag Archives: Hacking/Tweaking

MAX5214 Eval Board

I caught on to a promotion from AVNet last week, in which one may get a free MAX5214 eval board (available through August 31), so hopped on it because really, why wouldn’t I turn down free hardware? I promptly forgot about it until today, when a box arrived from AVNet.

What’s on the board

The board features four Maxim ICs:

  • MAX8510– small low-power LDO.  Not terribly interesting.
  • MAXQ622– 16-bit microcontroller with USB.  I didn’t even know Maxim make microcontrollers!
  • MAX5214– 14-bit SPI DAC. The most interesting part.
  • MAX6133– precision 3V LDO (provides supply for the DAC)

The MAXQ622 micro (U2) is connected to a USB mini-B port for data, and USB also supplies power for the 5V rail.  The MAX8510 (U4) supplies power for the microcontroller and also the MAX6133 (U3).  The microcontroller acts as a USB bridge to the MAX5214 DAC (U1), which it communicates with over SPI.  The SPI signals are also broken out to a 4-pin header (J4).

Software

The software included with the board is fairly straightforward, providing a small variety of waveforms that can be generated. It’s best demonstrated photographically, as below. Those familiar with National Instruments’ LabView environment will probably recognize that this interface is actually just a LabView VI (Virtual Instrument).

Hacking

Rather more interesting than the stock software is the possibility of reprogramming the microcontroller. Looking at the board photos, we can see that there’s a header that breaks out the JTAG signals. With the right tools, it shouldn’t be very difficult to write a custom firmware to open up a communication protocol to the device (perhaps change its device class to a USB CDC for easier interfacing). Reprogramming the device requires some sort of JTAG adapter, but I can probably make a Bus Pirate do the job.

With some custom software, this could become a handy little function generator- its precision is good and it has a handy USB connection. On the downside, the slew rate on the DAC is not anything special (0.5V/µs, -3dB bandwidth is 100 kHz), and its output current rating is pretty pathetic (5 mA typical). With a unity-gain amplifier on the output though, it could easily drive decent loads and act as a handy low-cost waveform generator. Let’s get hacking?

A few small projects

Going through some of my old projects this evening, I came across a couple little tools I wrote.  I’ve uploaded them here in the hope that others will find them useful.  They are the GCNClient GUI and RX BRR calculator.

I make no guarantees of the utility of these pieces of software, but they may be useful as examples in how to perform some task in the .NET framework (both are written in C# for .NET), or just for performing the very specific tasks which they are designed to perform.

Some Chronos Documentation

Moving on from my previous post (in which I muttered sullenly about brain-dead packaging of software for Linux), I began hacking on my Chronos proper tonight. Read on for some juicy tidbits.

Initial build

The first order of business was to set up a toolchain targeting MSP430. Since I’m running Arch on my primary development system, it was a simple matter to build gcc-msp430 from the AUR.

With that, I was ready to try compiling things. I assumed (correctly) that the provided firmware would not build on GCC without modification, but a little googling pointed me to OpenChronos, which effectively takes the stock firmware, makes it build with any of several compilers (TI’s compiler included with CCS, IAR’s, and GCC). Come to think of it, LLVM has an experimental MSP430 backend that might be interesting to try out.

One git checkout and an invocation of make later, and I was staring at a screenful of errors. “How auspicious,” I thought. The first part of the fix was easy– I simply needed msp430-libc for some of the more specialized functions that don’t map well into straight C- things like interrupt handling (which is in msp430-libc’s signal.h for some reason) or machine-specific delays.

The remaining compilation errors after grabbing libc were rather more troublesome, however. There were two main classes of problem.

  • Uses of types at some specific bit-width (such as uint16_t). These were easily resolved by strategic inclusion of stdint.h, but I’m not very happy with how I had to do it. Spraying header inclusions all over the source code is a poor way to fix things.
  • Large delay constants. There were two cases in the radio control code which adjusted the microcontroller’s voltage regulator, which then requires a rather long delay before the system can be considered stable again. The solution in code is simply to delay for as many as ~800000 clock cycles. Normally that wouldn’t be a problem, but some of the delay constants were larger than the input type to the __delay_cycles function could hold. My hacky solution was to split those into two calls of half the length, which seemed to work out OK.

After a while to figure out the compilation problems, I was able to build a firmware image. After the struggles I had with unpacking TI’s sample code and demo applications, it was fortunately painless to actually run them. I just ensured I had Tcl/Tk installed and ran the Chronos Control Center application. Putting the Chronos itself into WBSL (Wireless BootStrap Loader) mode and clicking a few times was easy, and I quickly got my new firmware image flashed onto the CC430.

Preparing for mods

Now that I had a known-working toolchain, it was time to get to work actually implementing some of the toy features I wanted to add. Since the single most interesting feature of the hardware is the radio (although the low-power capabilities of the MSP430 are quite shiny as well), I set out to see how I could communicate with the watch from my PC.

One of the USB dongles that comes packaged with the Chronos is a USB wireless access point, basically just a CC1111 (6801 core with USB and RF transciever). I understand that earlier revisions of the demo applications didn’t include source code for the software running on the CC1111, but the current release includes it. Some people had taken a bit of trouble to reverse-engineer the communications, but that alone isn’t very useful documentation. With that in mind, I set out to document for myself how to communicate with the RF access point and go through that to talk to the Chronos.

Setting up communications is easy, fortunately. The CC1111 is programmed to enumerate as a USB CDC, so one must only open the virtual serial port it creates with a 115200 bps baud rate with 8 data bits and 1 stop bit. (If that’s not terse enough for you: 115200 baud, 8n1.)

With virtual serial communications up, the upper-level protocol is rather easy- it consists of packets of at least 3 bytes each, where the first one is always 0xFF. Byte 2 provides a command ID, and byte 3 specifies the total packet size, including the overhead (so the minimum valid size is 3). Anything more in the message is interpreted based on the command ID.

Command IDs

There are a number of command IDs defined, but only a few that are of particular interest. In the hopes that somebody else will find it useful, I include my raw notes on the command bytes below.

As a little bit of context, the system can run on either of two different radio protocols. TI’s SimpliciTI is a protocol designed mainly for communication between low-power nodes in a network, while BlueRobin is a radio protocol developed by IAR Systems, notable with the Chronos because it allows communication with a heart rate monitor developed by BMi GmbH.

Command bytes:
    BM_GET_PRODUCT_ID
        Dumps 32-bit product ID into the usb buffer
    BM_GET_STATUS
        returns system_status (some file-scope var?)
== bluerobin
    BM_RESET
        Turns off bluerobin
    BM_START_BLUEROBIN
        Start bluerobin (set a flag, actually), stop simpliciti if that's going
    BM_SET_BLUEROBIN_ID
    BM_GET_BLUEROBIN_ID
    BM_SET_HEARTRATE
    BM_SET_SPEED
== simpliciti RX
    BM_START_SIMPLICITI
        Start simpliciti, stop bluerobin if that's going
    BM_GET_SIMPLICITIDATA
        Dump the 4 bytes from the simpliciti_data buffer to USB
        also mark simpliciti data as read
        If no pending data, usb_buffer[PACKET_BYTE_FIRST_DATA] = 0xFF
    BM_SYNC_START
        nop
    BM_SYNC_SEND_COMMAND
        copy packet from USB to simpliciti buffer and flag for tx ready
    BM_SYNC_GET_BUFFER_STATUS
        1-byte payload packet out, = var simpliciti_sync_buffer_status
    BM_SYNC_READ_BUFFER
        copy simpliciti_data buffer out to USB
    BM_STOP_SIMPLICITI
        Flag to turn off simpliciti

== WBSL
    BM_START_WBSL
        flag to start WBSL, turn off bluerobin/simpliciti if active
    BM_STOP_WBSL
        stop wbsl, turn off LED
    BM_GET_WBSL_STATUS
        copy back var wbsl_status
    BM_GET_PACKET_STATUS_WBSL
        copy back var wbsl_packet_flag or WBSL_ERROR if wbsl is off
    BM_GET_MAX_PAYLOAD_WBSL
        copy back max number of bytes allowed in wbsl payload
    BM_SEND_DATA_WBSL
        set wbsl_packet_flag to WBSL_PROCESSING_PACKET
        deocode packet and spew it to the 430
== self-test
    BM_INIT_TEST
    BM_NEXT_TEST
    BM_GET_TEST_RESULT
    BM_WRITE_BYTE
        write a byte to the access point's Flash memory
        first data byte is the value to write
        second and third are address, little-endian (2 is lsb, 3 => msb)
        must be in test mode (precede this with BM_INIT_TEST)

(Command and system status constants are defined in BM_API.h, FWIW.)

Knowing all the commands, it’s pretty easy to pull out the useful ones. BM_START_SIMPLICITI makes the access point switch into SimpliciTI mode, and sending BM_SYNC_START allows direct communication through the radio link with BM_SYNC_{SEND,READ}_BUFFER functions.

More.. later

This is as far as I’m going to go with this adventure for today, but there’s more to come in the coming days (hopefully, assuming my motivation holds out). This is just preliminary documentation– I’m hoping to create a more formal set of documents providing a whirlwind overview of how to get hacking on the Chronos, but I feel this is an excellent start.

How not to distribute software

I recently acquired a TI eZ430-Chronos watch/development platform. It’s a pretty fancy piece of kit just running the stock firmware, but I got it with hacking in mind, so of course that’s what I set out to do. Little did I know that TI’s packaging of some of the related tools is a good lesson in what not to do when packaging software for users of any system that isn’t Windows..

The first thing to do when working with a new platform is usually to try out the sample applications, and indeed in this case I did exactly that. TI helpfully provide a distribution of the PC-side software for communicating with the Chronos that runs on Linux, but things cannot be that easy. What follows is a loose transcript of my session to get slac388a unpacked so I could look at the provided code.

$ unzip slac388a.zip
$ ls
Chronos-Setup
$ chmod +x Chronos-Setup
$ ./Chronos-Setup
$

Oh, it did nothing. Maybe it segfaulted silently because it’s poorly written?

$ dmesg | tail
[snip]
[2591.111811] [drm] force priority to high
[2591.111811] [drm] force priority to high
$ file Chronos-Setup
Chronos-Setup: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, stripped
$ gdb Chronos-Setup
GNU gdb (GDB) 7.3
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/tari/workspace/chronos-tests/Chronos-Setup...
warning: no loadable sections found in added symbol-file /home/tari/workspace/chronos-tests/Chronos-Setup
(no debugging symbols found)...done.
(gdb) r
Starting program: /home/tari/workspace/chronos-tests/Chronos-Setup
[Inferior 1 (process 9214) exited with code 0177]

Great. It runs and exits with code 127. How useful.</sarcasm>

A Windows-style installer, "InstallJammer Wizard". On Linux.
This is stupid.

I moved the program over to a 32-bit system, and of course it worked fine, although that revealed a stunningly brain-dead design decision. The image (to the right) says everything.

To recap, this was a Windows-style self-extracting installer packed in a zip archive upon initial download, designed to run on a 32-bit Linux system, which failed silently when run on a 64-bit system. I am simply stunned by the bad design.

Bonus tidbit: it unpacked an uninstaller in the directory of source code and compiled demo applications, as if whoever packaged it decided the users (remember, this is an embedded development demo board so it’s logical to assume the users are fairly tech-savvy) were too clueless to delete a single directory when the contents were no longer wanted. I think the only possible reaction is a hearty :facepalm:.

mkg3a

Casio’s FX-CG, or Prizm, is a rather interesting device, and the programmers over on Cemetech seem to have found it worthwhile to make the Prizm do their bidding in software.

The Prizm device itself is based around some sort of SuperH core, identified at times in the system software as a SH7305 a “SH7780 or thereabouts”. The 7780 is not an exact device, though, and it’s likely a licensed SH4 core in a Casio ASIC. Whatever the case, GCC targeted for sh and compiling without the FPU (-m4a-nofpu) and in big-endian mode (-mb) seems to work on the hardware provided.

Between Jonimus and myself (with input from other users on what configurations will work), we’ve assembled a GCC-based toolchain targeting the Prizm. Jon put together a cross-compiler for sh with some supporting scripts, while I contributed a linker script and runtime initialization routine (crt0), both of which were adapted from Kristaba’s work.

With that, we can build binaries targetting sh and linked such that they’ll run on the Prizm, but that alone isn’t very useful. Jon also created libfxcg, a library providing access to the syscalls on the platform. Finally, I created mkg3a, a tool to pack the raw binaries output by the linker into the g3a files accepted by the device.

Rumor has it the whole set of tools works. I haven’t been able to verify that myself since I don’t have a Prizm of my own, but it’s all out there. Tarballs of the whole package are over on Jon’s site, for anyone interested.

Pointless Linux Hacks

I nearly always find it interesting to muck about in someone else’s code, often to add simple features or to make it do something silly, and the Linux kernel is no exception to that. What follows is my own first adventure into patching Linux to do my evil bidding.

Aside from mucking about in code for fun, digging through public source code such as that provided by Linux can be very useful when developing something new.

A short story

I was doing nothing of particular importance yesterday afternoon when I was booting up my previously mentioned netbook. The machine usually runs on a straight framebuffer powered by KMS on i915 hardware, and my kernel is configured to show the famous Tux logo while booting.

Readers familiar with the logo behaviour might already see where I’m going with this, but the kernel typically displays one copy of the logo for each processor in the system (so a uniprocessor machine shows one tux, a quad-core shows four, etc..). As a bit of a joke, then, suggested a friend, why not patch my kernel to make it look like a much more powerful machine than it really is? Of course, that’s exactly what I did, and here’s the patch for Linux 2.6.38.

--- drivers/video/fbmem.c.orig	2011-04-14 07:26:34.865849376 -0400
+++ drivers/video/fbmem.c	2011-04-13 13:06:28.706011678 -0400
@@ -635,7 +635,7 @@
 	int y;

 	y = fb_show_logo_line(info, rotate, fb_logo.logo, 0,
-			      num_online_cpus());
+			      4 * num_online_cpus());
 	y = fb_show_extra_logos(info, y, rotate);

 	return y;

Quite simply, my netbook now pretends to have an eight-core processor (the Atom with SMT reports two logical cores) as far as the visual indications go while booting up.

Source-diving

Thus we come to source-diving, a term I’ve borrowed from the community of Nethack players to describe the process of searching for the location of a particular piece of code in some larger project.

Diving in someone else’s source is frequently useful, although I don’t have any specific examples of it in my own work at the moment. For an outside example, have a look at musca, which is a tiling window manager for X which was written from scratch but used ratpoison and dwm (two other X window managers) as models:

Musca’s code is actually written from scratch, but a lot of useful stuff was gleaned from reading the source code of those two excellent projects.

A personal recommendation for anyone seeking to go source-diving: become good friends with grep. In the case of my patch above, the process went something like this:

  • grep -R LOGO_LINUX linux-2.6.38/ to find all references to LOGO_LINUX in the source tree.
  • Examine the related files, find drivers/video/fbmem.c, which contains the logo display code.
  • Find the part which controls the number of logos to display by searching that file for ‘cpu’, assuming (correctly) that it must call some outside function to get the number of CPUs active in the system.
  • Patch line 638 (for great justice).

Next up in my source-diving adventures will be finding the code which controls what happens when the user presses control+alt+delete, in anticipation of sometime rewriting fb-hitler into a standalone kernel rather than a program running on top of Linux..

Obfuscation for Fun and Profit

One of the fun things to do with computer languages is abuse them. Confusing human readers of code can be pretty easy, but it takes a specially crafted program to be thoroughly incomprehensible to readers of the source code yet still be legal within the syntax of whatever language the program is written in.

Not dissimilar from building a well-obfuscated program is using esoteric languages and building quines. All of these things can be mind-bending but also provide excellent learning resources for some dark corners of language specification, as well as the occasional clever optimization.

Obfuscation

It’s not uncommon for malware source code to be pretty heavily obfuscated, but that’s nothing compared to properly obfuscated code. What follows is some publically-released Linux exploit code.

ver = wtfyourunhere_heee(krelease, kversion);
if(ver < 0)
    __yyy_tegdtfsrer("!!!  Un4bl3 t0 g3t r3l3as3 wh4t th3 fuq!n");
__gggdfstsgdt_dddex("$$$ K3rn3l r3l3as3: %sn", krelease);
if(argc != 1) {
   while( (ret = getopt(argc, argv, "siflc:k:o:")) > 0) {
      switch(ret) {
          case 'i':
              flags |= KERN_DIS_GGDHHDYQEEWR4432PPOI_LSM|KERN_DIS_DGDGHHYTTFSR34353_FOPS;
              useidt=1; // u have to use -i to force IDT Vector
              break;
          case 'f':
              flags |= KERN_DIS_GGDHHDYQEEWR4432PPOI_LSM|KERN_DIS_GGDYYTDFFACVFD_IDT;
              break;

It reads like gibberish, but examination of the numerous #define statements at beginning of that file and some find/replace action make quick work to deobfuscate the source. Beyond that, the sheer pointlessness of ‘1337 5p33k’ in status messages makes my respect for the author plummet, no matter how skilled they may be at creating exploits.

Let’s now consider an entry to the International Obfuscated C Code Contest (IOCCC) from 1986, submitted by Jim Hague:

#define    DIT (
#define DAH )
#define __DAH   ++
#define DITDAH  *
#define DAHDIT  for
#define DIT_DAH malloc
#define DAH_DIT gets
#define _DAHDIT char
_DAHDIT _DAH_[]="ETIANMSURWDKGOHVFaLaPJBXCYZQb54a3d2f16g7c8a90l?e'b.s;i,d:"
;main           DIT         DAH{_DAHDIT
DITDAH          _DIT,DITDAH     DAH_,DITDAH DIT_,
DITDAH          _DIT_,DITDAH        DIT_DAH DIT
DAH,DITDAH      DAH_DIT DIT     DAH;DAHDIT
DIT _DIT=DIT_DAH    DIT 81          DAH,DIT_=_DIT
__DAH;_DIT==DAH_DIT DIT _DIT        DAH;__DIT
DIT'n'DAH DAH      DAHDIT DIT      DAH_=_DIT;DITDAH
DAH_;__DIT      DIT         DITDAH
_DIT_?_DAH DIT      DITDAH          DIT_ DAH:'?'DAH,__DIT
DIT' 'DAH,DAH_ __DAH    DAH DAHDIT      DIT
DITDAH          DIT_=2,_DIT_=_DAH_; DITDAH _DIT_&&DIT
DITDAH _DIT_!=DIT   DITDAH DAH_>='a'?   DITDAH
DAH_&223:DITDAH     DAH_ DAH DAH;       DIT
DITDAH          DIT_ DAH __DAH,_DIT_    __DAH DAH
DITDAH DIT_+=       DIT DITDAH _DIT_>='a'?  DITDAH _DIT_-'a':0
DAH;}_DAH DIT DIT_  DAH{            __DIT DIT
DIT_>3?_DAH     DIT          DIT_>>1 DAH:''DAH;return
DIT_&1?'-':'.';}__DIT DIT           DIT_ DAH _DAHDIT
DIT_;{DIT void DAH write DIT            1,&DIT_,1 DAH;}

What does it do? I couldn’t say without spending a while examining the code. Between clever abuse of the C preprocessor to redefine important language constructs and use of only a few language elements, it’s very difficult to decipher that program. According to the author’s comments, it seems to convert ASCII text on standard input to Morse code.

Aside from (ab)using the preprocessor extensively, IOCCC entries frequently use heavily optimized algorithms which do clever manipulation of data in only a few statements. For a good waste of time, I suggest browsing the list of IOCCC winners. At the least, C experts can work through some pretty good brain teasers, and C learners might pick up some interesting tricks or learn something new while puzzling through the code.

So what? Obfuscating code intentionally is fun and makes for an interesting exercise.

Quines

Another interesting sort of program is a quine- a program that prints its own source code when run. Wikipedia has plenty of information on quines as well as a good breakdown on how to create one. My point in discussing quines, however, is simply to point out a fun abuse of the quine ‘rules’, as it were. Consider the following:

#!/bin/cat

On a UNIX or UNIX-like system, that single line is a quine, because it’s abusing the shebang. The shebang (‘#!’), when used in a plain-text file, indicates to the kernel when loading a file with intent to run it that the file is not itself executable, but should be interpreted.

The system then invokes the program given on the shebang line (in this case /bin/cat) and gives the name of the original file as an argument. Effectively, this makes the system do the following, assuming that line is in the file quine.sh:

$ /bin/cat quine.sh

As most UNIX users will know, cat takes all inputs and writes them back to output, and is useful for combining multiple files (invocation like cat file1 file2 > both) or just viewing the contents of a file as plain text on the terminal. Final result: cat prints the contents of quine.sh.

Is that an abuse of the quine rules? Possibly. Good for learning more about system internals? Most definitely.

Esoteric Languages

Finally in our consideration of mind-bending ways to (ab)use computer languages, we come to the general topic of esoteric languages. Put concisely, an esoteric language is one intended to be difficult to use or just be unusual in some way. Probably the most well-known one is brainfuck, which is.. aptly named, being Turing-complete but also nearly impossible to create anything useful with.

The Esoteric language site has a variety of such languages listed, few of which are of much use. However, the mostly arbitrary limitations imposed on programmers in such languages can make for very good logic puzzles and often require use of rarely-seen tricks to get anything useful done.

One of my personal favorites is Petrovich. More of a command interpreter than programming language, Petrovich does whatever it wants and must be trained to do the desired operations.