Compartilhar via


Função CreateRemoteThreadEx (processthreadsapi.h)

Cria um thread que é executado no espaço de endereço virtual de outro processo e, opcionalmente, especifica atributos estendidos, como afinidade de grupo de processadores.

Sintaxe

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
);

Parâmetros

[in] hProcess

Um identificador para o processo no qual o thread deve ser criado. O identificador deve ter os direitos de acesso PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE e PROCESS_VM_READ. No Windows 10, versão 1607, seu código deve obter esses direitos de acesso para o novo identificador. No entanto, a partir do Windows 10, versão 1703, se o novo identificador tiver direito a esses direitos de acesso, o sistema os obterá para você. Para obter mais informações, consulte Direitos de acesso e segurança do processo.

[in, optional] lpThreadAttributes

Um ponteiro para uma estrutura SECURITY_ATTRIBUTES que especifica um descritor de segurança para o novo thread e determina se os processos filho podem herdar o identificador retornado. Se lpThreadAttributes for NULL, o thread obterá um descritor de segurança padrão e o identificador não poderá ser herdado. As ACL (listas de controle de acesso) no descritor de segurança padrão para um thread vêm do token primário do criador.

[in] dwStackSize

O tamanho inicial da pilha, em bytes. O sistema arredonda esse valor para a página mais próxima. Se esse parâmetro for 0 (zero), o novo thread usará o tamanho padrão para o executável. Para obter mais informações, consulte Tamanho da pilha do thread.

[in] lpStartAddress

Um ponteiro para a função definida pelo aplicativo do tipo LPTHREAD_START_ROUTINE a ser executado pelo thread e representa o endereço inicial do thread no processo remoto. A função deve existir no processo remoto. Para obter mais informações, consulte ThreadProc.

[in, optional] lpParameter

Um ponteiro para uma variável a ser passada para a função de thread apontada por lpStartAddress. Este parâmetro pode ser NULL.

[in] dwCreationFlags

Os sinalizadores que controlam a criação do thread.

Valor Significado
0
O thread é executado imediatamente após a criação.
CREATE_SUSPENDED
0x00000004
O thread é criado em um estado suspenso e não é executado até que a função ResumeThread seja chamada.
STACK_SIZE_PARAM_IS_A_RESERVATION
0x00010000
O parâmetro dwStackSize especifica o tamanho inicial da reserva da pilha. Se esse sinalizador não for especificado, dwStackSize especificará o tamanho da confirmação.

[in, optional] lpAttributeList

Uma lista de atributos que contém parâmetros adicionais para o novo thread. Essa lista é criada pela função InitializeProcThreadAttributeList .

[out, optional] lpThreadId

Um ponteiro para uma variável que recebe o identificador de thread.

Se esse parâmetro for NULL, o identificador de thread não será retornado.

Retornar valor

Se a função for bem-sucedida, o valor retornado será um identificador para o novo thread.

Se a função falhar, o valor retornado será NULL. Para obter informações de erro estendidas, chame GetLastError.

Comentários

A função CreateRemoteThreadEx faz com que um novo thread de execução comece no espaço de endereço do processo especificado. O thread tem acesso a todos os objetos que o processo abre. O parâmetro lpAttribute pode ser usado para especificar atributos estendidos, como afinidade de grupo de processadores para o novo thread. Se lpAttribute for NULL, o comportamento da função será o mesmo que CreateRemoteThread.

Antes de Windows 8, os Serviços de Terminal isolam cada sessão de terminal por design. Portanto, CreateRemoteThread falhará se o processo de destino estiver em uma sessão diferente do processo de chamada.

O novo identificador de thread é criado com acesso completo ao novo thread. Se um descritor de segurança não for fornecido, o identificador poderá ser usado em qualquer função que exija um identificador de objeto de thread. Quando um descritor de segurança é fornecido, um marcar de acesso é executado em todos os usos subsequentes do identificador antes que o acesso seja concedido. Se o acesso marcar negar acesso, o processo de solicitação não poderá usar o identificador para obter acesso ao thread.

Se o thread for criado em um estado executável (ou seja, se o sinalizador CREATE_SUSPENDED não for usado), o thread poderá começar a ser executado antes que CreateThread retorne e, em particular, antes que o chamador receba o identificador e o identificador do thread criado.

O thread é criado com uma prioridade de thread de THREAD_PRIORITY_NORMAL. Para obter e definir o valor de prioridade de um thread, use as funções GetThreadPriority e SetThreadPriority .

Quando um thread termina, o objeto de thread atinge um estado sinalizado, que satisfaz os threads que estão aguardando o objeto.

O objeto thread permanece no sistema até que o thread seja encerrado e todos os identificadores dele sejam fechados por meio de uma chamada para CloseHandle.

As funções ExitProcess, ExitThread, CreateThread, CreateRemoteThread e um processo que está sendo iniciado (como resultado de uma chamada CreateProcess ) são serializados entre si em um processo. Apenas um desses eventos ocorre em um espaço de endereço por vez. Isso significa que as seguintes restrições são retenção:

  • Durante as rotinas de inicialização de processo e inicialização de DLL, novos threads podem ser criados, mas eles não iniciam a execução até que a inicialização da DLL seja feita para o processo.
  • Somente um thread em um processo pode estar em uma rotina de inicialização ou desanexação de DLL por vez.
  • ExitProcess retorna depois que todos os threads tiverem concluído suas rotinas de inicialização ou desanexação de DLL.
Um uso comum dessa função é injetar um thread em um processo que está sendo depurado para emitir uma interrupção. No entanto, esse uso não é recomendado, pois o thread extra é confuso para a pessoa que depura o aplicativo e há vários efeitos colaterais para usar essa técnica:
  • Ele converte aplicativos de thread único em aplicativos multithread.
  • Ele altera o layout de tempo e memória do processo.
  • Isso resulta em uma chamada para o ponto de entrada de cada DLL no processo.
Outro uso comum dessa função é injetar um thread em um processo para consultar heap ou outras informações de processo. Isso pode causar os mesmos efeitos colaterais mencionados no parágrafo anterior. Além disso, o aplicativo poderá fazer deadlock se o thread tentar obter a propriedade de bloqueios que outro thread está usando.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows 7 [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows Server 2008 R2 [somente aplicativos da área de trabalho]
Plataforma de Destino Windows
Cabeçalho processthreadsapi.h (inclua Windows.h no Windows Server 2008 Windows Server 2008 R2)
Biblioteca Kernel32.lib
DLL Kernel32.dll

Confira também

CreateRemoteThread