为什么1987 Korn oneliner打印unix?

chx*_*chx 11 c deobfuscation

好的,我会咬人的.大众流行的答案为什么C预处理器将单词"linux"解释为常量"1"?问题提到

main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}`
Run Code Online (Sandbox Code Playgroud)

打印"unix",但原因与宏名称的拼写完全无关.

我阅读http://www.ioccc.org/1987/korn.hint,但我认为更多的细节将有助于不混淆这:)

glg*_*lgl 12

unix由于#define编译器或运行时环境中的隐式,因此为1 .

因此,a[b] == b[a] == *(a + b)因此1["xy"] == "xy"[1],你得到:

  • &unix["\021%six\012\0"] 指着 "%six\012\0"
  • (unix)["have"] = "have"[1] = 'a',
  • "'a'+"fun"-0x60" = "fun" + 1 = "un".

这导致你printf("%six\012\0", "un");明显打印"unix\012",\012是一个换行符(相同\n).

如果unix未定义,例如在Windows系统上,则会出现错误.

如果unix0(那可以成为一个清洁系统的方式吗?),你得到

printf("\012%six\n", 'h'+"fun"-0x60)
Run Code Online (Sandbox Code Playgroud)

第二个参数是"fun"+8指向Nirvana并导致未定义的行为.