【问题标题】:Why does this command crash cmd?为什么这个命令会导致 cmd 崩溃?
【发布时间】:2020-02-22 01:53:23
【问题描述】:

我遇到了一个令人兴奋的weird script,它使控制台崩溃

set "h=/?" & call [if | for | rem] %%h%%

@jeb指出CALLdoesn't execute the following special characters,而是将它们转换为“令牌”(取决于版本):

  • & 返回/
  • && 返回1
  • | 返回2
  • || 返回0
  • /? 返回<
  • @ 返回+
  • @() 返回;

  • @if a==a : 返回,
  • @for %a in () do : 返回+
  • @rem : 返回-

然而,即使它们有独特的解析器,它仍然不能解释为什么它们都会崩溃。所以我做了一些测试:

  • 删除call
    C:\>set "h=/?" & for %h%
    %%h%% was unexpected at this time.
  • 将命令更改为其他内容。 (我尝试了所有其他内部命令,没有一个有效)
  • 分开两个命令:
    C:\>set "h=/?"
    C:\>call for %%h%%
    --FOR help message--
  • 添加@
    C:\>set "h=/?" & call for @%%h%%
    CRASH!!!
  • ()包围脚本块
    C:\>set "h=/?" & call for (%%h%%)
    CRASH!!!

问题摘要

  • call 起什么作用?
  • 是什么导致解析器崩溃?

【问题讨论】:

  • 为什么不问问那个脚本的作者@npocmaka? (虽然我猜,它被列在“bugs”下是有原因的)
  • 投反对票的不是我。我为什么要?我刚刚提到了作者,以最大限度地提高您获得答案的机会。三周前?我不记得了(可能不是)。如果你告诉我哪个 Q/A,我会告诉你。

标签: cmd


【解决方案1】:

CALL 是启动第二轮解析器所必需的。

但是有一个小错误(或更多),在该阶段无法执行任何特殊命令或使用&|&&||、重定向或命令块。

原因似乎是,解析器在内部构建了一个标记图,将特殊的东西替换为某种标记值。
但是对于CALL,执行者不再知道如何处理它们。

这段代码试图执行一个名为3.bat的批处理文件!!!
(名称可能不同,取决于 Windows 版本)

set "cmd=(a) & (b)"
call %%cmd%%

但在您的示例中,帮助功能是在不可执行的令牌上触发的。
这似乎是刽子手完全失去理智的最后死亡触发器。

【讨论】:

    【解决方案2】:

    研究总结:

    调用换行符\nFORIFREM 的帮助函数会使cmd 崩溃,并以ERRORLEVEL -1073741819 aka 0xC0000005 退出,这表示访问冲突错误。

    首先,cmd 解析器尝试启动werfault 以终止进程。

    如果你提前终止werfault,将会出现错误信息!

    访问冲突错误:
    0x00007FF7F18E937B 处的指令引用了 0x0000000000000070 处的内存。无法读取内存。

    推测ifforrem使用了特殊的解析器,但是当call触发帮助函数时,返回一个非命令令牌,导致cmd解析器崩溃。


    来源:

    1. Why I can't CALL "IF" and "FOR" neither in batch nor in the cmd?
    2. CALL me, or better avoid call
    3. Limit CMD processing to internal commands, safer and faster?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-28
      • 2014-10-05
      相关资源
      最近更新 更多