Partager via


CreateRemoteThreadEx, fonction (processthreadsapi.h)

Crée un thread qui s’exécute dans l’espace d’adressage virtuel d’un autre processus et spécifie éventuellement des attributs étendus tels que l’affinité de groupe de processeurs.

Syntaxe

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

Paramètres

[in] hProcess

Handle du processus dans lequel le thread doit être créé. Le handle doit disposer des droits d’accès PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE et PROCESS_VM_READ. Dans Windows 10, version 1607, votre code doit obtenir ces droits d’accès pour le nouveau handle. Toutefois, à compter de Windows 10, version 1703, si le nouveau handle a droit à ces droits d’accès, le système les obtient pour vous. Pour plus d’informations, consultez Processus de sécurité et de droits d’accès.

[in, optional] lpThreadAttributes

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.

[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 pile de threads.

[in] lpStartAddress

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, optional] lpParameter

Pointeur vers une variable à passer à la fonction thread pointée par lpStartAddress. Ce paramètre peut être NULL.

[in] dwCreationFlags

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

Valeur Signification
0
Le thread s’exécute immédiatement après la 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.

[in, optional] lpAttributeList

Liste d’attributs qui contient des paramètres supplémentaires pour le nouveau thread. Cette liste est créée par la fonction InitializeProcThreadAttributeList.

[out, optional] 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 de retour

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’erreur étendues, appelez GetLastError.

Remarques

La fonction CreateRemoteThreadEx provoque le début 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. Le paramètre lpAttribute peut être utilisé pour spécifier des attributs étendus tels que l’affinité de groupe de processeurs pour le nouveau thread. Si lpAttribute a la valeur NULL, le comportement de la fonction est identique à CreateRemoteThread.

Avant Windows 8, Terminal Services isole chaque session de terminal par conception. Par conséquent, CreateRemoteThread échoue si le processus cible se trouve dans une session différente de celle du processus appelant.

Le nouveau handle de thread est créé avec un accès complet au nouveau thread. Si un descripteur de sécurité n’est pas 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, une vérification d’accès est effectuée sur toutes les utilisations ultérieures du handle avant l’octroi de l’accès. Si la vérification 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 CreateThread retourne 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. Pour obtenir et définir la valeur de priorité d’un thread, utilisez les fonctions GetThreadPriority et SetThreadPriority.

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 se termine et que tous les handles qu’il soit fermé par le biais d’un appel à CloseHandle.

Les ExitProcess, ExitThread, CreateThread, Fonctions CreateRemoteThread et un processus qui démarre (à la suite d’un appel CreateProcess) sont sérialisés entre eux 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 en attente :

  • Pendant le démarrage du processus et les routines d’initialisation de DLL, de nouveaux threads peuvent être créés, mais ils ne commencent pas l’exécution tant que l’initialisation dll n’est pas terminée pour le processus.
  • Un seul thread d’un processus peut se trouver dans une initialisation DLL ou détacher une routine à la fois.
  • ExitProcess retourne une fois que tous les threads ont terminé leur initialisation dll ou détachent des routines.
Une utilisation courante de cette fonction consiste à injecter un thread dans un processus en cours de débogage pour émettre un saut. Toutefois, cette utilisation n’est pas recommandée, car le thread supplémentaire est déroutant pour la personne qui débogue l’application et il existe plusieurs effets secondaires pour utiliser cette technique :
  • Il convertit les applications monothread en applications multithread.
  • Il modifie le minutage et la disposition de la mémoire du processus.
  • Il entraîne un appel au point d’entrée de chaque DLL du 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 bloquer si le thread tente d’obtenir la propriété des verrous qu’un autre thread utilise.

Exigences

Exigence Valeur
client minimum pris en charge Windows 7 [applications de bureau uniquement]
serveur minimum pris en charge Windows Server 2008 R2 [applications de bureau uniquement]
plateforme cible Windows
d’en-tête processthreadsapi.h (inclure Windows.h sur Windows Server 2008 Windows Server 2008 R2)
bibliothèque Kernel32.lib
DLL Kernel32.dll

Voir aussi

CreateRemoteThread