Author Topic: Obsfucated C Code  (Read 4675 times)

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Obsfucated C Code
« on: September 20, 2009, 03:35:08 AM »
Best one liner winner of the 1987 International Obsfucated C Code Contest:

Code: [Select]
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}


Anyone care to take a stab at it?
 

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3238
Obsfucated C Code
« Reply #1 on: September 20, 2009, 11:03:18 AM »
That's easy.  It transformers your computer in2 TEH MES HAL.  BLARYEUGH!
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Obsfucated C Code
« Reply #2 on: September 20, 2009, 04:21:25 PM »
Odd thing about C, is that the array indexing operator [] is commutative:
array
i[array]

They both mean the same thing.


Hence the following two are the same:
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
main() { printf(&("\021%six\012\0"[unix]),("have"[unix])+"fun"-0x60);}
 

Offline vennom

  • Jr. Member
  • **
  • Posts: 73
Obsfucated C Code
« Reply #3 on: September 25, 2009, 11:53:01 AM »
thats why i use delphi...

Offline CK9

  • Administrator
  • Hero Member
  • *****
  • Posts: 6226
    • http://www.outpost2.net/~ck9
Obsfucated C Code
« Reply #4 on: September 25, 2009, 04:18:52 PM »
I don't remember enough about the C++ class I took to even know what you're asking about, lol

 
CK9 in outpost
Iamck in runescape (yes, I still play...sometimes...)
srentiln in minecraft (I like legos, and I like computer games...it was only a matter of time...) and youtube...
xdarkinsidex on deviantart

yup, I have too many screen names

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Obsfucated C Code
« Reply #5 on: September 26, 2009, 01:31:57 PM »
Basically, figure out what the code does and why.

As an additional hint, the code is meant to be compiled and run under Linux/Unix. It was also meant to be used with a C compiler. If you use a C++ compiler, you'll need to add an include. If you're using MSVC, then you'll need to add an include, and define a value.
 

Offline Moley

  • Jr. Member
  • **
  • Posts: 95
Obsfucated C Code
« Reply #6 on: September 27, 2009, 10:43:08 AM »
so what is said include?
I HATE SPELLING!!!!!!
if i spell something or screw up grammer,
ignore it or tell me if you dont understand what i typed.

Offline CK9

  • Administrator
  • Hero Member
  • *****
  • Posts: 6226
    • http://www.outpost2.net/~ck9
Obsfucated C Code
« Reply #7 on: September 27, 2009, 12:48:30 PM »
okay, let's see...

it prints something out... Unix has to be an int variable by default....the "%six" and the "fun" are standing out the most to me...

I find it funny that you can spell unix by taking off the "f" and the "%s" and merging them together, heh
CK9 in outpost
Iamck in runescape (yes, I still play...sometimes...)
srentiln in minecraft (I like legos, and I like computer games...it was only a matter of time...) and youtube...
xdarkinsidex on deviantart

yup, I have too many screen names

Offline Hidiot

  • Hero Member
  • *****
  • Posts: 1018
Obsfucated C Code
« Reply #8 on: September 27, 2009, 01:33:25 PM »
in C++ % and a specific letter designates the type of input/output...

Maybe %s, followed by ix does something in C?

*Yay for wild guesses).
"Nothing from nowhere, I'm no one at all"

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Obsfucated C Code
« Reply #9 on: September 27, 2009, 02:43:40 PM »
The include is:
#include <stdio.h>

That's so printf is available. It's needed by MSVC 6.0 to compile the code, but isn't needed by gcc under Linux.


I'm thinking CK9 and Hidiot basically have it.

If unix = 1, then you're indexing into the strings starting at the position 1 (instead of 0). The next part is to realize the difference between using "&" and not using it. Then rearrange an expression, and check an ASCII table.
 

Offline Hidiot

  • Hero Member
  • *****
  • Posts: 1018
Obsfucated C Code
« Reply #10 on: September 28, 2009, 02:08:36 AM »
All I know about & is that it is used to retrieve the address of the variable it is attached to.

Now, I'm still not sure what the output looks like. Due to all the &'s and the address offset it could output an address value. But I know that ASCII tables link characters to numbers... So maybe there's something about & I'm not aware of (no surprise).
"Nothing from nowhere, I'm no one at all"

Offline CK9

  • Administrator
  • Hero Member
  • *****
  • Posts: 6226
    • http://www.outpost2.net/~ck9
Obsfucated C Code
« Reply #11 on: September 28, 2009, 10:01:55 AM »
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}

unix = 1, offset starting point....a...a = 97...0x60 = 96....

rearrange...97 - 96 + "fun"? ..............1 + fun...
...rearrange to (1 + "fun",&unix["\021%six\012\0"]) ?

(1 + "fun",&1["\021%six\012\0"]).....
« Last Edit: September 28, 2009, 10:02:10 AM by CK9 »
CK9 in outpost
Iamck in runescape (yes, I still play...sometimes...)
srentiln in minecraft (I like legos, and I like computer games...it was only a matter of time...) and youtube...
xdarkinsidex on deviantart

yup, I have too many screen names

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Obsfucated C Code
« Reply #12 on: September 29, 2009, 02:27:28 AM »
Hmm, that answer seems a bit obsfucated, but you seem to have it.

main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
main() { printf(&("\021%six\012\0"[unix]),("have"[unix])+"fun"-0x60);}
main() { printf("%six\012\0", 'a' + "fun" -0x60);}
main() { printf("%six\012", "fun" + 'a' - 0x60);}
main() { printf("%six\n", "fun" + 0x61 - 0x60);}
main() { printf("%six\n", "fun" + 1);}
main() { printf("%six\n", "un");}
main() { printf("unix\n");}

The "\0" is redundant, as C strings will already be redundant, so you can just drop that.

The "\012" is an octal code. This has value 1*8^1 + 2 * 8^0 = 8 + 2 = 10. Most people would recognize 0xD, 0xA, or 13, 10 a little easier as the CR and LF characters. So basically, it's an end of line character. Remeber that Windows uses both CR and LF for line termination, while Linux only uses one of them. (And Mac uses the other, apparently).

Indexing into a char* yields a char. That is, "have"[1] = 'a'. Here we turned a string into a char value, which is basically an integer in nature.

Indexing into a char*, getting a char, and then taking the address of it gives back a char*. Hence &"\0x21%six\0xA"[1] = "%six\0xA". So we still have a string in that case.

Checking an ASCII code table, a capital 'a' has value 97 = 0x61. Rearrange the terms,  as they are commutative and associative, and you can do some constant folding (0x61 - 0x60) = 1.

Remember that strings and arrays degenerate to a pointer to the base type. Adding a constant to a pointer, is like indexing into an array. So a + i, is equivalent to a, if a is a pointer type. Note that the actual addition to the address stored in a is scaled by the size of a. If it's a char*, then +1 will actually be +1 to the byte address of a. If a was a short*, then a+1 would actually be +2 to the byte address of a (1 element past the position of a). This later point is irrelevant here, as the string (which degenerates to a pointer to a char), has an element size of 1 byte, but nevertheless, it's an interesting point. So, "fun" + 1 = "un". That is, bump the address of the start of your string up by one, and use that address, so now you have the address of the char (array) starting at "un".
 

Offline Hidiot

  • Hero Member
  • *****
  • Posts: 1018
Obsfucated C Code
« Reply #13 on: September 30, 2009, 09:20:07 AM »
Doesn't this go under bad programming practices?
I mean, making such a simple command so complex without changing anything?

Anyway, was interesting.
"Nothing from nowhere, I'm no one at all"

Offline CK9

  • Administrator
  • Hero Member
  • *****
  • Posts: 6226
    • http://www.outpost2.net/~ck9
Obsfucated C Code
« Reply #14 on: September 30, 2009, 09:20:43 AM »
soo...what I thought was a funny coinncidence was actually the whole purpose?
CK9 in outpost
Iamck in runescape (yes, I still play...sometimes...)
srentiln in minecraft (I like legos, and I like computer games...it was only a matter of time...) and youtube...
xdarkinsidex on deviantart

yup, I have too many screen names

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Obsfucated C Code
« Reply #15 on: September 30, 2009, 11:34:43 PM »
Pretty much.


Actually, this reminds me of another code obsfucation technique with naming variables. Don't just name them meaningless names, like var1, var2, var3, .... Instead, give them names with the wrong meaning, like superman, toaster, alarmClock, .... These are much more confusing than meaningless names.

I say this because of the "%six" part. The "%s" code means to take one of the following parameters as a string and insert it here, and after that's done, it continues echoing/scanning the format string for more codes, hence printing the "ix" (echoed, as it isn't a % escape code). But when looking at it, "six" has a meaning, and so we tend to associate those characters together, rather than properly "parsing" the tokens into the groups (%s)(ix).


As for other wonderful variable naming conventions, you can use names like "swimner", or "swimrner", instead of "swimmer", as it's very hard to distinguish those with certain fonts. Or swapping around o0O. Or, in some older languages, where the identifier names have some max length, and any characters after that are ignored, keep changing the suffix after the max length. They appear to people to be different variables, but the compiler chops off that part before examing them so they're all the same.


Oh, and cookie to the first person that can find code to compute square roots, where the code itself, with proper placing of whitespace, looks like an image of a square root symbol.
« Last Edit: September 30, 2009, 11:35:09 PM by Hooman »

Offline CK9

  • Administrator
  • Hero Member
  • *****
  • Posts: 6226
    • http://www.outpost2.net/~ck9
Obsfucated C Code
« Reply #16 on: October 01, 2009, 09:31:47 AM »
when I saw %six I instantly thought "modulus six" as I don't remember ever seeing a %s operator....
CK9 in outpost
Iamck in runescape (yes, I still play...sometimes...)
srentiln in minecraft (I like legos, and I like computer games...it was only a matter of time...) and youtube...
xdarkinsidex on deviantart

yup, I have too many screen names

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Obsfucated C Code
« Reply #17 on: October 02, 2009, 12:09:45 AM »
It's not an operator, it's a formatting code understand by the printf family of functions. That includes printf, sprintf, snprintf, fprintf, and a few more. They all take a format string, and they output that format string verbatim, except when they encounter certain % codes. When they encounter a format code, they match it up with one of the following parameters, which they then print according to the code. As the format string can contain an arbitrary number of format codes, all these functions are variadic (they take a variable number of arguments).

Code: [Select]
int printf(const char *format, ...);  // Note the ... for the variable number of args


printf("Hello World");  // Just the format string, no additional arguments

// Insert two variable strings into a fixed format string
printf("Message Title: %s\n Message Body:\n%s\n", title, message);

// Insert numbers into a string
printf("You have %i new messages.\n", numNewMessages);

// Display a number followed by a literal % symbol
printf("Formating spammer's hard drive: %i%% complete.", i);

// Display both strings and numbers
printf("%i %s have died.", numPeople, colonistType);

You may note there are two different escape codes being used in there. The "\n" is processed by the C compiler and translated into a new line character. This is in contrast to the % escape codes, which are only understood by the printf function, not by the C compiler. By the time printf gets those strings, the "\n" characters have already been translated (during the compilation step). The printf function must then translate the % escape codes (during runtime). You'll note that whenever you use escape codes, it interferes with usage of the escape code for non-special purposes. To deal with this, most implementations that use escape codes will have an escape code for the escape code. Hence, the C compiler uses "\\" to print a slash, so if you wanted a literal "\n" in a string, without it being escaped into a newline character, you'd write it as "\\n". Similarly, to print a "%" symbol with printf, you'd escape it with an extra % and end up with "%%". In a related issue, quotation marks which delimit the start and end of strings also need to be escaped if they're to appear in the string: "\"".


Btw, since the C compiler doesn't understand the format strings (only the printf family of functions do), it can't perform any type checking of the string against the supplied arguments. Hence, if you do strange things like the following:
Code: [Select]
// The compiler is unable to warn of these
printf("%s", someStringVariable);  // Print the string  (demo of correct usage)
printf("%i", someStringVariable);  // Print the address of the string (in decimal)
printf("%x", someStringVariable);  // Print the address of the string (in hex)
printf("%f", someStringVariable);  // Interpret the address of the string as a floating point value and print that floating point value (bug!)

// These are bad and should almost certainly generate a warning, if only the compiler could
printf("%i", 1, 2, 3);  // Ignoring some parameters. (bad)
printf("%i");  // Try to print a non-existent parameter.  (very bad)

// This is just plain unsafe
printf(stringVariable);  // ... (very very bad)

That last one probably needs a bit of explaination. Compare it to the "Hello World" example at the top, and it seems quite natural. If have a string you want to print, and it echoes the format string, just print it as the format string. Sure..., unless that string just happens to have unexpected format codes embedded in it. If that comes from user input, or worse, a network packet, then it can poke around all the values on the stack and display them however the person who constructed that string wants. This could reveal a lot of potentially sensitive information. Or, it can be used to obtain information useful to creating a remote exploit, like how far away the return address on the stack is. By printing your stack contents as a series of hex values (%x), they could examine the output to see about where the stack pointer lies. What's even worse, is the %n code, which writes the number of bytes output so far into (what it assumes to be) an integer pointer. This could allow an attacker to write a value of their choosing to some part of your stack, overwriting a local variable. Who knows what that could accomplish.


Of course, you are right that % is a modulus operator in C, however, if you consider they way things are parsed, anything within a string can't be an operator.
 

Offline CK9

  • Administrator
  • Hero Member
  • *****
  • Posts: 6226
    • http://www.outpost2.net/~ck9
Obsfucated C Code
« Reply #18 on: October 02, 2009, 09:21:22 AM »
leave it to hooman to teach a class to explain the different roles of a symbol in coding, :P

I do appreciate the explanation, though
CK9 in outpost
Iamck in runescape (yes, I still play...sometimes...)
srentiln in minecraft (I like legos, and I like computer games...it was only a matter of time...) and youtube...
xdarkinsidex on deviantart

yup, I have too many screen names

Offline Hidiot

  • Hero Member
  • *****
  • Posts: 1018
Obsfucated C Code
« Reply #19 on: October 02, 2009, 09:57:43 AM »
That's why I like Hooman.
"Nothing from nowhere, I'm no one at all"

Offline Moley

  • Jr. Member
  • **
  • Posts: 95
Obsfucated C Code
« Reply #20 on: October 02, 2009, 12:44:31 PM »
Oh duh...
and i just looked that up not 2 weaks ago...
though i did not know that the index and the identifer where interchangable.
 
I HATE SPELLING!!!!!!
if i spell something or screw up grammer,
ignore it or tell me if you dont understand what i typed.