web-dev-qa-db-fra.com

Partager la mémoire entre deux processus (C, Windows)

Comme je n'ai pas trouvé de réponse à la question posée précédemment J'essaie une approche différente.

Existe-t-il un moyen de partager la mémoire entre deux processus?

Le deuxième processus obtient les informations d'une injection, car il s'agit d'un programme hérité qui n'est plus pris en charge.

Mon idée est d'y injecter du code, dans la structure que je passe au programme injecté, de passer l'adresse (ou autre) à la mémoire partagée où se trouvent les données que j'ai besoin d'exécuter. Une fois que j'aurai les données, je remplirai mes propres variables dans le thread injecté.

Est-ce possible? Comment?

Le code est apprécié.

ÉDITER:

Je pense que ce n'est pas clair, je vais donc clarifier. Je sais comment injecter. Je le fais déjà. Le problème ici est de transmettre des données dynamiques à l'injection.

28
wonderer

Vous pouvez essayer un fichier mappé en mémoire .

This donne un peu plus de détails étape par étape.

10
Scott Marlowe

Bien que Windows prenne en charge la mémoire partagée via son API de mappage de fichiers , vous ne pouvez pas facilement injecter directement un mappage de mémoire partagée dans un autre processus, car MapViewOfFileEx ne prend pas d'argument de processus.

Cependant, 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 en utilisant DuplicateHandle , puis injecter un stub qui appelle MapViewOfFileEx , vous pourriez établir un mappage de mémoire partagée dans un autre processus. Comme il semble que vous injecterez du code de toute façon, cela devrait bien fonctionner pour vous.

Pour résumer, vous devrez:

  • Créez 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
  • Allouez de la mémoire pour le code en utilisant VirtualAllocEx , avec flAllocationType = MEM_COMMIT | MEM_RESERVE et flProtect = PAGE_EXECUTE_READWRITE
  • Écrivez votre stub code dans cette mémoire, en utilisant WriteProcessMemory . Ce talon devra probablement être écrit dans l'assembleur. Passez le HANDLE de DuplicateHandle en l'écrivant ici quelque part.
  • Exécutez votre stub en utilisant CreateRemoteThread . Le stub doit ensuite utiliser le HANDLE qu'il a obtenu pour appeler 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 - c'est-à-dire qu'il suffit d'appeler LoadLibrary (la recherche de l'adresse de LoadLibrary est laissée comme exercice au lecteur) et de faire votre travail à partir du point d'entrée dllmain de la bibliothèque. Dans ce cas, l'utilisation de la mémoire partagée nommée est probablement plus simple que de flâner avec DuplicateHandle. Voir l'article MSDN sur CreateFileMapping pour plus de détails, mais, essentiellement, passez INVALID_HANDLE_VALUE pour hFile et un nom pour lpName.

Modifier : Étant donné que votre problème passe des données et non pas une injection de code réelle, voici quelques options.

  1. Utilisez une mémoire partagée de taille variable. Votre talon obtient la taille et le nom ou une poignée 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 sa création.
  2. Utilisez un nommé 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, écrire un size_t pour la longueur, suivi du message réel. Ou utilisez PIPE_TYPE_MESSAGE et PIPE_READMODE_MESSAGE et surveillez ERROR_MORE_DATA pour déterminer la fin des messages. Cela est approprié si vous devez échanger des données plusieurs fois.

Édition 2 : Voici un aperçu de la façon dont vous pouvez implémenter le stockage de poignée ou de pointeur pour votre stub:

.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 également simplement utiliser un nom fixe, ce qui est probablement plus simple.

25
bdonlan

Vous pouvez utiliser la mémoire partagée

3
JaredPar

Avez-vous essayé d'utiliser des canaux (pour la mémoire) ou même la sérialisation (pour vos objets)? Vous pouvez utiliser des fichiers pour gérer la mémoire entre les processus. Les sockets sont également utiles pour obtenir une communication entre les processus.

1
hackus

Le mappage de la mémoire est le chemin à parcourir, vous n'avez même pas besoin de créer un espace mémoire permanent, le secteur de la mémoire sort du cadre lorsque tous les processus qui le partagent sont arrêtés. Il existe également d'autres moyens. Un moyen rapide et sale de passer des données d'une application C à une autre consiste simplement à utiliser le système d'exploitation. Sur la ligne de commande, tapez app1 | app2. Cela entraîne app2 à être la destination de sortie de app1 ou iow une commande printf de app1 l'enverrait à app2 (c'est ce qu'on appelle la tuyauterie).

1
gumby

Si vous parlez de Windows, le principal obstacle est que les processus vivent chacun dans leur propre espace d'adressage virtuel. Vous ne pouvez malheureusement pas transmettre des adresses mémoire normales d'un processus à l'autre et obtenir les résultats que vous attendez. (Les threads, en revanche, vivent tous dans le même espace d'adressage, c'est pourquoi les threads peuvent voir la mémoire de la même manière.)

Windows dispose cependant d'un espace mémoire partagé que vous devez être très prudent pour gérer correctement. Tout processus qui alloue de l'espace dans l'espace de mémoire partagée est responsable de la libération explicite de cette mémoire. Cela contraste avec la mémoire locale, qui disparaît plus ou moins à la fin du processus.

Voir cet exemple d'article MSDN pour quelques idées sur la façon dont vous pouvez utiliser l'espace de mémoire partagée pour conquérir le monde. Euh, interface avec le logiciel hérité. Ou peu importe :) Bonne chance quoi que vous finissiez par faire!

0
Mike

Vous pouvez essayer d'utiliser Boost.Interprocess pour communiquer entre deux processus. Mais pour injecter du code dans un logiciel existant, non pris en charge, vous devrez probablement utiliser la méthode de @ bdonlan en utilisant WriteProcessMemory .

0
Vargas