CreateRemoteThread, fonction (processthreadsapi.h)

Crée un thread qui s’exécute dans l’espace d’adressage virtuel d’un autre processus.

Utilisez la fonction CreateRemoteThreadEx pour créer un thread qui s’exécute dans l’espace d’adressage virtuel d’un autre processus et spécifier éventuellement des attributs étendus.

Syntaxe

HANDLE CreateRemoteThread(
  [in]  HANDLE                 hProcess,
  [in]  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  [in]  SIZE_T                 dwStackSize,
  [in]  LPTHREAD_START_ROUTINE lpStartAddress,
  [in]  LPVOID                 lpParameter,
  [in]  DWORD                  dwCreationFlags,
  [out] LPDWORD                lpThreadId
);

Paramètres

[in] hProcess

Handle du processus dans lequel le thread doit être créé. Le handle doit avoir les droits d’accès PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE et PROCESS_VM_READ , et peut échouer sans ces droits sur certaines plateformes. Pour plus d’informations, consultez Traiter les droits de sécurité et d’accès.

[in] lpThreadAttributes

Un pointeur vers une structure SECURITY_ATTRIBUTES qui spécifie un descripteur de sécurité pour le nouveau thread et détermine si les processus enfants peuvent hériter du handle retourné. Si lpThreadAttributes a la valeur NULL, le thread obtient un descripteur de sécurité par défaut et le handle ne peut pas être hérité. Les listes de contrôle d’accès (ACL) dans le descripteur de sécurité par défaut d’un thread proviennent du jeton principal du créateur.

Windows XP : Les listes de contrôle d’accès dans le descripteur de sécurité par défaut d’un thread proviennent du jeton principal ou d’emprunt d’identité du créateur. Ce comportement a changé avec Windows XP avec SP2 et Windows Server 2003.

[in] dwStackSize

Taille initiale de la pile, en octets. Le système arrondit cette valeur à la page la plus proche. Si ce paramètre est égal à 0 (zéro), le nouveau thread utilise la taille par défaut pour l’exécutable. Pour plus d’informations, consultez Taille de la pile de threads.

[in] lpStartAddress

Un pointeur vers la fonction définie par l’application de type LPTHREAD_START_ROUTINE à exécuter par le thread et représente l’adresse de départ du thread dans le processus distant. La fonction doit exister dans le processus distant. Pour plus d’informations, consultez ThreadProc.

[in] lpParameter

Pointeur vers une variable à passer à la fonction thread.

[in] dwCreationFlags

Indicateurs qui contrôlent la création du thread.

Valeur Signification
0
Le thread s’exécute immédiatement après sa création.
CREATE_SUSPENDED
0x00000004
Le thread est créé dans un état suspendu et ne s’exécute pas tant que la fonction ResumeThread n’est pas appelée.
STACK_SIZE_PARAM_IS_A_RESERVATION
0x00010000
Le paramètre dwStackSize spécifie la taille de réserve initiale de la pile. Si cet indicateur n’est pas spécifié, dwStackSize spécifie la taille de validation.

[out] lpThreadId

Pointeur vers une variable qui reçoit l’identificateur de thread.

Si ce paramètre a la valeur NULL, l’identificateur de thread n’est pas retourné.

Valeur retournée

Si la fonction réussit, la valeur de retour est un handle pour le nouveau thread.

Si la fonction échoue, la valeur de retour est NULL. Pour obtenir des informations détaillées sur l’erreur, appelez GetLastError.

Notez que CreateRemoteThread peut réussir même si lpStartAddress pointe vers des données, du code ou n’est pas accessible. Si l’adresse de début n’est pas valide lorsque le thread s’exécute, une exception se produit et le thread se termine. L’arrêt du thread en raison d’une adresse de début non valide est géré comme une sortie d’erreur pour le processus du thread. Ce comportement est similaire à la nature asynchrone de CreateProcess, où le processus est créé même s’il fait référence à des bibliothèques de liens dynamiques (DLL) non valides ou manquantes.

Remarques

La fonction CreateRemoteThread entraîne le démarrage d’un nouveau thread d’exécution dans l’espace d’adressage du processus spécifié. Le thread a accès à tous les objets que le processus ouvre.

Avant Windows 8, les services Terminal Server isolent chaque session de terminal par conception. Par conséquent, CreateRemoteThread échoue si le processus cible se trouve dans une autre session que le processus appelant.

Le nouveau handle de thread est créé avec un accès complet au nouveau thread. Si aucun descripteur de sécurité n’est fourni, le handle peut être utilisé dans n’importe quelle fonction nécessitant un handle d’objet thread. Lorsqu’un descripteur de sécurité est fourni, un case activée d’accès est effectué sur toutes les utilisations ultérieures du handle avant d’accorder l’accès. Si le case activée d’accès refuse l’accès, le processus demandeur ne peut pas utiliser le handle pour accéder au thread.

Si le thread est créé dans un état exécutable (autrement dit, si l’indicateur CREATE_SUSPENDED n’est pas utilisé), le thread peut commencer à s’exécuter avant le retour de CreateThread et, en particulier, avant que l’appelant ne reçoive le handle et l’identificateur du thread créé.

Le thread est créé avec une priorité de thread de THREAD_PRIORITY_NORMAL. Utilisez les fonctions GetThreadPriority et SetThreadPriority pour obtenir et définir la valeur de priorité d’un thread.

Lorsqu’un thread se termine, l’objet thread atteint un état signalé, qui satisfait les threads qui attendent l’objet.

L’objet thread reste dans le système jusqu’à ce que le thread soit terminé et que tous les handles qu’il contient soient fermés via un appel à CloseHandle.

Les fonctions ExitProcess, ExitThread, CreateThread, CreateRemoteThread et un processus qui démarre (à la suite d’un appel CreateProcess ) sont sérialisées entre elles au sein d’un processus. Un seul de ces événements se produit dans un espace d’adressage à la fois. Cela signifie que les restrictions suivantes sont appliquées :

  • Pendant le démarrage du processus et les routines d’initialisation de DLL, de nouveaux threads peuvent être créés, mais ils ne démarrent pas l’exécution tant que l’initialisation de la DLL n’est pas terminée pour le processus.
  • Un seul thread d’un processus peut être dans une routine d’initialisation ou de détachement de DLL à la fois.
  • ExitProcess retourne une fois que tous les threads ont terminé leurs routines d’initialisation ou de détachement de DLL.
Une utilisation courante de cette fonction consiste à injecter un thread dans un processus en cours de débogage pour émettre un arrêt. Toutefois, cette utilisation n’est pas recommandée, car le thread supplémentaire prête à confusion pour la personne qui débogue l’application et il existe plusieurs effets secondaires à l’utilisation de cette technique :
  • Il convertit les applications à thread unique en applications multithread.
  • Il modifie le minutage et la disposition de la mémoire du processus.
  • Il en résulte un appel au point d’entrée de chaque DLL dans le processus.
Une autre utilisation courante de cette fonction consiste à injecter un thread dans un processus pour interroger le tas ou d’autres informations de processus. Cela peut entraîner les mêmes effets secondaires mentionnés dans le paragraphe précédent. En outre, l’application peut s’interblocage si le thread tente d’obtenir la propriété des verrous qu’un autre thread utilise.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows XP [applications de bureau uniquement]
Serveur minimal pris en charge Windows Server 2003 [applications de bureau uniquement]
Plateforme cible Windows
En-tête processthreadsapi.h (inclure Windows.h sur Windows Server 2003, Windows Vista, Windows 7, Windows Server 2008 Windows Server 2008 R2)
Bibliothèque Kernel32.lib
DLL Kernel32.dll

Voir aussi

CloseHandle

CreateProcess

CreateRemoteThreadEx

CreateThread

ExitProcess

ExitThread

GetThreadPriority

Fonctions de processus et de thread

ResumeThread

SECURITY_ATTRIBUTES

SetThreadPriority

ThreadProc

Threads