Какова цель кода операции nop?



Я иду через MSIL и замечаю, что есть много nop инструкция. В статье MSDN говорится, что они не предпринимают никаких действий и используются для заполнения пространства, если код операции исправлен. Они используются в отладочных построениях, чем версии. Я знаю, что такие операторы используются в языках ассемблера, чтобы убедиться, что код операции соответствует границе слова, но зачем он нужен в MSIL?

822   19  

19 ответов:

NOPs служат нескольким целям:

  • Они позволяют отладчику размещать точку останова в строке, даже если она объединена с другими в сгенерированном коде.
  • это позволяет загрузчику исправлять прыжок с разным размером смещения цели.
  • это позволяет выровнять блок кода на определенной границе, что может быть хорошо для кэширования.
  • это позволяет для инкрементного связывания перезаписать куски кода с вызовом нового раздела без приходится беспокоиться об общей функции изменения размера.

вот как NOP используются при отладке:

Nops используются языковыми компиляторами (C#, VB и др.) для определения неявных точек последовательности. Они сообщают JIT-компилятору, где гарантировать, что машинные инструкции могут быть сопоставлены с инструкциями IL.

запись в блоге Рика Байера на DebuggingModes.IgnoreSymbolStoreSequencePoints, объясняет некоторые детали.

C# также помещает Nops после инструкций по вызову, чтобы вернуть местоположение сайта в источник вызова, а не после звонка.

Он предоставляет возможность для линейных маркеров (например, точек останова) в коде, где сборка выпуска не будет выдавать ни одного.

Это также может сделать код работать быстрее, при оптимизации для конкретных процессоров или архитектур:

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

в этих условиях, посвященный НОП может заставить следующую инструкцию в конкретный конвейер (первый или не первый) и улучшить сопряжение следующих инструкций, чтобы стоимость НОП - это больше, чем амортизируется.

чувак! No-op-это потрясающе! Это инструкция, которая ничего не делает, но отнимет время. В тусклые темные века вы использовали бы его для выполнения микрорегулировок во времени в критических циклах или, что более важно, в качестве наполнителя в самомодифицирующемся коде.

одно классическое использование для них заключается в том, что ваш отладчик всегда может связать строку исходного кода с инструкцией IL.

Они могли бы использовать их для поддержки edit-and-continue во время отладки. Он предоставляет отладчику пространство для работы по замене старого кода новым без изменения смещений и т. д.

Nop имеет важное значение в полезной нагрузке переполнения буфера эксплойтов.

Как сказал ddaa, nops позволяет учитывать дисперсию в стеке, так что при перезаписи обратного адреса он переходит к NOP sled (много nops подряд), а затем правильно попадает в исполняемый код, а не прыгает на какой-то байт в инструкции, которая не является началом.

50 лет слишком поздно, но эй.

Nop полезны, если вы набираете ассемблерный код вручную. Если бы вам пришлось удалить код, вы могли бы nop старые коды операций.

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

иногда вы должны были использовать инструменты, которые были доступны. В некоторых случаях это был просто очень простой машинный код редактор.

В настоящее время с компиляторами методы не имеют никакого смысла вообще больше.

в сцене взлома программного обеспечения классическим методом разблокировки приложения было бы исправление с помощью NOP строки, которая проверяет наличие ключа или регистрации или периода времени или еще чего-то, чтобы он ничего не делал и просто продолжал запускать приложение, как если бы оно было зарегистрировано.

Я также видел NOPs в коде, который изменяет себя, чтобы запутать то, что он делает в качестве заполнителя (veeery old copy protection).

несколько неортодоксальное использованиеNOP-слайды, используется в эксплойтах переполнения буфера.

в одном процессоре я работал недавно (в течение четырех лет) NOP был использован, чтобы убедиться, что предыдущая операция завершена до начала следующей операции. Например:

значение нагрузки для регистрации (занимает 8 циклов) nop 8 добавить 1 для регистрации

Это убедилось, что регистр имел правильное значение перед операцией добавления.

другое использование состояло в том, чтобы заполнить исполнительные единицы, такие как векторы прерываний, которые должны были быть определенного размера (32 байта), потому что адрес для vector0 было, скажем, 0, для вектора 1 0x20 и так далее, поэтому компилятор помещал туда NOPs, если это необходимо.

Они позволяют компоновщику заменить более длинную инструкцию (обычно длинный прыжок) на более короткую (короткий прыжок). NOP занимает дополнительное пространство - код не может быть перемещен, так как он остановит другие прыжки от работы. Это происходит во время соединения, поэтому компилятор не может знать, подходит ли длинный или короткий прыжок.

по крайней мере, это одно из их традиционных применений.

Это не ответ на ваш конкретный вопрос, но в старые времена вы могли бы использовать НОП для заполнения слот задержки ветви, Если вы не смогли заполнить его с помощью другой полезной инструкции.

выравнивают ли компиляторы .NET выходные данные MSIL? Я бы предположил, что это может быть полезно для ускорения доступа к IL... Кроме того, я понимаю, что он предназначен для портативного и выровненного доступа требуется на некоторых других аппаратных платформах.

первая сборка, которую я узнал, была SPARC, поэтому я знаком с слотом задержки ветви, если вы не можете заполнить его другой инструкцией, обычно инструкцией, которую вы собирались поместить над инструкцией ветви или увеличить счетчик в циклах, вы используете NOP.

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

Я использовал NOPs для автоматической настройки задержки, накопленной после ввода ISR. Очень удобно прибивать время мертвым.

Comments

    Ничего не найдено.