Bien que Windows prenne en charge la mémoire partagée via son file mapping API, vous ne pouvez pas injecter directement un mappage de mémoire partagée dans un autre processus, car MapViewOfFileEx ne prend pas d'argument de processus. Toutefois, vous pouvez injecter des données en allouant de la mémoire dans un autre processus en utilisant VirtualAllocEx et WriteProcessMemory. Si vous deviez copier dans un handle à l'aide de DuplicateHandle, puis injectez un stub qui appelle MapViewOfFileEx, vous pouvez établir un mappage de mémoire partagée dans un autre processus. Comme il semble que vous injecter du code de toute façon, cela devrait bien fonctionner pour vous.
Pour résumer, vous devez:
- Créer une poignée de segment de mémoire partagée anonyme en appelant CreateFileMapping avec INVALID_HANDLE_VALUE pour hFile et NULL pour lpName.
- Copiez cette poignée dans le processus cible avec DuplicateHandle
- Allouer de la mémoire pour le code en utilisant VirtualAllocEx, avec flAllocationType = MEM_COMMIT | MEM_RESERVE et flProtect = PAGE_EXECUTE_READWRITE
- Ecrivez votre code de dérivation dans cette mémoire, en utilisant WriteProcessMemory. Ce talon devra probablement être écrit en assembleur. Passez le HANDLE de DuplicateHandle en l'écrivant ici quelque part. Exécutez votre talon à l'aide de CreateRemoteThread. Le talon doit alors utiliser le HANDLE qu'il a obtenu pour appeler le MapViewOfFileEx. Les processus auront alors un segment de mémoire partagée commun.
Vous trouverez peut-être un peu plus facile si votre talon charge une bibliothèque externe - à savoir, l'ont suffit d'appeler LoadLibrary (trouver l'adresse de LoadLibrary est laissée en exercice au lecteur) et faire votre travail de la Le principal point d'entrée de la bibliothèque. Dans ce cas, l'utilisation de la mémoire partagée nommée risque d'être plus simple que de se disputer avec DuplicateHandle.Voir l'article MSDN sur CreateFileMapping pour plus de détails, mais, essentiellement, passer INVALID_HANDLE_VALUE pour hFile et un nom pour lpName.
Modifier: Puisque votre problème est de transmettre des données et pas d'injection de code réelle, voici quelques options.
- Utilisez une mémoire partagée de taille variable. Votre talon obtient la taille et le nom ou un handle de la mémoire partagée. Ceci est approprié si vous n'avez besoin d'échanger des données qu'une seule fois. Notez que la taille d'un segment de mémoire partagée ne peut pas être facilement modifiée après la création.
- Utilisez un named pipe. Votre talon obtient le nom ou une poignée du tuyau. Vous pouvez ensuite utiliser un protocole approprié pour échanger des blocs de taille variable - par exemple, écrivez size_t pour length, suivi du message réel. Ou utilisez PIPE_TYPE_MESSAGE et PIPE_READMODE_MESSAGE et observez ERROR_MORE_DATA pour déterminer où les messages se terminent. Ceci est approprié si vous devez échanger des données plusieurs fois.
Edit 2: Voici un croquis de la façon dont vous pourriez mettre en œuvre la poignée ou le stockage de pointeur pour votre talon:
.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...
Vous pouvez aussi utiliser un nom fixe, ce qui est probablement plus simple.
Quel genre de programme? Windows, interface graphique, console? –
tous. Je peux lancer à partir d'un service, ou d'une interface graphique ou d'une console – wonderer
Il y a un bon encapsuleur C++ facile à utiliser pour les fichiers mappés en mémoire dans le projet POCO. http://pocoproject.org/download/index.html Je l'ai trouvé après avoir essayé à plusieurs reprises d'utiliser les trucs de Boost, ce que d'autres personnes pourraient trouver facile à utiliser, mais j'ai trouvé brutalement difficile à utiliser correctement. –