Вызов функций в DLL, загруженной другим процессом - PullRequest
4 голосов
/ 09 июля 2011

У меня есть DLL, которую я вставляю в другой процесс, но я хочу иметь возможность вызывать экспорт этой DLL из моего приложения.В другом месте я читал, что у вас есть API SendMessage, но я понятия не имею, что делать.Есть ли пример кода о том, как это делается?

Ответы [ 3 ]

10 голосов
/ 09 июля 2011

Хотя невозможно напрямую вызвать функцию в другом процессе, вы можете сделать это косвенно довольно легко с помощью нескольких шагов и API Windows.

  1. Получите адреса LoadLibrary иGetProcAddress из вашего собственного процесса.kernel32.dll должен быть загружен по одному и тому же адресу в каждом процессе, поэтому вы можете рассчитывать на то, что они присутствуют в процессе, в который вы вводите
  2. Создайте struct, который будет содержать все аргументы, которые вы хотитепередать вашей функции, которая будет вызывать функции в другом процессе (потому что CreateRemoteThread может передать только один аргумент функции, поэтому мы будем использовать его для передачи указателя на структуру), который по крайней мере содержит указатели на функции-члены для храненияадреса LoadLibrary и GetProcAddress
  3. Выделите достаточно памяти для структуры в удаленном процессе через VirtualAllocEx, затем заполните ее правильной информацией с помощью WriteProcessMemory
  4. Записатьфункция, взяв указатель на struct, который вы написали, который использует LoadLibrary / GetProcAddress для вызова нужной функции.Не забывайте использовать указатели для тех функций в структуре, которой вы передаете функцию, а не имена.
  5. Выделите достаточно памяти в удаленном процессе, чтобы сохранить функцию с VirtualAllocEx, делаяОбязательно передайте VAX флаг PAGE_EXECUTE_READWRITE, чтобы он мог содержать исполняемый код
  6. Чтение и запись кода функции из вашего процесса в другой процесс через Read/WriteProcessMemory
  7. Вызов функциив удаленном процессе (который находится по адресу, возвращаемому VirtualAllocEx) с помощью CreateRemoteThread.

Убедитесь, что все данные, которые вы передаете функции, либо хранятся внутри структуры и/ или находится в адресном пространстве удаленного процесса (введите его с помощью VirtualAllocEx / WriteProcessMemory.

Это может показаться немного сложным, но это не так уж сложно. Если вам нужна помощь с этим,не стесняйтесь спрашивать в комментарии.

1 голос
/ 09 июля 2011

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

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

Но перед реализацией этого механизма пользовательских сообщений / протоколов / IPC, я предлагаю вам сначала определить точную потребность.

1 голос
/ 09 июля 2011

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

Во-первых, если вы знаете адрес экспорта (что не так часто), и функция, которую вы вызываете, использует соглашение о вызовах __stdcall, в качестве аргумента принимает целое число размером с указатель, и возвращает DWORD, вы можете использовать CreateRemoteThread для выполнения его в потоке в удаленном процессе. Это часто используется для запуска LoadLibrary для внедрения DLL в целевой процесс, поскольку LoadLibrary загружается по одному и тому же адресу во все процессы на данном компьютере.

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

...