Что такое использование саморедактирующего кода? - программирование
Подтвердить что ты не робот

Что такое использование саморедактирующего кода?

Есть ли реальное использование для самомодифицирующего кода?

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

Любые идеи? Гипотетические ситуации также приветствуются.

4b9b3361

Ответ 1

Оказывается, что запись в Википедии " самомодифицирующий код" имеет отличный список:

  • Полуавтоматическая оптимизация зависимого от состояния цикла.
  • Генерация кода времени выполнения или специализация алгоритма в время выполнения или время загрузки (что является популярным, например, в области графика в реальном времени), например, общая сортировать утилиту для подготовки кода для выполнения ключевое сравнение, описанное в конкретный вызов.
  • Изменение встроенного состояния объекта или симуляция высокоуровневого строительство затворов.
  • Задание адреса адреса подпрограммы, как это обычно делается при загрузке динамических библиотек, или, по каждому вызов, исправляющий подпрограмму внутренние ссылки на его параметры чтобы использовать их фактические адреса. Рассматривается ли это как "самомодифицирующий код" или нет - случай терминологии.
  • Эволюционные вычислительные системы, такие как генетическое программирование.
  • Скрытие кода предотвращает обратное проектирование, так как использование дизассемблер или отладчик.
  • Скрытие кода до избежания обнаружения с помощью программного обеспечения для сканирования вирусов и шпионских программ и.
  • Заполнение 100% памяти (в некоторых архитектурах) с шаблоном перемотки повторяющихся кодов операций, до стереть все программы и данные, или записать аппаратное обеспечение.
  • Сжатие кода, которое нужно распаковать и выполнить во время выполнения, например, когда память или дисковое пространство ограничено.
  • Некоторые очень ограниченные наборы инструкций не оставляют никаких вариантов, кроме как использовать самомодифицирующий код для достижения определенных Функциональность. Например, "Один Instruction Set Computer", который использует только вычитать-и-ветки, если отрицательным "инструкция" не может делать косвенные копировать (что-то вроде эквивалента "* a = ** b" в программировании на С язык) без использования самомодифицирующихся код.
  • Инструкции по изменению отказоустойчивости

В связи с тем, что хакерские хакеры используют самомодифицирующийся код:

В течение нескольких обновлений прошивки DirectTV медленно собирала программу на своей смарт-карте, чтобы уничтожить карты, которые были взломаны, чтобы незаконно получать неоплаченные каналы. См. Статью Jeff Coding Horror о Black Sunday Hack для получения дополнительной информации.

Ответ 2

Я видел самомодифицирующийся код, используемый для:

  • оптимизация скорости, благодаря тому, что программа записывает больше кода для себя на лету

  • обдумывание, сделать сложную реструктуризацию

Ответ 3

В прежние времена, когда оперативная память была ограничена, для сохранения памяти использовался самомодифицирующий код. В настоящее время, например, утилиты сжатия приложений, такие как UPX, используются для распаковки/изменения собственного кода после загрузки сжатого изображения приложения.

Ответ 4

Поскольку Commodore 64 не имеет много регистров и имеет процессор 1 МГц. Когда вам нужно прочитать адрес памяти, смещенный на значение, проще изменить источник.

@Reader:
LDA $C000
STA $D020
INC Reader+1
JMP Reader

В последний раз я написал самомодифицирующийся код: -)

Ответ 5

Языки ассемблера 1960-х годов использовали самомодифицирующийся код для реализации вызовов функций без стека.

Knuth, v1, 1ed p.182:

MAX100  STJ   EXIT   ;Subroutine linkage
        ENT3  100    ;M1. Initialize
        JMP   2F
1H      CMPA  X,3    ;M3. Compare
        JGE   *+3
2H      ENT2  0,3    ;M4. Change m
        LDA   X,3    ;(New maximum found)
        DEC3  1      ;M5. Decrease k
        J3P   1B     ;M2. All tested?
EXIT    JMP   *      ;Return to main program

В более крупной программе, содержащей это кодирование в качестве подпрограммы, одна команда "JMP MAX100" приведет к тому, что регистр A будет установлен на текущее максимальное значение местоположений X + 1 - X + 100, а положение максимума будет появляются в rI2. Подпрограмма в этом случае достигается инструкциями "MAX100 STJ EXIT", а затем "EXIT JMP *". Из-за того, как работает J-регистр, инструкция выхода затем переместится в место, следующее за местом, где была сделана исходная ссылка на MAX100.

Изменить: может быть, трудно понять, что происходит, даже с кратким объяснением здесь. В строке MAX100 STJ EXIT, MAX100 является меткой для инструкции (и, следовательно, для процедуры в целом), STJ означает STORE в регистре перехода (откуда мы только что пришли), EXIT означает ячейку памяти помеченный как "EXIT" является целью STORE. EXIT, мы увидим позже метку последней инструкции. Так что это переписывание кода! Но многие инструкции (включая STJ здесь) неявно переписывают только часть операнда слова команды. Таким образом, JMP остается нетронутым, а * является фиктивным маркером, так как там действительно ничего значимого в этом нет, он только перезаписывается.


Самомодифицирующийся код также используется там, где косвенная адресация недоступна, и все же адрес, который вам нужен, сидит прямо там, в регистре. PDP-1 LISP:

dap .+1  ;deposit address part of accumulator in (IP+1)
lac xy   ;load accumulator with (ADDRESS) [xy is a dummy symbol, just like * above]

Эти две команды выполняют ACC := (ACC) путем изменения операнда команды загрузки.

Модификации, подобные этим, относительно безопасны, и на античных архитектурах они необходимы.

Ответ 6

Множество причин. Сверху моей головы:

  • Конструкция класса времени выполнения и метапрограммирование. Например, имея класс factory, который принимает соединение с таблицей SQL и генерирует класс клиента, специализированный для этой таблицы (с аксессуарами для столбцов, методами поиска и т.д.).

  • Тогда, конечно, есть известный пример bitblt и регулярные выражения.

  • Динамическая оптимизация на основе информации RT a la tracing JITs

  • Специализация подтипа общих функций стиля ada в аккреционной среде.

- MarkusQ

Ответ 7

Потому что это действительно здорово, а иногда и эта причина.

Ответ 8

Динамическое связывание - это своего рода самомодификация (исправление абсолютных и/или относительных мест перехода)... что обычно выполняется загрузчиком программ O/S.

Ответ 9

Искусственный интеллект?

Ответ 11

LOL - два раза я написал самомодифицирующий код:

  • при первом изучении языка ассемблера, прежде чем я понял косвенный индексированный доступ
  • случайно, как ошибки указателя на языке ассемблера и C

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

Ответ 12

Майк Абраш описал генератор кода Pixomatic для Dr. Dobb Journal некоторое время назад: http://www.ddj.com/architect/184405807. Это программный 3D dx7 (?) Совместимый растеризатор.

Ответ 13

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

Ответ 14

Генерация динамического кода в SwiftShader - это форма самомодифицирующего кода, которая позволяет ему эффективно реализовать Direct3D 9 на процессоре.