Как поделиться процессом? - PullRequest
0 голосов
/ 07 июня 2010

Как я могу прижаться к другому процессу? Как, поделитесь именем другого процесса? Так что, если мое приложение - griddemo.exe, и я хочу войти, скажем, в explorer.exe, возможно ли это? Просто прочитайте что-нибудь о CreateRemoteThread () из kernel32. Это в правильном направлении? Будут ли проблемы с безопасностью / UAC? ​​

Ответы [ 4 ]

3 голосов
/ 07 июня 2010

Прежде всего, извините, но мой ответ будет длиннее, чем другие ответы.

Я использую DLL-инъекцию много лет в другой версии операционной системы (от Windows NT 4.0 до Windows 7), и у меня не было временилюбая проблема с любым антивирусным сканером (включая Norton и McAfee в разных версиях).Поэтому я не согласен со Стивеном Клири (см. Его ответ) в этом аспекте.

Использование CreateRemoteThread() на самом деле является лишь одним из способов. AppInit_DLLs - это еще один способ.У обоих есть свои преимущества и недостатки.Основным преимуществом AppInit_DLLs является простота внедрения DLL в любой процесс.Основными недостатками подхода AppInit_DLLs являются:

  1. Все приложения с графическим интерфейсом будут загружать DLL.Если вы хотите загрузить его только в одном процессе, таком как explorer.exe , вы не сможете этого сделать.Таким образом, рабочее пространство всех процессов GUI будет увеличено вашей DLL.Ошибка в вашей DLL (особенно внутри DllMain или в любой зависимой DLL вашей DLL) может привести к сбою многих процессов, о которых вы в данный момент не знаете.
  2. Вы не можете внедрить свою DLL с учетом подхода AppInit_DLLsв консольном приложении или в любом EXE-файле, который не зависит от User32.dll.
  3. Вы должны быть очень осторожны внутри вашего DllMain, потому что он будет называться до User32.dllбудет полностью инициализирован.Таким образом, безопасная DLL, которую вы можете использовать внутри DllMain вашей DLL - Kernel32.dll.

Что касается CreateRemoteThread(), можно запустить дополнительный поток в процессе.Основная проблема CreateRemoteThread() заключается в том, что его параметр lpStartAddress должен быть адресом удаленного процесса .Поэтому необходимо использовать функции OpenProcess, VirtualAllocEx и WriteProcessMemory для записи некоторой информации в память процесса назначения.Чтобы иметь возможность открыть процесс, необходимо включить привилегию отладки.Если вы хотите сделать только 2 + 2 внутри процесса назначения, вы можете скопировать соответствующий двоичный код непосредственно в процесс назначения.Вся настоящая интересная работа может быть выполнена с использованием некоторого Windows API.Так что в основном никто не копирует код.Вместо этого один вызов LoadLibrary("MyPath\\MyDll.dll") внутри процесса назначения.Поскольку прототип LoadLibrary совпадает с прототипом ThreadProc из CreateThread, вы можете назвать LoadLibrary как ThreadProc из CreateRemoteThread().Этот способ имеет имя DLL Injection .

Я рекомендую использовать эту DLL Injection , только если она действительно требуется .Если у вашего конечного приложения есть какой-то другой способ, например, плагины для загрузки вашей DLL внутри процесса, вы должны использовать этот способ вместо DLL Injection.

Некоторые общие проблемы, которые вам придется решать после того, как у вас будет рабочий примерИнъекция DLL.Эти проблемы вы не видите в первый раз, но после длительного использования вашего приложения вы увидите его важность:

  1. Вы должны найти момент, когда процесс назначения уже запущен, прежде чем выможно использовать CreateRemoteThread().
  2. Приложение назначения должно быть уже инициализировано перед вызовом CreateRemoteThread().Так что не стоит использовать CreateRemoteThread() слишком рано.В случае explorer.exe вы можете использовать запуск вашей небольшой триггерной программы из ключа реестра Run.На данный момент файл explorer.exe полностью подготовлен для внедрения DLL.
  3. Следует учитывать 64-разрядную версию Windows.
  4. Не забывайте о перемещении DLL внутри целевого процесса.Будьте осторожны, чтобы ваша DLL могла быть загружена в процессе назначения по другому адресу, как в вашем процессе.В большинстве случаев это хорошая идея, чтобы выбрать хороший базовый адрес (вариант компоновщика) для вашей DLL, которую вы будете вставлять.Kernel32.dll иногда (очень редко) может быть загружен по другому адресу, как в исходном процессе.Вы можете создать код DLL-инъекции, в котором нет этой проблемы.
  5. Службы терминалов изолируют каждый сеанс терминала по проекту.Следовательно, CreateRemoteThread завершается ошибкой, если целевой процесс находится в другом сеансе, чем вызывающий процесс.Проблема, которую вы можете увидеть в XP (которая не подключена к домену) или особенно в Vista или Windows 7, если вы попытаетесь внедрить DLL из службы Windows.Чтобы решить эту проблему, вы должны сделать DLL Injection либо из процесса, запущенного в том же терминальном сеансе, что и целевой процесс, либо вам нужно переключить текущий сеанс перед использованием CreateRemoteThread.Ваш процесс должен иметь привилегию SE_TCB_NAME и использовать SetTokenInformation с параметром TokenSessionId.Чтобы получить идентификатор сеанса процесса назначения, вы можете использовать разные методы.Функции с префиксом WTS (например, WTSGetActiveConsoleSessionId) могут быть очень полезными.

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

1 голос
/ 07 июня 2010

DLL инъекция является традиционным способом сделать это.Это довольно сложно, тем более что вирусные сканеры смотрят косо на практике.Поэтому, даже если вы работаете, Norton / McAfee, скорее всего, заблокирует вас или заблокирует вас в будущем.

Одним из простых способов внедрения DLL является значение реестра AppInit_DLLs .Обратите внимание, что Microsoft оставляет за собой право просто удалить эту функцию (и, вероятно, сделает это в будущем).

Одобренный Microsoft способ внедрения DLL - это лицензирование Microsoft Detours .

Обратите внимание, что ваша DLL должна быть построена на CLR версии 4.0 или выше, чтобы безопасно выполнять внедрение DLL, потому что это первая версия, поддерживающая in-proc бок о бок.

0 голосов
/ 07 июня 2010

Я не пробовал это в последнее время, но другой способ сделать это - создать Hook DLL:

  1. Создайте DLL, содержащую процедуру подключения, например MessageProc .

  2. Установите эту DLL в Windows \ System32.

  3. Используйте FindWindows (Ex), чтобы найти окно процесса вашей жертвы.

  4. Используйте GetWindowThreadProcessId (), чтобы найти поток-владелец этого окна. Это необходимо, чтобы избежать внедрения вашей DLL в каждый отдельный процесс в системе.

  5. Используйте SetWindowsHookEx , чтобы перехватить эту нить.

  6. PostMessage сообщение WM_USER в окно - активация DLL-библиотеки Hook, если она еще не активна.

Скорее всего, это вызовет новый Windows Vista / 7 UIPI / UAC , если вы не являетесь достаточно привилегированным пользователем, но это зависит от многих факторов - ваш пробег может отличаться.

0 голосов
/ 07 июня 2010

Если вы имеете в виду внедрение вашего кода в другой процесс, то внедрение dll - это один из методов:

http://en.wikipedia.org/wiki/DLL_injection

Не делали этого годами, поэтому не уверены, насколько счастливы будут современные операционные системы MS Windows (то есть после XP).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...