Win32 프로세스 내에서 실행되는 첫 번째 스레드가 "기본 스레드"입니까?의미론을 이해해야 합니다.

StackOverflow https://stackoverflow.com//questions/9695370

문제

나는 다음을 사용하여 프로세스를 만듭니다. CreateProcess() 와 더불어 CREATE_SUSPENDED 그런 다음 원격 프로세스 내부에 작은 코드 패치를 만들어 DLL을 로드하고 함수(해당 DLL에서 내보낸)를 호출합니다. VirtualAllocEx() (와 함께 ..., MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE), WriteProcessMemory(), 그런 다음 전화하세요 FlushInstructionCache() 코드가 있는 메모리 패치에

그 후에 나는 전화한다. CreateRemoteThread() 해당 코드를 호출하여 나에게 hRemoteThread.원격 코드가 의도한 대로 작동하는지 확인했습니다. 메모: 이 코드는 단순히 반환만 할 뿐 다른 API를 호출하지 않습니다. LoadLibrary() 그리고 GetProcAddress(), 현재 단순히 스레드의 종료 상태로 전달될 값을 반환하는 내보낸 스텁 함수를 호출합니다.

이제 특이한 관찰이 나옵니다.기억하세요. PROCESS_INFORMATION::hThread 아직 정지 상태입니다.내가 그냥 무시할 때 hRemoteThread의 종료 코드를 입력하고 종료될 때까지 기다리지 마십시오. 모든 것이 "괜찮습니다".호출하는 루틴 CreateRemoteThread() 반품 및 PROCESS_INFORMATION::hThread 재개되고 (원격) 프로그램이 실제로 실행됩니다.

그런데 내가 전화하면 WaitForSingleObject(hRemoteThread, INFINITE) 또는 다음을 수행하십시오(동일한 효과가 있음).

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

이어서 CloseHandle() 이는 다음으로 이어진다 hRemoteThread 전에 마무리 PROCESS_INFORMATION::hThread 다시 시작되고 프로세스가 단순히 "사라집니다".허락하는 것만으로도 충분하다 hRemoteThread 어떻게든 끝내려고 PROCESS_INFORMATION::hThread 프로세스가 종료되도록 합니다.

이는 특정 상황에서 경쟁 조건처럼 의심스럽게 보입니다. hRemoteThread 코드를 그대로 두더라도 여전히 더 빠를 수 있으며 프로세스가 여전히 "사라질" 수 있습니다.

이는 프로세스 내에서 실행되는 첫 번째 스레드가 자동으로 기본 스레드가 되고 해당 기본 스레드에 대한 특별한 규칙이 있음을 의미합니까?

나는 항상 프로세스가 종료될 때가 아니라 마지막 스레드가 죽을 때 끝난다는 인상을 받았습니다. 특정한 스레드가 죽습니다.

또한 참고하세요: 전화가 없습니다 ExitProcess() 어떤 식으로든 여기에 관여했으니까. hRemoteThread 단순히 반환하고 PROCESS_INFORMATION::hThread 내가 기다리는 동안 여전히 일시중지되었습니다. hRemoteThread 돌려 주다.

이 문제는 Windows XP SP3, 32비트에서 발생합니다.

편집하다: 방금 Sysinternals Process Monitor를 사용해 무슨 일이 일어나고 있는지 확인했고 이전에 관찰한 내용을 확인할 수 있었습니다.삽입된 코드는 충돌하거나 아무것도 발생하지 않습니다. 대신 스레드를 기다리지 않으면 코드가 삽입된 프로그램을 닫기 전에 스레드가 종료되지 않는다는 것을 알게 됩니다.전화를 받을지 생각 중이에요 CloseHandle(hRemoteThread) 연기해야 한다던가..

편집+1: 그렇지 않다 CloseHandle().테스트용으로만 남겨두면 스레드가 완료될 때까지 기다릴 때 동작이 변경되지 않습니다.

도움이 되었습니까?

해결책

실행되는 첫 번째 스레드는 특별하지 않습니다.

예를 들어 일시 중단된 스레드를 생성하고 원래 스레드를 종료하는(ExitThread 호출을 통해) 콘솔 앱을 만듭니다.이 프로세스는 결코 종료되지 않습니다(어쨌든 Windows 7에서는).

또는 새 스레드가 5초 동안 대기한 후 종료되도록 합니다.예상대로 프로세스는 5초 동안 유지되며 보조 스레드가 종료되면 종료됩니다.

나는 당신의 예에서 무슨 일이 일어나고 있는지 모르겠습니다.경합을 피하는 가장 쉬운 방법은 새 스레드가 원래 스레드를 재개하도록 만드는 것입니다.

지금 추측해보면, 당신이 하고 있는 일이 어쨌든 문제를 일으킬 가능성은 없는지 궁금합니다.예를 들어, 모든 사람들에게 무슨 일이 일어나는가? DllMain 암시적으로 로드된 DLL을 호출합니까?잘못된 스레드에서 예기치 않게 발생하고 있습니까? 건너뛰고 있습니까? 아니면 코드가 실행되고 메인 스레드가 시작될 때까지 연기됩니까?

다른 팁

확률은 좋은 것 같습니다. main (또는 이에 상응하는) 함수 호출 ExitProcess (명시적으로 또는 런타임 라이브러리에서). ExitProcess, 음, 모든 스레드 종료를 포함하여 전체 프로세스를 종료합니다.메인 스레드는 삽입된 코드에 대해 알지 못하므로 코드가 완료될 때까지 기다리지 않습니다.

메인 스레드가 완료될 때까지 기다리게 하는 좋은 방법이 있는지 모르겠습니다...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top