You’d think I’d remember the morning that the code went into production after all the work and effort that went behind one of the biggest pranks I have ever pulled, but I don’t. However, I do remember every other charming detail. Who can forget such a challenging labor of love after all?

It all started with a close friend and a brilliant programmer’s idea to craft an Easter egg to celebrate the launch of a product. Now, as innocent as that sounds, this Easter egg was one of the many hilarious pranks in which I’ve participated. A small incident in the larger scheme of life you could say, but it was an incredible exercise in learning and totally worth the effort and thought. Looking back, I wonder how we managed to pull it off…

Back to the beginning, it was a much simpler time.

I had a windows laptop and I was a .net programmer (Sorry to disappoint you folks – all the code below is C#). You had VisualStudio, great documentation and complicated DependencyObjectFactory-ies. Sure, things were simpler, but it wasn’t really that simple to pull off what we had in mind and the challenges a two-person army had to overcome wasn’t a single one.

  • Every commit email was read by everyone in the company. Sneaking something in was hard. Most changes went through multiple reviews by different people.
  • The changes had to be as concise as possible – which meant minimal code
    changes, and file size constraints.
  • And of course being an Easter egg it has to have an element of surprise and ingenuity.

For the restless, here’s what we achieved:
Pressing a key combination anywhere in the app played a song.

Now, don’t get misled by it’s simplicity. This was not easy to achieve. At least for me. And we weren’t close to being done.

Which brings us to the next challenge.

  • Committing a song file by a dev is like firing up a barbecue under the smoke alarm.

Tl;dr version: Our product was a Windows based .net desktop app. We made a 20 second music clip file from a popular song,  wrote library code to play it on keystroke combinations. We then embedded both of them to the data section of the background JPEG file of the app. This was the largest chunk of the code base. Then minimal code was written in the windows desktop app to extract both the player library and song file and executed them.

If this has tickled your curiosity, it get’s better from here…

To circumvent the challenge of devs figuring out details from the change-lists and commit emails we went with embedding the code in the image. Updating an image in a repository is more or less passed on by devs. We also XORed the embedded image code lest one of them decided to take a look at the image diff’s (C# library dll’s have prepending text messages like “This Program Cannot Be Run in DOS Mode” etc)
Initially we went with a music loop from the mp3 version of a popular song that time. But pretty soon we realized that including the libraries to play mp3’s will trigger alarms. So we had to resort to creating the MIDI version of it since .net by default included the player library for MIDI’s. This was one of the funnier moments of the whole exercise when we had headphones on during meetings testing out loops, playing DJs mixing and matching. The midi file is included in the example image if you want to try it out. To understand how the code was embedded into the image you need to understand a little about how JPEG format works.

A JPEG image file starts with a Start Of Image (0xFFD8) and ends with a End Of Image (0xFFD9) marker. In between these two markers, there is a sequence of segments, each starts with its own markers that indicates the type of the segment. The segment marker is followed by two bytes indicating the length of the segment specific payload, including the two bytes for the length.  APPn segments (0xFFEn) segments usually start with a header string and are used by different applications to store application specific data.   APP0 is with a header string “JFIF” is mandatory as the first segment in the JPEG file and is used to identify JPEG File Interchange Format. A few known APP segments are listed here.

We chose APP12 segment to store our player assembly.The midi file was then appended to the end of the image file. All of this can be done with simple unix commands. XOR the dll :

cat hook.dll | perl -e 'while (sysread STDIN, $_, 1) { print chr(ord^0xff)}'

APP12 segment header and size bytes:

perl -e 'print pack("CCna4", 0xFF, 0xEC, 5126, "JSH")'
  0xFF, 0xEC => APP12 marker
  5126 => 2 (length bytes) + 4 (header - JSH\0 ) + 5120 (length of hook.dll)
  JSH => header bytes.
  “a4” in the pack() format specifier adds the \0 at the end of it.

Everything put together (assuming hook.dll is of size 5120 bytes):

  dd if=background.jpg bs=1 count=20 ;  # copy the jpeg SOI & APP0 
  perl -e 'print pack("CCna4", 0xFF, 0xEC, 5126, "JSH")' ; # Add APP12 marker, size, header 
  cat hook.dll | perl -e 'while (sysread STDIN, $_, 1) { print chr(ord^0xff) }' ;  # our payload 
  dd if=background.jpg bs=1 skip=20 ; # rest of the original jpeg file 
  cat music.wav ; # midi file at the end 
) > new_background.jpg

The riskiest part of the whole experiment was to get the executor code in the app. We tried out several iterations to make this as concise as possible. C# being a very high level and robust language gave us semantics that would have otherwise required a ton more lines in other languages
The hook dll was read from the jpeg file from inside a PropertyChangedCallback that was registered by overriding the metadata of the WPF application’s BackgroundProperty using FrameworkPropertyMetadata. .net also like Java allows for Reflection, allowing you to load a resource, inspect and execute it. In this case the Activator.CreateInstance does the magic, within a static constructor inside the WPF app.

For the curiouser, reverse engineering the above piece of code will give your a crystal clear picture.

This 24 line code was sneaked into the production deployment along with a 20 file change list for a major feature on a Friday evening. The commit mail as usual was read by most of the devs but the feature being complex took the cynosure and most of the code wasn’t seen in the large list. And for those who saw it assumed it to be part of the feature.
Note: This was at a time when we didn’t have version controls like git and people didn’t commit for every small feature. Change list sometimes varied between 10 lines to 25 files during a refactor.

As an exercise here’s the code embedded in a similar image. Try extracting it decompiling. It’s gratifying.

Code embedded in image

I am sure it was an exciting morning, the day the code went into production. But it got really fun when we leaked out some clues and it became the Harlem Shake of its time in that company.

What’s most important is creative exercises like this molded my thought process and it all came back when I finally decided to build a company.

Who knew?

Cucumbertown today is riddled with Easter Eggs. An arms race by us founders to screw time. So perk your ears, let’s have some fun.
Benedict Cumberbatch may like us.


  1. Its been a long time since I’ve coded in C# and chances are that some of the libraries and API calls are outdated
  2. I have left out a lot of minute details like the need for double compiling etc.