【问题标题】:Why does the 1987 Korn oneliner print unix? [closed]为什么 1987 年的 Korn oneliner 打印 unix? [关闭]
【发布时间】:2013-10-18 09:22:56
【问题描述】:

好的,我会咬人的。对广受欢迎的Why does the C preprocessor interpret the word "linux" as the constant "1"? 问题的answer 提到了这一点

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

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

我阅读了http://www.ioccc.org/1987/korn.hint,但我认为更多细节将有助于澄清这一点:)

【问题讨论】:

  • 这个“问题”提出了一个难题,而不是一个问题。
  • @EricPostpischil 现在一个谜题可能会让人们感到困惑,如果人们感到困惑,他们往往会提出问题。

标签: c deobfuscation


【解决方案1】:

unix 为 1,因为编译器或运行时环境中存在隐式 #define

因此,因为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 未定义,例如。 G。在 Windows 系统上,您会收到错误消息。

如果 unix0(在干净的系统上可以这样吗?),你会得到

printf("\012%six\n", 'h'+"fun"-0x60)

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

【讨论】:

    【解决方案2】:

    通常我认为只有在类 unix 系统下编译时才应该打印“unix”。

    这是因为在此类系统上,unix 是一个预定义宏,其值为1

    因此,它翻译为:

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

    重新排序处理int[array]的废话,我们得到:

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

    我们可以忽略\021,因为它已被跳过(我将用? 替换它),并将\012 翻译成\n

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

    这给出了:

    main() { printf("%six\n", "un"); }
    

    注意:我正在重新解决它(尤其是第二部分),但我第一次看到它时需要两个提示才能理解解释:

    • unix 表示 1
    • int[array] 是编译器接受的实际符号。

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      • 2010-11-06
      相关资源
      最近更新 更多