Jim Hague and the obfuscation program.

The IOCCC, International Obfuscated C Code Contest, is a competition which goal is to create the most obscure C program. In 1986, Jim Hague won the contest with his (almost) undecipherable morse encryptor. Today, we are going to try and understand how his program works, step by step. Here’s what it looks like:

#define DIT (
#define DAH )
#define __DAH ++
#define DITDAH *
#define DAHDIT for
#define DIT_DAH malloc
#define DAH_DIT gets
#define _DAHDIT char
_DAHDIT _DAH_[]="ETIANMSURWDKGOHVFaLaPJBXCYZQb54a3d2f16g7c8a90l?e'b.s;i,d:"
;main DIT DAH{_DAHDIT
DITDAH _DIT,DITDAH DAH_,DITDAH DIT_,
DITDAH _DIT_,DITDAH DIT_DAH DIT
DAH,DITDAH DAH_DIT DIT DAH;DAHDIT
DIT _DIT=DIT_DAH DIT 81 DAH,DIT_=_DIT
__DAH;_DIT==DAH_DIT DIT _DIT DAH;__DIT
DIT'\n'DAH DAH DAHDIT DIT DAH_=_DIT;DITDAH
DAH_;__DIT DIT DITDAH
_DIT_?_DAH DIT DITDAH DIT_ DAH:'?'DAH,__DIT
DIT' 'DAH,DAH_ __DAH DAH DAHDIT DIT
DITDAH DIT_=2,_DIT_=_DAH_; DITDAH _DIT_&&DIT
DITDAH _DIT_!=DIT DITDAH DAH_>='a'? DITDAH
DAH_&223:DITDAH DAH_ DAH DAH; DIT
DITDAH DIT_ DAH __DAH,_DIT_ __DAH DAH
DITDAH DIT_+= DIT DITDAH _DIT_>='a'? DITDAH _DIT_-'a':0
DAH;}_DAH DIT DIT_ DAH{ __DIT DIT
DIT_>3?_DAH DIT DIT_>>1 DAH:'\0'DAH;return
DIT_&1?'-':'.';}__DIT DIT DIT_ DAH _DAHDIT
DIT_;{DIT void DAH write DIT 1,&DIT_,1 DAH;}

First things first: what happens when we try to compile it with gcc? We see a lot of errors and warnings popping up, mostly about undeclared variables and implicit declarations. This means that the program doesn’t follow C standards in terms of function or variable declarations. Let’s take a closer look.

One of the first things we can see in the program is a long list of preprocessor directives “#define”. The preprocessor is the part of the compiler that gets rid of comments, includes header files and expands macros. What is a macro? it’s an identifier that will be replaced by a piece of code. In our program, for example, we have #define DIT (, this means that every time we will type the macro DIT later on in the program, it will be replaced by the character ‘(‘. We can see there is A LOT of macros in this program, and that’s what makes it messy.

What is source of code obfuscation?

Code obfuscation is the act of deliberately obscuring source code, making it very difficult for humans to understand, and making it useless to hackers who may have ulterior motives. it may also be used to deter the reverse-engineering of software.

Essentially, obfuscation completely alters the source code; nonetheless, it remains functionally equivalent to the original code.

Obfuscation is NOT the same as encryption. The purpose of encryption is to transform data in order to keep it secret from others. The purpose of obfuscation is to make it difficult for humans to understand the data. Encrypted code always needs to be decrypted before execution, while obfuscation does not require that code undergo de-obfuscation to execute it.

What does this code?

Code obfuscation consists of several techniques, each building on top of the other, thus rendering the code unintelligible. Following are a few of the obfuscation techniques that are used.

  1. Rename Obfuscation: Renaming basically modifies the variable and method names, making the code difficult for a human to understand. However, it still maintains the program execution behavior. This basic technique is most commonly used for Android, Java and IOS obfuscators.
  2. String Encryption: While the renaming technique simply alters the variable and method names, string encryption intends to encrypt all the strings that are clearly readable. (You should take note that with this technique, decrypting strings at runtime may incur a minor runtime performance penalty.)
  3. Dummy Code Insertion: This has to do with inserting code into the executable. This technique makes it very difficult for reverse-engineered code to be analyzed. However, the insertions do not affect the logic and/or execution of the program.

Before Obfuscation:

function sayHello(){
console.log("Hello World");
}

sayHello();

After Obfuscation:

var _0x12b3=["\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64","\x6C\x6F\x67"];
function sayHello(){console[_0x12b3[1]](_0x12b3[0])}sayHello()

HolbertonStudent