Что такое пещера кода, и есть ли законное использование для нее?

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

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

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

9 ответов

Решение

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам