2009-02-05 8 views
46

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

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

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

ответ

46

Оказывается, что запись на Википедии «self-modifying code» имеет большой список:

  1. Полуавтоматическая оптимизация государственного зависимого цикла.
  2. время выполнения генерации кода или специализации алгоритма в выполнения или время загрузки (который является популярным, , например, в области в реальном масштабе времени графики), такие как общий рода утилита подготовки кода для выполнения сравнение ключей, описанное в специальном вызове .
  3. Изменение состояния в развернутом состоянии объекта или моделирование конструкции затворов верхнего уровня .
  4. заплаты из подпрограммы адрес вызывающем, как это было сделано, как правило, во время загрузки динамических библиотек, или, на каждый вызов Patching внутренних ссылок на подпрограмме по своим параметрам таким образом, чтобы использовать их реальные адреса. Означает ли это, что это «самомодифицирующийся код» или нет - это случай терминологии.
  5. Эволюционные вычислительные системы, такие как генетическое программирование.
  6. Скрытие кода до предотвращает обратное проектирование, как с помощью дизассемблера или отладчика .
  7. Скрытие кода до определение обхода с помощью программного обеспечения для сканирования вирусов и шпионских программ и .
  8. Заполнение 100% память (в некоторых архитектурах) с схемой прокатки повторяющихся опкодов, чтобы стереть все программ и данные или выгорания в аппаратных.
  9. Сжатие кода, которое должно быть распаковано и выполнено во время выполнения, например, если память или дисковое пространство ограничены.
  10. Некоторые очень ограниченные инструкции не оставляют никаких вариантов, кроме как использовать самомодифицирующийся код для достичь определенных функциональность.Например, «One Instruction Set Computer» машина, которая использует только вычитает-и-ветвь, если отрицательный «инструкция» не может сделать косвенную копии (что-то вроде эквивалента «* а = ** b "в программировании C ) без использования самомодифицируемого кода .
  11. инструкции изменяющей для отказоустойчивости

На момент о срыве хакеров с помощью самомодифицирующегося кода:

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

+0

Black Sunday Hack? – Brian

+0

Вот и все! Благодаря! –

+0

Спасибо, что Зак !!! – Niyaz

4

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

12

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

  1. оптимизации скорости, имея программу писать больше кода для себя на лету

  2. obsfucation, чтобы сделать обратный инжиниринг гораздо сложнее

+0

Исторически это было довольно популярно для механизмов защиты от копирования в игровом программном обеспечении. – ConcernedOfTunbridgeWells

+0

действительно - это именно то место, где я его видел :) – Alnitak

+0

, который был необходим на некоторых старых 8-битных микро (BBC) играх, чтобы заставить их работать с диска вместо кассетной ленты. – Alnitak

3

Neural networks - это самосовершенствующий код.

Тогда есть evolutionary algorithms, которые сами себя модифицируют.

+1

Я не уверен, что нейронные сети меняют код. Я этого никогда не знал. http://www.hoozi.com/Articles/Neural-Networks-Artificial-Neuron.htm – Niyaz

+0

Я считаю, что любое изменение, которое должно быть сделано для структуры нейронной сети, может быть выполнено в части данных. Почему он должен модифицировать код? – Niyaz

+2

Нейронные сети - это незаменимый код. это не что иное, как сложные нелинейные преобразования, веса которых определяются обучением. – Alnitak

11

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

+0

Я думал, что эти бинарные компрессоры сжаты только на диске и распаковываются при загрузке в память? Я также прочитал один раз, что, поскольку они распаковываются, как загруженные в память, они не могут быть выгружены на диск, поэтому они потребляют больше ОЗУ. Разве это не так? –

+1

У упакованных исполняемых файлов есть приложение «bootstrap», которое загружается в память и запускается там. Затем он загружает сжатые данные, распаковывает их и добавляет распакованные инструкции в свой собственный код. Когда декомпрессия закончена, этот код запускается. Пейджинг происходит, как обычно. – Kosi2801

+0

Самораспаковывающийся JavaScript используется в изобилии на веб-страницах. –

1

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

2

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

3

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

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

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

6

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

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

Это последний раз, когда я написал самомодифицирующийся код в любом случае :-)

5

Много причин. В верхней части головы:

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

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

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

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

- MarkusQ

4

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

0

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

5

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

+0

да это/чувствует/круто, но что - рационально - делает его круто? – Rabarberski

+1

Не чувствует, что это круто, это круто? –

6

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

Кнут, v1, 1ed с.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 

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

Edit: Это может быть трудно понять, что происходит, даже с кратким объяснением здесь. В строке MAX100 STJ EXIT, MAX100 - это метка инструкции (и, следовательно, для процедуры в целом), STJ означает STORE the jump register (где мы только что пришли от), EXIT означает, что ячейка памяти с надписью «EXIT» является цели МАГАЗИНА. 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) путем изменения операнд команды загрузки.

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