Obfuscated C

Originally published on: Tue, 21 Apr 2009 23:51:27 +0000

I had written a little C program a while back for the 19th annual International Obfuscated C Coding contest.

Not only did my code not win … it didn’t even warrant an entry in the honorable mentions or anything like that. If you look at the winners and look back at my code, you’ll immediately see why; the winners and the runners-up were much more creative than my effort.

Rather than get lost in obscurity, I felt that my entry needed to be published, so it has been given the honor of appearing in my first public blog post.

Everyone, please meet lawless.c … a ROT-13 encoder/decoder that encodes/decodes one line at a time:

// Copyright (c) 2009 by Jim Lawless
#include <stdio.h>
#include <ctype.h>

char *z="DCFEBA";
int zzz;
void zzzzzzzzz(void) { zzz=zzz; }
typedef void (*ZZ)(void);
#define I
void zzzzzzz(void) { z-=6; }
#define r(x) isalpha(x) ? tolower(x)>'m' ? x-'\r' : x+'\r' : x
void zzzzzz(void) { if(!(zzz-10)) { z++; z++; } }
#define o(x) Z[*z-'A']();
#define t(x)
void zzzz(void) { zzz=fgetc(stdin); }
#define a(x) for(;*z;z++)
void zzzzz(void) { zzz=r(zzz); }
#define s(x)
void zzzzzzzz(void) { fputc(zzz,stdout); }

ZZ Z[12]={ zzzzzzz, zzzzzzzz, zzzz, zzzzzzzzz, zzzzzz, zzzzz };

int main() {

I s(lit) t(he) s(heet) t(he) s(heet) I s(lit) a(nd)
o(n) t(he) s(litted) s(heet) I s(it)
}

The rules for the 19th annual competition had noted that C preprocessor tricks might just as well not be used as each entry would be run through the preprocessor for expansion.

Here’s what the above code would look like after preprocessing;

char *z="DCFEBA";
int zzz;
void zzzzzzzzz(void) { zzz=zzz; }
typedef void (*ZZ)(void);

void zzzzzzz(void) { z-=6; }

void zzzzzz(void) { if(!(zzz-10)) { z++; z++; } }

void zzzz(void) { zzz=fgetc((&amp;_iob[0])); }

void zzzzz(void) { zzz=(__mb_cur_max &gt; 1 ? _isctype(zzz,(0x0100|0x1|0x2)) : _pctype[zzz] &amp;amp; (0x0100|0x1|0x2)) ? tolower(zzz)&gt;'m' ? zzz-'\r' : zzz+'\r' : zzz; }

void zzzzzzzz(void) { fputc(zzz,(&amp;_iob[1])); }

ZZ Z[12]={ zzzzzzz, zzzzzzzz, zzzz, zzzzzzzzz, zzzzzz, zzzzz };

int main() {

for(;*z;z++)
Z[*z-'A']();
}

I tried to use preprocessor abuse to get my cutesy “I slit the sheet…” lines into view … but the core of the processing was done via indirect invocation of entries in an array of function-pointers.

 

Advertisements

About Jim Lawless

I've been programming computers for about 36 years ... 30 of that professionally. I've been a teacher, I've worked as a consultant, and have written articles here and there for publications like Dr. Dobbs Journal, The C/C++ Users Journal, Nuts and Volts, and others.
This entry was posted in Computers, Programming and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s