这个混淆的C行如何打印“EMIL”?

时间:2013-08-08 11:08:31

标签: c deobfuscation

您能解释以下代码的工作原理吗?

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

输出:

EMIL

您可以在Ideone上进行测试。我在unwind的个人资料中找到了这一行。

2 个答案:

答案 0 :(得分:7)

可以轻松地逐步进行反混淆。

白色空间总是有帮助:

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

添加变量:

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

?:替换为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);
}

&&替换为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);
}

明确括号:

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);
}

从这里开始,这是一个应用运算符的基本C知识的简单案例。

运行代码:( main的初始参数为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)
  ...

是谁写的呢?嗯,据我所知,当谈到混淆代码时,这几乎是个谜。

答案 1 :(得分:5)

如果您将代码转换为更好的C,那么它可能如下所示:

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;
}

注意:

    为每个角色递归调用
  • main()
  • putchar()成功返回后,该字符只是写入控制台。
  • 打印换行符(ASCII码10)是停止递归的条件。
  • 原始代码取决于旧的C规则,即未声明的变量属于int类型。
  • 变量i在第一次调用时的值为1(实际上是argc参数)。
  • 对于第一个if,变量i在五次迭代中的值为0,1,2,3,4。对于值4,if条件变为false并使用换行符(ASCII 10)。
  • 表达式77 - (15 & (5128 >> (4 * i)))i值0,1,2,3生成字母E,M,I,L的ASCII代码。