Что такое пещера кода, и есть ли законное использование для нее? - PullRequest
25 голосов
/ 24 апреля 2009

Я впервые столкнулся с этим словом в вопросе StackOverflow " C # Теоретическое: запись JMP в кодовую пещеру в asm ." Я вижу, что согласно Викисловарь , кодовая пещера:

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

Нашел ли я правильное определение? Если так, есть ли законное использование для пещеры кода?

Ответы [ 9 ]

17 голосов
/ 24 апреля 2009

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

Предполагая, конечно, что это безумие.

13 голосов
/ 24 апреля 2009

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

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

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

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

Для тех из вас, кто предлагает, что пещеры кода предназначены только для кода, генерируемого во время выполнения: это неполное определение. Много раз я писал структуру данных в «пещере кода» и обновлял указатели, чтобы указывать туда, и я подозреваю, что я не единственный, кто делает это.

11 голосов
/ 24 апреля 2009

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

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

8 голосов
/ 24 апреля 2009

некоторые законные применения : исправление исполняемых двоичных файлов ОС без перезагрузки (MS делает это), подключение низкоуровневых функций ОС (файловая система, сеть) для брандмауэра и антивируса, расширение приложения, когда у вас нет исходный код (например, очистка вызовов низкого уровня ОС для DrawText, чтобы вы могли читать их вслух для слепых людей)

6 голосов
/ 24 апреля 2009

То, как это описано здесь напоминает мне о патч-точках - законное использование.

4 голосов
/ 24 апреля 2009

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

3 голосов
/ 24 апреля 2009

Для меня это звучит как правильное определение.

Что касается законного использования, позвольте мне сказать следующее: не делайте этого, если вы просто не экспериментируете ради эксперимента и не готовы принять последствия.

Не существует способа, чтобы этот тип вещей когда-либо входил в производственный код:

  1. Это огромная потенциальная проблема безопасности. Если есть возможность вставить код в память и затем выполнить его, злоумышленник теоретически может делать все, что угодно.
  2. Это кошмар обслуживания кода и кошмар отладки. Если код, который завершается выполнением, может измениться во время выполнения, становится практически невозможно отследить ошибки и ошибки.
3 голосов
/ 24 апреля 2009

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

2 голосов
/ 24 апреля 2009

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

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

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

...