Pergunta

Eu crio um processo usando CreateProcess() com o CREATE_SUSPENDED e então crie um pequeno patch de código dentro do processo remoto para carregar uma DLL e chamar uma função (exportada por essa DLL), usando VirtualAllocEx() (com ..., MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE), WriteProcessMemory(), Em seguida, ligue FlushInstructionCache() naquele pedaço de memória com o código.

Depois disso eu ligo CreateRemoteThread() invocar esse código, criando para mim um hRemoteThread.Verifiquei que o código remoto funciona conforme planejado. Observação: esse código simplesmente retorna, ele não chama nenhuma API além de LoadLibrary() e GetProcAddress(), seguido pela chamada da função stub exportada que atualmente simplesmente retorna um valor que será passado como o status de saída do thread.

Agora vem a observação peculiar:lembre-se que o PROCESS_INFORMATION::hThread ainda está suspenso.Quando eu simplesmente ignoro hRemoteThreadcódigo de saída e também não espere que ele saia, tudo correrá "bem".A rotina que chama CreateRemoteThread() retorna e PROCESS_INFORMATION::hThread é retomado e o programa (remoto) realmente começa a ser executado.

No entanto, se eu ligar WaitForSingleObject(hRemoteThread, INFINITE) ou faça o seguinte (que tem o mesmo efeito):

DWORD exitCode = STILL_ACTIVE;
while(STILL_ACTIVE == exitCode)
{
    Sleep(500);
    if(!GetExitCodeThread(hRemoteThread, &exitCode))
        break;
}

seguido pela CloseHandle() isto leva a hRemoteThread terminando antes PROCESS_INFORMATION::hThread é retomado e o processo simplesmente "desaparece".É o suficiente para permitir hRemoteThread terminar de alguma forma sem PROCESS_INFORMATION::hThread para fazer com que o processo morra.

Isto parece suspeitamente com uma condição de corrida, já que sob certas circunstâncias hRemoteThread ainda pode ser mais rápido e o processo provavelmente ainda "desaparecerá", mesmo se eu deixar o código como está.

Isso implica que o primeiro thread executado em um processo se torna automaticamente o thread primário e que existem regras especiais para esse thread primário?

Sempre tive a impressão de que um processo termina quando seu último thread morre, não quando um especial o fio morre.

Observe também: não há chamada para ExitProcess() envolvido aqui de alguma forma, porque hRemoteThread simplesmente retorna e PROCESS_INFORMATION::hThread ainda está suspenso enquanto espero hRemoteThread para retornar.

Isso acontece no Windows XP SP3 de 32 bits.

Editar: Acabei de experimentar o Sysinternals Process Monitor para ver o que está acontecendo e pude verificar minhas observações anteriores.O código injetado não trava nem nada, em vez disso, vejo que, se não esperar pelo thread, ele não sai antes de fechar o programa onde o código foi injetado.Estou pensando se a chamada para CloseHandle(hRemoteThread) deveria ser adiado ou algo assim ...

Editar +1: não é CloseHandle().Se eu deixar isso de fora apenas para um teste, o comportamento não muda ao aguardar o término do thread.

Foi útil?

Solução

O primeiro thread a ser executado não é especial.

Por exemplo, crie um aplicativo de console que crie um thread suspenso e encerre o thread original (chamando ExitThread).Este processo nunca termina (pelo menos no Windows 7).

Ou faça o novo thread esperar cinco segundos e depois sair.Como esperado, o processo durará cinco segundos e será encerrado quando o thread secundário terminar.

Não sei o que está acontecendo com o seu exemplo.A maneira mais fácil de evitar a corrida é fazer com que o novo thread retome o thread original.

Especulando agora, me pergunto se o que você está fazendo provavelmente não causará problemas de qualquer maneira.Por exemplo, o que acontece com todos os DllMain chama as DLLs carregadas implicitamente?Eles estão acontecendo inesperadamente no thread errado, estão sendo ignorados ou são adiados até depois que o código for executado e o thread principal for iniciado?

Outras dicas

As chances são boas de que o tópico com o main (ou equivalente) chamadas de função ExitProcess (explicitamente ou em sua biblioteca de tempo de execução). ExitProcess, bem, sai de todo o processo, incluindo a eliminação de todos os threads.Como o thread principal não sabe sobre o seu código injetado, ele não espera que ele termine.

Não sei se existe uma boa maneira de fazer o thread principal aguardar a conclusão do seu ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top