Question

Can you explain how does the following code work?

main(O){10<putchar(4^--O?77-(15&5128>>4*O):10)&&main(2+O);}

Output:

EMIL

You can test it on Ideone. I have found this line on unwind's profile.

Was it helpful?

Solution

Deobfuscation can easily be done in a step-by-step basis.

White-space always helps:

main(O)
{
  10 < putchar(4 ^ --O ? 77 - (15 & 5128 >> 4 * O)
                       : 10)
  && main(2+O);
}

Add a variable:

main(O)
{
  int i = 4 ^ --O ? 77 - (15 & 5128 >> 4 * O)
                  : 10;
  i = putchar(i);
  10 < i && main(2+O);
}

Replace ?: with if-else:

main(O)
{
  int i;
  if (4 ^ --O)
    i = 77 - (15 & 5128 >> 4 * O)
  else
    i = 10;
  i = putchar(i);
  10 < i && main(2 + O);
}

Replace && with if:

main(O)
{
  int i;
  if (4 ^ --O)
    i = 77 - (15 & 5128 >> 4 * O)
  else
    i = 10;
  i = putchar(i);
  if (10 < i)
    main(2 + O);
}

Brackets for clarity:

main(O)
{
  int i;
  if (4 ^ --O)
    i = 77 - (15 & (5128 >> (4 * O)))
  else
    i = 10;
  i = putchar(i);
  if (10 < i)
    main(2 + O);
}

From here it's a simple case of applying basic C knowledge of operators.

Run through the code: (initial parameter of main is 1, we can check this)

main(1)
  4 ^ 0 = 4 = true
    5128 >> 4 * 0 = 5128
    15 & 5128 = 8
    i = 77 - 8 = 69
  putchar(69) -> 'E'
  10 < 69
    call main(2+0)
main(2)
  ...

How whomever wrote it came up with it? Well, to my knowledge, that's mostly a mystery when it comes to obfuscated code.

OTHER TIPS

If you translate the code into nicer C, then it could look like this:

int main(int i)
{
    int ch;

    i--;
    if (i ^ 4)
        ch = 77 - (15 & (5128 >> (4 * i))); 
    else
        ch = 10;

    ch = putchar(ch);
    if (ch > 10)
        main(i + 2);

    return 0;
}

Note:

  • main() is called recursively for each character.
  • putchar() on success returns the character is just wrote to the console.
  • Printing a newline (ASCII code 10) is the condition to stop the recursion.
  • The original code depends on the old C rule that undeclared variable are of type int.
  • The variable i has the value 1 on the first call (it's in fact the argc argument).
  • For the first if, the variable i has the values 0, 1, 2, 3, 4 in the five iterations. For the value 4, the if condition becomes false and the newline (ASCII 10) is used.
  • The expression 77 - (15 & (5128 >> (4 * i))) produces the ASCII codes for the letters E, M, I, L for the i values 0, 1, 2, 3.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top