Динамическое перераспределение секции кода

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

12
задан Jonathan Leffler 22 February 2010 в 19:16
поделиться

3 ответа

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

В GCC вы можете использовать -fpic для генерации независимого от позиции кода. Передача -q или - emit-relocs компоновщику заставит его передать информацию о перемещении. Спецификация ELF (ссылка в формате PDF) содержит информацию о том, как использовать эту информацию о перемещении; если вы не используете ELF, вам нужно будет найти соответствующую документацию для вашего формата.

8
ответ дан 2 December 2019 в 22:05
поделиться

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

Вы можете скопировать некоторый код в область кучи malloc, а затем вызвать его через указатели функций, но в зависимости от ОС вам может потребоваться включить выполнение в сегменте. Вы можете попытаться скопировать некоторый код в сегмент кода (стараясь не перезаписать следующую функцию), но ОС, вероятно, сделала этот сегмент доступным только для чтения. Вы можете посмотреть на ядро ​​Linux и посмотреть, как оно загружает свои модули.

3
ответ дан 2 December 2019 в 22:05
поделиться

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

0
ответ дан 2 December 2019 в 22:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: