CREATE_SUSPENDED
과 함께 CreateProcess()
을 사용하여 프로세스를 만든 다음 원격 프로세스 내에서 코드를 작성하여 DLL을로드하고 해당 DLL에서 내 보낸 함수를 호출하려면 VirtualAllocEx()
을 사용하십시오 (..., MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE
) WriteProcessMemory()
을 입력 한 다음 코드가있는 해당 패치에서 FlushInstructionCache()
을 호출하십시오.Win32 프로세스 내에서 실행되는 첫 번째 스레드가 "주 스레드"프로세스입니까?
그 후 CreateRemoteThread()
을 호출하여 해당 코드를 호출하여 나를 hRemoteThread
으로 만듭니다. 원격 코드가 의도 한대로 작동하는지 확인했습니다. 참고 :이 코드는 단순히 반환하고 LoadLibrary()
및 GetProcAddress()
이외의 API는 호출하지 않고 내 보낸 스텁 함수를 호출 한 다음 현재 스레드의 종료 상태로 전달되는 값을 반환하기 만합니다.
이제 특이한 관찰이 있습니다. PROCESS_INFORMATION::hThread
은 여전히 정지 상태입니다. hRemoteThread
의 종료 코드를 무시하고 종료 될 때까지 기다리지 않고 모두 "괜찮습니다". CreateRemoteThread()
을 호출하고 PROCESS_INFORMATION::hThread
을 호출하는 루틴이 재개되고 (원격) 프로그램이 실제로 실행됩니다. 그러나
, 내가 WaitForSingleObject(hRemoteThread, INFINITE)
로 문의하거나 (같은 효과를 가지고있는) 다음을 수행하는 경우 :
CloseHandle()
다음
DWORD exitCode = STILL_ACTIVE;
while(STILL_ACTIVE == exitCode)
{
Sleep(500);
if(!GetExitCodeThread(hRemoteThread, &exitCode))
break;
}
이 PROCESS_INFORMATION::hThread
가 다시 시작되기 전에 hRemoteThread
마무리로 연결 프로세스가 단순히 "사라"를. 프로세스가 종료되도록하려면 PROCESS_INFORMATION::hThread
없이 hRemoteThread
을 완료하는 것으로 충분합니다.
특정 상황에서 hRemoteThread
이 여전히 빠를 수 있고 코드를 그대로 두어도 프로세스가 여전히 "사라질"수 있기 때문에 이것은 의심스러운 경쟁 조건처럼 보입니다.
프로세스 내에서 실행되는 첫 번째 스레드가 자동으로 기본 스레드가되고 해당 기본 스레드에 대한 특수 규칙이 있음을 의미합니까?
나는 항상 스레드가 죽을 때가 아니라, 마지막 스레드가 죽을 때 프로세스가 끝난다는 인상을 받고있었습니다.
또한주의 :hRemoteThread
단순히 반환하고 내가 돌아 hRemoteThread
기다릴 때 PROCESS_INFORMATION::hThread
여전히 중단되기 때문에 어떤 식 으로든 여기에 포함 ExitProcess()
에는 전화가 없다.
Windows XP SP3, 32 비트에서 발생합니다.
편집 : 나는 Sysinternals 프로세스 모니터를 사용하여 어떤 일이 일어나고 있는지를 보았고 이전의 관찰 내용을 확인할 수있었습니다. 삽입 된 코드가 충돌하지 않거나 아무것도 아닌 대신 코드를 주입 한 프로그램을 닫기 전에 스레드를 기다리지 않으면 종료되지 않습니다.이 CloseHandle()
가 아니다 : 나는
편집 + 1 ... CloseHandle(hRemoteThread)
에 대한 호출이 연기 또는 뭔가해야하는지 여부를 생각하고 있어요. 테스트를 위해서만 남겨두면 쓰레드가 끝나기를 기다릴 때 동작이 바뀌지 않습니다.
마지막 요점을 설명하십시오. ** ** ** 같은 기본 addr에 DLL이로드되었다고 가정하는 데 문제가 발생할 것입니다. 내 프로세스에서 원격 프로세스처럼,'CreateRemoteThread'에 전달 된 명백한 오래된'LoadLibrary'는 날지 않습니다. 이것이 바로 이런 이유입니다. 게다가 메인 스레드가 프로세스를 생성 한 후 일시 중단되었을 때, DLL이 이미로드되었지만, 그때까지 'DllMain'이 호출되었는지 확실하지는 않습니다. 하지만 메인 쓰레드가 시작되고'DllMain' 내부에있을 수있게 된 후에'LoadLibrary'를 호출하지 않는 한 그것은 중요하지 않습니다. Thx – 0xC0000022L
정적 DLL이 초기화되기 전에 Windows는 일반적으로 'LoadLibrary'에 대한 호출을 보지 못합니다. 이것은 아마도 문제를 일으킬 수 있습니다. 또는 스레드에서 정적 DllMains가 호출되는 경우 초기화 스레드가 프로세스의 수명 동안 지속되는 것으로 간주하는 DLL을 혼동하게됩니다. 일반적으로 이는 사실입니다. 내가 말했듯이, 나는 추측하고 있지만 파손 가능성은 충분히있는 것으로 보인다. – arx
흠, 알았어. 다른 DLL의'DllMain'이 호출되었는지 어떻게 확인할 수 있습니까? 과거의 경험에서 나는'kernel32.dll'이 초기화되고 Win32에 대한 연결이 성립되지 않으면'CreateRemoteProcess'를 성공적으로 호출 할 수 없다는 것을 알고 있습니다. 그러나'CreateRemoteProcess' **에 대한 호출은 ** 여기서 성공적입니다. 당신이 옳을 수도 있지만, 지금은 그렇게 생각하지 않습니다. – 0xC0000022L