2013-04-27 4 views
2

Есть ли библиотека C для управления машинным кодом x86/x64? В частности, я хотел бы изменить функцию в адресном пространстве моей программы во время выполнения.Библиотека для управления машинным кодом во время выполнения?

Например, у меня есть функции foo и bar, для которого у меня есть источник или знание их внутренней работы, но не перекомпилировать библиотеку они, и я имею функцию baz я написал сам. Теперь я хотел бы сказать такие вещи, как: «В функции foo найдите звонок bar и введите« baz »прямо перед ним». Инструмент должен будет соответствующим образом скорректировать все соответствующие адреса в программе.

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

+1

Уточните поиск в Google, чтобы включить такие термины, как «кодовое ткачество», «инъекция кода» и «аспектно-ориентированное программирование». –

+0

@Brendan: Это несколько гипотетический вопрос. Но есть ситуации, когда вы не можете сделать это технически (не можете заменить системные библиотеки) или юридически (из-за лицензирования). – jdm

ответ

3

Это известный как «самомодифицирующийся код» (см. wikipedia), и в 80-х и начале 90-х годов он был очень модным. Однако, в частности, в машинных кодах и ASM, он довольно сильно вымер, как подход с современными языками, потому что он довольно хрупкий. Управляемые языки пытались обеспечить более безопасную модель, поскольку она также была основой для атаки с переполнением буфера.

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

Вот несколько ссылок, которые помогут вам начать работу;

  1. How to write self-modifying code in x86 assembly
  2. Self-modifying code for debug tracing in quasi-C

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

В вашем thunk вы можете выполнять любые операции, которые вам нравятся до и после вызова реальной функции. Если вы уже находитесь в одном и том же адресном пространстве, и ваш thunk-код загружен, вы дома.

Если вы на Windows, вы также можете захотеть взглянуть на Detours.

+0

Да - проблемы безопасности, а не потокобезопасные. Лучше всего избегать. –

1

Если вы используете gcc и вы хотите заменить целую функцию, вы можете перенаправить, завернуть функцию с помощью -Wl,wrap,functionName переключатель: https://stackoverflow.com/a/617606/111160.

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

Если вы хотите выполнить некоторые действия перед каждым звонком до baz, сделайте так, чтобы ваши __wrap_baz совершили эти действия и позвонили по телефону __real_baz.