2013-04-27 3 views
4

Предположим, я хочу вставить DLL в процесс, который хочет изменить значение адреса A каждые 250 мс. Мне нужно будет использовать DllMain, верно? Проблема в том, что мне не разрешено ждать внутри DllMain. Значит, мне нужно создать поток? Или это не обходит ограничения? Как мне это сделать?Лучшие практики для инъекций DLL?

Также есть ли какие-либо преимущества для использования DLL-инъекции для редактирования памяти приложения с использованием EXE?

Кроме того, какой размер стека должен быть в CreateThread? Что, если он слишком мал или слишком велик? Как узнать, сколько мне нужно?

ответ

5

Из вашего описания, похоже, вы уже знаете, как получить целевой процесс загрузки вашей DLL. Если мое предположение верно, то ответ прост: создайте поток из DLLMain и реализуйте свою логику в потоке. Пока ваш код соблюдает приведенные ниже правила, вы должны быть в порядке.

Этот document описывает, что может и не может быть сделано в DLLMain и почему.

Как документально, вы никогда не должны выполнять следующие задачи в DllMain:

  • вызова LoadLibrary или LoadLibraryEx (прямо или косвенно). Это может привести к тупиковой ситуации или сбою.
  • Синхронизация с другими потоками. Это может привести к тупиковой ситуации.
  • Приобретите объект синхронизации, принадлежащий коду, который ожидает получения загрузчика блокировка. Это может привести к тупиковой ситуации.
  • Инициализировать COM-потоки с помощью CoInitializeEx. При определенных условиях эта функция может вызвать LoadLibraryEx.
  • Вызовите функции реестра. Эти функции реализованы в Advapi32.dll. Если Advapi32.dll не инициализируется перед вашей DLL, DLL может получить доступ к неинициализированной памяти и привести к сбою процесса.
  • Звоните CreateProces. Создание процесса может загрузить другую DLL.
  • Позвоните в ExitThread. Выход из потока при отсоединении DLL может привести к повторному приобретению блокировки загрузчика, что приведет к тупиковой ситуации или сбою.
  • Звоните CreateThread. Создание потока может работать, если вы не синхронизируете с другими потоками, но это рискованно.
  • Создайте именованный канал или другой именованный объект (только для Windows 2000). В Windows 2000 именованные объекты предоставляются библиотекой служб терминалов. Если эта DLL не инициализирована, вызовы DLL могут привести к сбою процесса .
  • Используйте функцию управления памятью из динамического C Run-Time (CRT). Если CRT DLL не инициализируется, вызовы этих функций могут привести к сбою процесса.
  • Функции вызова в User32.dll или Gdi32.dll. Некоторые функции загружают другую DLL, которая не может быть инициализирована.
  • Использовать управляемый код.

следующие задачи являются безопасными для выполнения в DllMain:

  • Инициализировать статические структуры данных и пользователей во время компиляции.
  • Создание и инициализация синхронизации объектов
  • Выделения памяти и инициализировать динамические структуры данных (избегая функции, перечисленные выше.)
  • Настройки нити локального запоминающего устройства (TLS).
  • Открыть, прочитать и записать в файлы.
  • Функции вызова в Kernel32.dll (кроме функций, перечисленных выше).
  • Установите глобальные указатели на NULL, отложив инициализацию динамических элементов. В Microsoft Windows Vista ™ вы можете использовать одноразовые функции инициализации, чтобы гарантировать, что блок кода выполняется только один раз в многопоточной среде.

Ваш второй вопрос менее ясен для меня. Чтобы вводить код в другой процесс, вы должны начать с чего-то (браузер, exe, что угодно), а затем записать в целевую память процесса, чтобы загрузить ее DLL.

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