IOCCC image by Matt Zucker

The International Obfuscated C Code Contest

2014/skeggs - Most dynamic

dynamic library abusing game

Author:

To build:

    make

To use:

    ./prog

HINT: Try pressing the left and right arrow keys as needed. Also try pressing space/enter to select options. Pressing Q or Escape may end the fun before you are ready. :-)

Judges’ remarks:

When the code looks like lemons, it is probably because the LEMONPEOPLE, or at least the LEMONLORD was involved. :-)

Look at some of the C pre-processor macros in the source code. Ask yourself why C source is being passed as arguments to some of those macros.

Now you may observe, while it is running, that some C source code is being written to a file and then compiled. And yet that compiled code is somehow executed from main(). But how? How is main() able to call code that was written and compiled just in time for execution?

Author’s remarks:

TABLE OF CONTENTS

BACKSTORY

It was ten yours ago when THE LEMONPEOPLE invaded, juicing all in their path.

Attempting to free the Earth from their tyranny, you have endured pulpy and sour battles.

This has now culminated in you reaching the throne room of THE LEMONLORD.

Armed with your right-facing curly brace, you charge into battle.

(Use left and right arrow keys and space/enter to select options. Press Q or Escape to quit.)

KNOWN COMPILER WARNINGS

Unfortunately, it became very difficult to get this entry to fit within the size requirements. It’s currently at 2052 according to iocccsize, and 3994 according to wc -c.

The current size is a third to a half of the original size before compression.

Due to this, it does LOTS of things that subtly annoy compilers!

OBFUSCATION? WHAT OBFUSCATION? THIS IS A PERFECTLY NORMAL C PROGRAM!

THE COOL PART

Take a close look at how it works. Notice that it’s passing C code to certain macros…

Guess what? It’s a very simple kind of JIT compiler, though not used as deeply as would be cool.

Essentially, it generates C code at runtime, dumps it to a file, and then runs a C compiler on that file, telling the C compiler to generate a shared library. Then it loads the shared library with dlopen(3), and…

Ignores the result?

That can’t be right.

Well, it is. Instead of using dlsym(3) like a normal programmer, I mark one of the generated functions with __attribute__((constructor)). This means that it gets called immediately on load, so it can make its functions available.

But wait - how can it link into the main program, either? It has no way to reference anything in the main executable!

But it does: I’m injecting certain addresses into the generated code, which it then casts to pointers and accesses! It uses this to make certain functions available to the main program, so the main program’s generated code will then enter itself where it’s needed.

THE NOT-SO-COOL PART

There are also lots of #defines.

No, these are not obfuscation. These are compression.

There is a little bit of obfuscation gained from using the stringification operator. (I can never remember what it’s actually called, but it’s the # operator in a preprocessor macro) - this allows me to pass C code in arguments to the macros, meaning that it gets interpreted as C code instead of a string by the iocccsize tool, so it gets counted as smaller! :D

A SLIGHTLY COOL PART

As part of the JIT compiling, the program hides the fact that it needs ncurses: it just links ncurses with one of the generated shared libraries, and then can access the contents of the ncurses library!

WAIT WHAT

Also, note where functions start and end…

I’ve messed with the syntax so that it’s not actually formatted properly. It almost looks like it is, but it isn’t.

This isn’t significant obfuscation as long as you run it through a C source code beautifier.

But wait… if you aren’t careful, running it through a C source code beautifier won’t work. Remember how I’m interlacing generated C code with actual C code? Note that this WRECKS some beautifiers. I hope you have a good one!

(There’s an obvious way around this but I’m not going to spell it out for you. That’d be too easy!)

MISCELLANEOUS STUFF

Do note that there are some other miscellaneous obfuscations, but they should be easy to understand once you figure out the ones above.

TROUBLESHOOTING GUIDE

This program is a very easy program to cause to fail!

Some things to check

I’ve tested it on the following platforms, in case you need to try it on one:

I ran out of time to test it on more systems.

Q&A

    $ ./iocccsize -i < README.md
    6057

Inventory for 2014/skeggs

Primary files

Secondary files


Jump to: top