I see, learn and rediscoverโ€ฆ everyday!
 
Obfuscate C Code – Part I

Obfuscate C Code – Part I

Hello, this is the first post I’m writing on C code obfuscation. Let me warn you before I start. I am a beginner in code obfuscation and still learning from different code snippets I get from my friends.

Since this is the first post in this series, we will start with hello world. But instead of printing the same old hello world, we will print the quote “He that falls in love with himself will have no rivals.”, quoted by Benjamin Franklin.

We need a simple base program to start with right? The following code prints the quote.

#include
int main() {
char s[123] = "He that falls in love with himself will have no rivals.";
printf("%s", s);
return 0;
}

Surely, that is not the obfuscated code. First, let us convert the string into character array and instead of printing the string, we print the character array. Simple right? So the code now looks like this.

#include
int main() {
int i;
char s[] = {'H','e',' ','t','h','a', 't', ' ', 'f', 'a', 'l', 'l', 's', ' ', 'i', 'n', ' ', 'l', 'o', 'v', 'e', ' ', 'w', 'i', 't', 'h', ' ', 'h', 'i', 'm', 's', 'e', 'l', 'f', ' ', 'w', 'i', 'l', 'l', ' ', 'h', 'a', 'v', 'e', ' ', 'n', 'o', ' ', 'r', 'i', 'v', 'a', 'l', 's', '.'};
for (i=0; i<55; i++) {
printf("%c", s[i]);
}
return 0;
}

Next step, we take the two variables “i” and “s” outside the main. Since now the two variables are in global scope, if we don’t define the data type, it is an integer by default. Since we can define a character array as an integer array, we need not provide the datatype for both the variables. So now the code looks like this. Also we can change “int main” to “main” and remove the “return 0;” statement.

Note:: This idea of not defining the data type shouldn’t be used if you are practising for IOCCC. In there, the guidelines clearly states the following.
When declaring local or global variables, you should declare the type:

int this_is_ok;
this_is_not; <-- don't use such implicit type declarations

i, s[] = {'H','e',' ','t','h','a', 't', ' ', 'f', 'a', 'l', 'l', 's', ' ', 'i', 'n', ' ', 'l', 'o', 'v', 'e', ' ', 'w', 'i', 't', 'h', ' ', 'h', 'i', 'm', 's', 'e', 'l', 'f', ' ', 'w', 'i', 'l', 'l', ' ', 'h', 'a', 'v', 'e', ' ', 'n', 'o', ' ', 'r', 'i', 'v', 'a', 'l', 's', '.'};
main() {
for (i=0; i<55; i++) {
printf("%c", s[i]);
}
}

Next, we remove the 55 to the size of the array. We need to replace 55 by “sizeof(s)/sizeof(int)”. Let us do that in a better way as shown below. The two preprocessor statements added below to replaces ck by sizeof(s)/sizeof(int). The point to note here is that we have added the preprocessor statements in between the for statement.


i, s[] = {'H','e',' ','t','h','a', 't', ' ', 'f', 'a', 'l', 'l', 's', ' ', 'i', 'n', ' ', 'l', 'o', 'v', 'e', ' ', 'w', 'i', 't', 'h', ' ', 'h', 'i', 'm', 's', 'e', 'l', 'f', ' ', 'w', 'i', 'l', 'l', ' ', 'h', 'a', 'v', 'e', ' ', 'n', 'o', ' ', 'r', 'i', 'v', 'a', 'l', 's', '.'};
main() {
for (i=0;
#define f(z) sizeof(z)
#define ck f(s)/f(int)
i<ck; i++) {
printf("%c", i[s]);
}
}

Since i is a global variable, we need not initialize the value to 0. Again, we can remove the i++ statement by changing s[i] to s[i++]. And also note that a[i] and i[a] are both the same. So we can use i++[s]. So the code now becomes

i, s[] = {'H','e',' ','t','h','a', 't', ' ', 'f', 'a', 'l', 'l', 's', ' ', 'i', 'n', ' ', 'l', 'o', 'v', 'e', ' ', 'w', 'i', 't', 'h', ' ', 'h', 'i', 'm', 's', 'e', 'l', 'f', ' ', 'w', 'i', 'l', 'l', ' ', 'h', 'a', 'v', 'e', ' ', 'n', 'o', ' ', 'r', 'i', 'v', 'a', 'l', 's', '.'};
main() {
for (;
#define f(z) sizeof(z)
#define ck f(s)/f(int)
i<ck;
)
printf("%c", i++[s]);
}

Next, we remove the extra spaces so that the code is “poorly” aligned, as shown below. Also, now, we can replace the variable names by _ and __ etc. I haven’t done much to the character array here. That is not the aim of this post. Will write a separate post on manipulating strings. But for now, we can convert the character array to hexadecimal or octal numbers. ๐Ÿ˜‰ (This is not the best way to obfuscate it though).

So the final code looks something like this.

#define ____(z) sizeof(z)
_, __[] = {0x48, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x66, 0x61, 0x6c, 0x6c, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x68, 0x69, 0x6d,0x73, 0x65, 0x6c, 0x66, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20,0x68, 0x61, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x20, 0x72, 0x69, 0x76, 0x61, 0x6c, 0x73, 0x2e}; main() { for (;
#define ___ ____(__)/____(int)
_<___;) printf("%c", _++[__]);}

All suggestions on still screwing up this code are welcome. ๐Ÿ˜‰

Update: You can download all the C files as a single zip file here.

11 Comments

  1. well u can make the displaying of strings recursive … make one bottom up recursion for printing from middle to start and one top down recursion from middle to end . further more u can write your own printf and scanf functions to print the characters. I have written them once for my lab ex.. i think this wud add more flavour to obfuscation ๐Ÿ˜›

Leave a Reply to Bharath Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.