Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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