Почему эта команда cra sh cmd? - PullRequest
3 голосов
/ 22 февраля 2020

Так что я случайно наткнулся на потрясающий странный сценарий , который cra sh консоль при вводе:

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

Факты:

  • Все без пробелов между командой и /? игнорируется. Например, REM ANYTHING_HERE_WITHOUT_SPACES/? должен был быть перехвачен как REM /?
  • Однако IF, FOR и REM не являются обычными внутренними командами . Они используют собственный специальный синтаксический анализатор, который, возможно, вызвал некоторые ошибки перехвата, поэтому он вылетел.

Я отметил @ Jeb как принятый, потому что его ответ не только указал 1030 * executor не может правильно перехватить следующие специальные символы , но они также возвращают «токен» (зависит от версии):

  • & возвращает /
  • && возврат 1
  • | возврат 2
  • || возврат 0
  • /? возврат <
  • @ возвращает +
  • @() возвращает ;

Редактировать:

  • @if a==a : возвращает ,
  • @for %a in () do : возвращает +
  • @rem : возвращает -

Однако, хотя они имеют уникальные парсеры, они все равно не объясните, почему они все краны sh. Поэтому я провел некоторое тестирование:

  • Удалите 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?

  • Что заставило парсер взломать sh?

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

CALL необходим для начала второго раунда парсера.

Но есть небольшая ошибка (или больше), на этом этапе невозможно выполнить любую из специальных команд или использовать &, |, &&, ||, перенаправление или блоки команд.

Причина, по-видимому, в том, что синтаксический анализатор строит внутренне граф токенов, заменяя специальные вещи на некоторые значения токенов.
Но с CALL исполнитель больше не знает как справиться с ними.

Этот код пытается выполнить пакетный файл с именем 3.bat !!!
(имя может отличаться в зависимости от версии windows)

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

Но в вашем примере функция справки запускается на неисполняемом токене.
Кажется, что окончательный смертельный триггер для исполнителя полностью не в себе.

0 голосов
/ 26 апреля 2020

Сводка исследования:

Вызов функции перевода строки \n или FOR, IF & REM помогает справиться с cmd, завершив работу с ERRORLEVEL -1073741819 aka 0xC0000005, что указывает на ошибка нарушения доступа.

Сначала анализатор cmd пытается запустить werfault, чтобы завершить процесс.

Если вы преждевременно завершите работу werfault, появится сообщение об ошибке!

Ошибка нарушения доступа:
Инструкция по адресу 0x00007FF7F18E937B ссылалась на память по адресу 0x0000000000000070. Память не может быть прочитана.

Предполагается, что if, for и rem используют специальные синтаксические анализаторы, но когда функция справки запускается с помощью call, возвращается токен команды, который приводит к сбою синтаксического анализатора cmd.


Источники:

  1. Почему я не могу ВЫЗВАТЬ «ЕСЛИ» и «ЗА» ни в пакетном режиме, ни в cmd?
  2. ВЫЗВАТЬ меня, или лучше избегать вызова
  3. Ограничить обработку CMD внутренними командами, безопаснее и быстрее?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...