2010-11-30 7 views
4

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

Я думал использовать что-то вроде Udis86 и читать инструкции один за другим, а затем записывать их в память, а между ними писать мои другие инструкции. Это хороший подход или что-то лучше?

+0

Это библиотека DLL, которую вы указали или иным образом контролируете? Или это готовая DLL, нуждающаяся в модификации? – wallyk 2010-11-30 16:45:24

+0

Да, извините, я написал и скомпилировал DLL. – SamJam 2010-11-30 16:47:48

+0

+1 для интересного вопроса. Извините, я не знаю, что ответ – 2010-11-30 16:48:44

ответ

0

У вас есть (по крайней мере) два варианта:

  • открыть файл DLL и модифицируют его, используя файл, операции чтения/записи
  • нагрузку, DLL и модифицируют инструкции, прежде чем они выполняют

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

С загруженным кодом существует прямая поддержка o/s для поиска адресов символов. Для изменения файла потребуется либо расширенное знание об декодировании символьной информации, либо интерпретация смещения файла, либо поиск шаблонов, помещенных в файл специально для этой цели. Это может быть логикой в ​​точке входа DllMain, которая вызывается для инициализации DLL или любой другой функции в DLL, которая, как известно, выполняется достаточно рано.

Есть также методы DLL injection, которые могут выполнять те же концы.


Но вместо всего этого, что об организации для DLL использовать некоторые функции обратного вызова передать ему, как только вы написал код для выполнения? Трудно сказать, что полезно, не зная больше о том, чего вы пытаетесь достичь.


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

1

Я не уверен, где вы пытаетесь вставить код. Но если он находится в середине тела функции и не обязательно является прологом или эпилогом функции, тогда почему вы не используете блок __asm ​​с кучей nop, чтобы заполнить область, в которую вы будете писать код. Затем просто заполните код, где nop находятся во время выполнения.

3

Инструкции по переключению - это не очень хорошая идея. Многие инструкции x86 зависят от их положения, поэтому, если вы их смените, вы, вероятно, сломаете много вещей.
Вместо этого вы можете скопировать инструкцию в место, которое вам нужно запланировать; заплатите там jmp в какую-нибудь свободную область, затем в эту свободную область поместите скопированную команду, ваш дополнительный код, а затем, наконец, jmp обратно в исходный код. Не тривиально, но выполнимо. Проверьте this и this на предмет возможных вариантов реализации.
Что сказал, почему вам нужно изменить двоичный файл, если вы можете просто изменить источник вместо этого? Вы должны задать вопрос, а не «как сделать X [потому что я решил, что мне нужно X, чтобы решить мою проблему»).

Смежные вопросы