你能解释一下下面的代码是如何工作的吗?
main(O){10<putchar(4^--O?77-(15&5128>>4*O):10)&&main(2+O);}
输出:
EMIL
你能解释一下下面的代码是如何工作的吗?
main(O){10<putchar(4^--O?77-(15&5128>>4*O):10)&&main(2+O);}
输出:
EMIL
反混淆可以很容易地逐步完成。
空白总是有帮助的:
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);
}
替换&&
为如果:
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,我们可以查看这个)
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)
...
写它的人是怎么想出来的?好吧,据我所知,当涉及到混淆代码时,这主要是一个谜。
如果你把代码翻译成更好的 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()
成功返回时,字符只是写入控制台。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 代码。