IOCCC image by Matt Zucker

The International Obfuscated C Code Contest

obfuscation.html for 2015/burton

Deobfuscation

calc is a recursive-descent parser. It allocates from the stack deep enough that all expressions are exhausted before the recursion stack depth reaches the allocations. The memory map and source is documented in src.doc.txt. Tokens are encoded using values 0-20, where 0 is an invalid token, 1 is minus, 2 is space, 3 is plus, etc. The necessary constants are derived at the start of the program, using the guarantee that globals are initialized to zero; so a correct NULL pointer is obtained from an uninitialized global pointer variable, and the integers from uninitialized global int variables. If x is a global int, then !x is 1, and the derivation proceeds from there, using some identities that are confusingly similar and interestingly combined (increasing obfuscation):

    obc    clr
    ---    ---
    -~x    x+1
    ~-x    x-1
    y-~x   y+x+1

The derived constants are a compromise between simple expressions, maximum utility, and minimum number of variables used.

Command line arguments are copied into the upper half of the input buffer, separated by a space. This allows the code to have a single input parser by using a pointer-to-func to either getchar(3) if live, or a getchar(3) simulator.

A small amount of obfuscation comes from void functions declared int, but missing return. This is necessary to allow these functions in ternary ?: expressions and paired with && and ||; but the requisite returns would add symbol count at no benefit to obscurity or functionality. Function decomposition was mostly chosen to avoid curly braces: if a for-loop required multiple statements, the body became a new function. Last, but not least: sharing state via global variables is an ancient and honored form of obfuscation, and remarkably effective.


Jump to: top