Подтвердить что ты не робот

Обмен памятью между двумя процессами (C, Windows)

Так как я не нашел ответа на вопрос, заданный ранее здесь, я пытаюсь использовать другой подход.

Есть ли способ обмена памятью между двумя процессами?

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

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

Возможно ли это? Как?

Оценивается код.

EDIT:

Я думаю, что это не ясно, поэтому я уточню. Я знаю, как вводить. Я делаю это уже. Проблема здесь заключается в передаче динамических данных в инъекции.

4b9b3361

Ответ 2

Хотя окна поддерживают разделяемую память через API сопоставления файлов, вы не можете легко вводить сопоставление общей памяти в другой процесс напрямую, так как MapViewOfFileEx не принимает аргумент процесса.

Однако вы можете вставлять некоторые данные, выделяя память в другом процессе, используя VirtualAllocEx и WriteProcessMemory. Если вы должны были скопировать в дескрипторе, используя DuplicateHandle, затем введите заглушку, которая вызывает MapViewOfFileEx, вы можете установить отображение общей памяти в другом процессе. Поскольку это звучит так, будто вы все равно будете вводить код, это должно хорошо работать для вас.

Подводя итог, вам необходимо:

  • Создайте дескриптор сегмента анонимной разделяемой памяти, вызвав CreateFileMapping с INVALID_HANDLE_VALUE для hFile и NULL для lpName.
  • Скопируйте этот дескриптор в целевой процесс с помощью DuplicateHandle
  • Выделите некоторую память для кода, используя VirtualAllocEx, с flAllocationType = MEM_COMMIT | MEM_RESERVE и flProtect = PAGE_EXECUTE_READWRITE
  • Напишите свой код заглушки в эту память, используя WriteProcessMemory. Вероятно, этот заглушка должен быть написан на ассемблере. Передайте РУЧКУ из DuplicateHandle, написав здесь где-нибудь.
  • Запустите свою заглушку, используя CreateRemoteThread. Затем заглушка должна использовать полученную HANDLE для вызова MapViewOfFileEx. Затем процессы будут иметь общий сегмент разделяемой памяти.

Вы можете найти это немного легче, если ваш заглушка загружает внешнюю библиотеку, то есть просто попробуйте вызвать LoadLibrary (найти адрес LoadLibrary в качестве упражнения для читателя) и выполнить свою работу из библиотеки dllmain entry точка. В этом случае использование именованной общей памяти, вероятно, будет проще, чем использование DuplicateHandle. Подробнее см. Статью MSDN на CreateFileMapping, но, по существу, передайте INVALID_HANDLE_VALUE для hFile и имя для lpName.

Изменить. Поскольку ваша проблема связана с передачей данных, а не с фактической вставкой кода, вот несколько вариантов.

  • Использовать разделяемую память переменной величины. Ваша заглушка получает размер и имя или дескриптор в общей памяти. Это подходит, если вам нужно только обменять данные один раз. Обратите внимание, что размер сегмента разделяемой памяти не может быть легко изменен после создания.
  • Используйте named pipe. Ваш заглушка получает название или ручку для трубы. Затем вы можете использовать соответствующий протокол для обмена блоками с переменным размером, например, написать size_t для длины, за которым следует фактическое сообщение. Или используйте PIPE_TYPE_MESSAGE и PIPE_READMODE_MESSAGE, и следите за ERROR_MORE_DATA, чтобы определить, где заканчиваются сообщения. Это подходит, если вам нужно обмениваться данными несколько раз.

Изменить 2. Здесь приведен пример того, как вы можете использовать дескриптор или указатель для вашего заглушки:

.db B8            ;; mov eax, imm32
.dl handle_value  ;; fill this in (located at the start of the image + one byte)
;; handle value is now in eax, do with it as you will
;; more code follows...

Вы также можете просто использовать фиксированное имя, которое, вероятно, проще.

Ответ 4

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

Однако Windows имеет пространство общей памяти, которое должно быть очень осторожным для правильного управления. Любой процесс, который выделяет пространство в пространстве разделяемой памяти, отвечает за освобождение этой памяти явно. Это в отличие от локальной памяти, которая более или менее исчезает, когда процесс умирает.

См. эту статью примера MSDN для некоторых идей о том, как вы можете использовать пространство разделяемой памяти для захвата мира. Er, интерфейс с устаревшим программным обеспечением. Или что угодно:) Удачи, что бы вы ни делали!

Ответ 5

Вы пытались использовать каналы (для памяти) или даже сериализацию (для ваших объектов)? Вы можете использовать файлы для управления памятью между процессами. Сокеты также хороши для связи между процессами.

Ответ 6

Вы можете использовать Boost.Interprocess для связи между двумя процессами. Но для ввода кода в ранее существующее, не поддерживаемое программное обеспечение вам, вероятно, придется использовать метод @bdonlan, используя WriteProcessMemory.

Ответ 7

Отображение памяти - это путь, вам даже не нужно создавать постоянное пространство памяти, сектор памяти выходит за пределы области видимости, когда все процессы, связанные с ним, завершаются. Есть и другие способы. Быстрый и грязный способ передачи данных из одного приложения C другому - это просто использовать ОС. В командной строке введите app1 | app2. Это приводит к тому, что app2 будет выходным пунктом app1 или iow команда printf из приложения 1 отправит ее в app2 (это называется piping).