Category: Programming

Jetpack: Unread Messages in Gmail App Tab August 13th, 2010

One of the new features in Firefox 4 is the App Tab which lets users persist a tab that they use continuously. Firefox shrinks the tab down to just the favicon and places it in a special area for these tabs which generally aren’t closed by the user. The feature is great, but one of the side effects is that Gmail App Tabs don’t show anymore the part of the <title> that indicates unread messages.

That’s where my new Jetpack (a cool new, lightweight (and secure!) way to write Add-ons) comes in.

Go install Unread Gmail Favicon from AMO and the favicon for that tab will indicate the number of unread messages when you have them like so:

Hacked my DEF CON 18 badge July 30th, 2010

I was only able to stay for part of the first day of DEF CON this year, but I’m glad I did. One of the things they’ve done for the last five years or so is put microcontrollers in the badges, and put in little Easter eggs for people to search for. This year’s had a Ninja Party mode which was locked by default, but you could unlock it by placing a series of 15 tumblers in the correct position.

They published the source code for the badges on the CD they gave out at registration (so perhaps I’m stupid for loading the CD on my laptop rather than smart for reverse engineering the badge). I opened up DC18_Badge.c and, searching for “Ninja” (the code was commented nicely), quickly found the following two C functions:


int dc18_ninja_validate(uint32_t val) 
    uint16_t a, b;
    a = (uint16_t)(val & 0xfff);
    b = (uint16_t)(val >> 12);
    if((a ^ b) == 0x916) 
        return 1;
    return 0;

// encode tumbler states into
// 24-bit value
    uint32_t x = 0, j = 1;
    uint16_t i;
    for (i = 0; i < TUMBLERS_PER_IMAGE;
        x += tumblers[i] * j;
        j *= 3;
    return x;

So the trick was to find the number that made (a ^ b) == 0x916 and then figure out the tumbler positions to represent that number. I wrote two small Python functions to automate those tasks. To find the number that would unlock Ninja Mode, I wrote this loop. I added a print statement to show how far into the search we were, thinking it might take some time to find it, but it popped out 6423 in no time at all:

while 1:
    a = i & 0xfff
    b = i >> 12
    if i % 10000 == 0:
        print "# a: %d, b: %d, i: %d" % \
            (a, b, i)
    if a ^ b == 0x916:
        print "DONE: %d" % (i)
    i += 1
DONE: 6423

Now all that was left was to figure out the tumbler positions to represent 6423. Clearly, dc18_encode_tumblers tells us how to do that. I whipped up this little function to convert the tumbler positions to a decimal number:

def enc_tumblers(tum):
    x = 0; j = 1;
    for i in range(15):
        x += tum[i] * j
        j *= 3
    return x

>>> enc_tumblers([1,1,1,1,1,2,2,2,

I was going to write another loop to increment the tumbler array I was passing to enc_tumblers, but my first guess was so close that I just manually entered the settings until I found the winning configuration:

>>> enc_tumblers([0,2,2,0,1,2,2,2,

Once I had the configuration, I put the tumblers in the appropriate positions: 0 - up, 1 - middle, 2 - down. After that, well, I guess I'm a ninja now:

Sharing Links May 28th, 2010

Sometimes I make a tool that I use for a while and then wonder if it’s something others will find useful too. Here’s one of them…

For a while I was sharing links on my home page by linking to the feed of stories I’ve upvoted on Reddit, but that has become less satisfying as Reddit dumbs itself down each day (the same thing that happened to Digg a few years earlier). I decided to make my own link-sharing program that I could use by just clicking a bookmarklet whenever I was on a page I wanted to share.

It is a very simple program that stores the links in a flat text file and uses CORS to allow the bookmarklet to POST data to it from across domains. You can put the files in a directory on your server and use this simple bookmarklet to share links:

Drag this to your bookmarks toolbar: Share This

You can check out the server code or the bookmarklet source, or you can download the zip archive and extract the files on your server.

When you fetch the server script with GET you get back a JSON or RSS feed depending on the format parameter you pass.

Make sure the password in the bookmarklet stays synced with the password in the server file and change them to something secure.

A-Star (A*) Algorithm in Python – Update January 25th, 2010

Since there have been many requests over the years for the source code referenced in my A-Star (A*) Algorithm post, I decided to share it. I did a bit of refactoring too, as I have learned some neat things about Python in the years since I wrote that post, like list comprehensions.

A cautionary note to undergrad CS students (who I can only assume are the requestors): CS professors are pretty good at catching cheaters, so learn from others’ code, but write your own.


Python CIDR Block Converter December 14th, 2007

I wrote a Python script that converts a CIDR Block into a list of individual IP addresses, one-per-line. I found that I needed to repeat some network-related tasks across an entire subnet, and this script provides an easy way to automate these kinds of tasks in a shell environment. The source code and sample usage for the script follow:

Source Code:

Sample Usage:

brandon@zodiac ~ $ cidr

One item to note is a key difference between the way this program computes a CIDR block and others I have seen. The lazy way to convert a CIDR block to a list of IPs is to calculate the number of IP addresses in the subnet, (2^(32 – $subnetSize)), and simply increment the base IP address that number of times. This method is deficient because, as in the example usage above, the base IP address that is specified may fall somewhere in the middle of the range of IP addresses (not necessarily at the beginning).

In my script, I calculate the CIDR block members the correct way. I am converting the base IP address to its binary form, zeroing-out the number of least significant bits as specified in the subnet size, and starting the enumeration of IP addresses at the bottom of that range.