Comment puis-je me glisser dans un autre processus ? Comme, partager le nom d'un autre processus ? Donc si mon application est griddemo.exe, et que je veux me glisser dans, disons, explorer.exe, est-ce possible ? Je viens de lire quelque chose à propos de CreateRemoteThread() de kernel32. Est-ce que cela va dans le bon sens ? Y aurait-il des problèmes de sécurité/UAC ?
Réponses
Trop de publicités?Tout d'abord, désolé, mais ma réponse sera plus longue qu'une autre.
J'utilise l'injection de DLL depuis des années dans différentes versions du système d'exploitation (de Windows NT 4.0 à Windows 7) et je n'ai jamais eu de problème avec aucun scanner de virus (y compris Norton et McAfee dans différentes versions). Je ne suis donc pas d'accord avec Stephen Cleary (voir sa réponse) sur ce point.
Utilisation de CreateRemoteThread()
n'est vraiment qu'un des moyens. AppInit_DLLs est un autre moyen. Les deux ont leurs avantages et leurs inconvénients. Le principal avantage de l'approche AppInit_DLLs est la simplicité de l'injection de DLL dans n'importe quel processus. Les principaux inconvénients de l'approche AppInit_DLLs sont les suivants :
-
Toutes les applications GUI chargera la DLL. Si vous voulez la charger seulement dans un processus comme explorer.exe vous ne pouvez pas le faire. Ainsi, l'espace de travail de tous les processus GUI sera augmenté par votre DLL. Une erreur dans votre DLL (en particulier à l'intérieur de
DllMain
ou dans toute dépendance de votre DLL) peut faire planter de nombreux processus que vous ne connaissez pas actuellement. - Vous ne pouvez pas injecter votre DLL en respectant l'approche AppInit_DLLs dans une application console ou dans tout EXE qui n'a pas de dépendance à User32.dll.
- Vous devez être très prudent à l'intérieur de votre
DllMain
car il sera appelé avant User32.dll sera initialisé complètement. Ainsi, une DLL sûre que vous pouvez utiliser à l'intérieur deDllMain
de votre DLL est Kernel32.dll.
En ce qui concerne CreateRemoteThread()
on peut démarrer un fil supplémentaire dans un processus. Le principal problème de CreateRemoteThread()
est que son lpStartAddress
doit être une adresse du processus distant . Il faut donc utiliser les fonctions OpenProcess
, VirtualAllocEx
et WriteProcessMemory
pour écrire des informations dans la mémoire du processus de destination. Pour pouvoir ouvrir un processus, il faut que le privilège de débogage soit activé. Si vous voulez seulement faire 2 + 2 à l'intérieur du processus de destination, vous pouvez copier le code binaire correspondant directement dans le processus de destination. Tout le travail réellement intéressant peut être fait avec l'utilisation de certaines API Windows. Donc, la plupart du temps, on ne copie pas un code. Au lieu de cela, on appelle LoadLibrary("MyPath\\MyDll.dll"
) à l'intérieur du processus de destination. Parce que le prototype de LoadLibrary
est le même que le prototype de ThreadProc
de CreateThread
vous pouvez appeler LoadLibrary
en tant que ThreadProc
de CreateRemoteThread()
. Cette voie porte le nom de Injection de DLL .
Je vous recommande d'utiliser cette injection de DLL. seulement si cela est vraiment nécessaire . Si votre application de destination dispose d'un autre moyen, comme des plug-ins, pour charger votre DLL à l'intérieur du processus, vous devez utiliser ce moyen au lieu de l'injection de DLL.
Quelques problèmes généraux que vous devrez résoudre après avoir obtenu un exemple fonctionnel d'injection de DLL. Ces problèmes ne sont pas visibles au premier abord, mais après une longue utilisation de votre application, vous verrez leur importance :
- Vous devez trouver le moment où le processus de destination est déjà en cours d'exécution avant de pouvoir utiliser la fonction
CreateRemoteThread()
. - L'application de destination doit être déjà initialisée avant que vous n'appeliez
CreateRemoteThread()
. Vous ne devez donc pas utiliserCreateRemoteThread()
trop tôt. Dans le cas d'explorer.exe, vous pouvez utiliser un démarrage de votre petit programme déclencheur à partir de la clé de registre Run. Pour le moment, explorer.exe est entièrement préparé pour l'injection de DLL. - Vous devez prendre en considération la version 64 bits de Windows.
- N'oubliez pas la relocalisation des DLL à l'intérieur du processus de destination. Faites attention à ce que votre DLL puisse être chargée dans le processus de destination à l'autre adresse que dans votre processus. En général, il est bon de choisir une bonne adresse de base (option du linker) pour la DLL que vous allez injecter. La Kernel32.dll peut parfois (très rarement) être chargée à l'autre adresse que celle du processus source. Vous pouvez créer un code d'injection de DLL qui est exempt de ce problème.
- Terminal Services isole chaque session de terminal par conception. Par conséquent,
CreateRemoteThread
échoue si le processus cible est dans une session différente de celle du processus appelant. Le problème peut être observé sur XP (qui n'est pas connecté au domaine) ou surtout sur Vista ou Windows 7 si vous essayez de faire une injection de DLL à partir d'un service Windows. Pour résoudre ce problème, vous devez effectuer l'injection de DLL soit à partir du processus fonctionnant dans la même session du terminal que le processus de destination, soit en changeant de session avant d'utiliser l'optionCreateRemoteThread
. Votre processus doit avoirSE_TCB_NAME
activé et utiliserSetTokenInformation
avecTokenSessionId
paramètre. Pour obtenir l'identifiant de session du processus de destination, vous pouvez utiliser différentes méthodes. Les fonctions avec le préfixe WTS (commeWTSGetActiveConsoleSessionId
) peuvent être très utiles.
Tout n'est donc pas très facile, mais c'est un sujet vraiment intéressant où vous pouvez étudier beaucoup de choses sur le système d'exploitation. Il vous suffit de consacrer un peu de temps à l'analyse de votre problème et des différentes façons de le résoudre avant de choisir la solution qui correspond aux exigences de votre projet et de commencer à programmer.
L'injection de DLL est la méthode traditionnelle pour ce faire. C'est assez délicat, d'autant plus que les antivirus voient cette pratique d'un mauvais œil. Ainsi, même si vous parvenez à la faire fonctionner, Norton/McAfee risque de vous bloquer - ou de vous bloquer à l'avenir.
Un moyen simple d'injection de DLL est la Valeur de registre AppInit_DLLs . Notez que Microsoft s'est réservé le droit de supprimer purement et simplement cette fonctionnalité (et le fera probablement à l'avenir).
La méthode approuvée par Microsoft pour réaliser l'injection de DLL est l'octroi de licences. Les détours de Microsoft .
Notez que votre DLL doit être construite contre la version 4.0 ou supérieure du CLR pour effectuer l'injection de DLL en toute sécurité, car il s'agit de la première version à prendre en charge l'in-proc côte à côte.
Si vous voulez dire injecter votre code dans un autre processus, alors l'injection de dll est une technique :
http://en.wikipedia.org/wiki/DLL_injection
Je n'ai pas fait cela depuis des années, donc je ne suis pas sûr que les systèmes d'exploitation MS Windows modernes (c.-à-d. après XP) seront satisfaits de cela.
Je n'ai pas essayé dernièrement, mais une autre façon de faire serait de créer une DLL Hook :
-
Créez une DLL qui contient une procédure d'accrochage telle que MessageProc .
-
Installer cette DLL dans Windows \System32.
-
Utilisez FindWindows(Ex) pour localiser la fenêtre du processus de votre victime.
-
Utilisez GetWindowThreadProcessId () pour trouver le thread propriétaire de cette fenêtre. Ceci est nécessaire pour éviter d'injecter votre DLL dans chaque processus du système.
-
Utilisez SetWindowsHookEx pour accrocher ce fil.
-
PostMessage un message WM_USER à la fenêtre - activant votre DLL Hook si elle n'est pas déjà active.
Cela pourrait invoquer la nouvelle Windows Vista/7 UIPI/UAC si vous n'êtes pas un utilisateur suffisamment privilégié, mais cela dépend de nombreux facteurs - votre kilométrage peut varier.