Изменение инструкции по сборке перед загрузкой - PullRequest
4 голосов
/ 30 ноября 2010

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

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

Ответы [ 3 ]

3 голосов
/ 30 ноября 2010

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

1 голос
/ 30 ноября 2010

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

0 голосов
/ 30 ноября 2010

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

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

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

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

Существуют также методы инъекция DLL , который может достичь тех же целей.


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


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

...