원본 http://lunapiece.net/879327
#include < windows.h >
#include < cstdio >
#include < cstdlib >
bool isThreadWaiting(HANDLE ThreadHandle)
{
bool Result = false;
SuspendThread(ThreadHandle);
CONTEXT ThreadContext;
ThreadContext.ContextFlags = CONTEXT_CONTROL;
BOOL a = GetThreadContext(ThreadHandle, &ThreadContext);
INT_PTR* StackPointer = reinterpret_cast< INT_PTR* > ( ThreadContext.Esp);
HMODULE DLLHandle = LoadLibraryA("Ntdll.dll");
INT_PTR WaitFunctionPtr = reinterpret_cast< INT_PTR >( GetProcAddress(DLLHandle, "NtWaitForSingleObject"));
//WaitForSingleObject의 종착점이 되는 함수가 NtWaitForSingleObject
if ( (*StackPointer >= WaitFunctionPtr) && (*StackPointer <= WaitFunctionPtr + 50) )
{
//대충 +50을 해 주는 이유는 실제 복귀주소로 저장된 곳이 NtWaitForSingleObject의 시작주소가 아니라 조금 실행된 뒤이기 때문
Result = true;
}
FreeLibrary(DLLHandle);
ResumeThread(ThreadHandle);
return Result;
}
DWORD PASCAL ThreadFun1(PVOID Param)
{
WaitForSingleObject(HANDLE(Param), INFINITE);
return 0;
}
DWORD PASCAL ThreadFun2(PVOID Param)
{
while(true)
{
Sleep(100000);
}
return 0;
}
void main()
{
HANDLE Event = CreateEvent(nullptr, TRUE, FALSE, nullptr);
HANDLE Thread1 = CreateThread(nullptr, 0, &ThreadFun1, reinterpret_cast< LPDWORD >(Event), 0, nullptr);
HANDLE Thread2 = CreateThread(nullptr, 0, &ThreadFun2, nullptr, 0, nullptr);
Sleep(1000); //Thread 돌 시간좀 주고 ...
printf("Is Thread1 Waiting? %s\n", isThreadWaiting(Thread1) ? "Yes" : "No");
printf("Is Thread2 Waiting? %s\n", isThreadWaiting(Thread2) ? "Yes" : "No");
system("pause");
}
Wait계열 함수가 몇종류 더 있는데 그것도 그냥 각자 처리해 주면 간단...
|