Несмотря на то, что Windows поддерживает совместно используемую память через API-интерфейс для сопоставления файлов *1002*, вы не можете легко внедрить сопоставление совместно используемой памяти непосредственно в другой процесс, поскольку 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 . Затем заглушка должна использовать полученную РУЧКУ для вызова MapViewOfFileEx . Затем процессы будут иметь общий сегмент общей памяти.
Вам может быть немного легче, если ваша заглушка загружает внешнюю библиотеку - то есть просто вызовите LoadLibrary (поиск адреса LoadLibrary оставлен для чтения читателю) и выполните свою работу из записи библиотеки dllmain. точка. В этом случае использование именованной совместно используемой памяти, вероятно, будет проще, чем работа с DuplicateHandle. См. Статью MSDN по CreateFileMapping для получения более подробной информации, но, по сути, передайте INVALID_HANDLE_VALUE для hFile и имя для lpName.
Редактировать : Поскольку ваша проблема заключается в передаче данных, а не в ввод кода, вот несколько вариантов.
- Использовать разделяемую память переменного размера. Ваша заглушка получает размер и либо имя, либо дескриптор общей памяти. Это уместно, если вам нужно обмениваться данными только один раз. Обратите внимание, что размер сегмента общей памяти не может быть легко изменен после создания.
- Использовать именованный канал . Ваша заглушка получает имя или ручку к трубе. Затем вы можете использовать соответствующий протокол для обмена блоками переменного размера - например, напишите 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...
Вы также можете просто использовать фиксированное имя, которое, вероятно, проще.