Код (Text): DWORD WINAPI ThrFunc(LPVOID lParam) { return(0); } CreateThread(0,0,ThrFunc,0,0,0); Какая функция вызываеться после окончания работы ThrFunc? Как освобождаеться память после потока?
Если я правильно понял вопрос, http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659%28v=vs.85%29.aspx Хэндл, возвращенный CreateThread, можно закрыть сразу (CloseHandle), если он не нужен.
Если стек в порядке, после return, поток окажеться или в kernel или в ntdll, и там уже сам вызовет ExitThread/ZwTerminateThread. Отладчиком глянь любым, стек потока.
NtTerminateThread(Если это не основной поток). Дальше в ядро ... Не в кое случае так как память потока не будет освобождена. Это относится к удалению описателя потока. так что на завершение не как не повлияет.
Сколько экспортируемых ф-ций,для завершения потока, вызываеться до LdrShutdownThread ? Провел небольшое исследование в своей 7ке.И теперь я вполном неудомение.Если завершение потока созданного обычной CreateThread можно перехватить,при помощи хука ExitThread,ZwTerminateThread,NtTerminateThread и LdrShutdownThread.То завершение потока, созданного при помощи цртшной _beginthread.МОжно перехватить только в LdrShutdownThread.Смотрел в IDA что из себя представляет _beginthread, и оно оказалось просто оберткой с CreateThread внутри. Код (Text): unsigned char ExitThreadOrig[5]; DWORD ExitThreadAdr; unsigned char ZwTerminateThreadOrig[5]; DWORD ZwTerminateThreadAdr; unsigned char NtTerminateThreadOrig[5]; DWORD NtTerminateThreadAdr; unsigned char LdrShutdownThreadOrig[5]; DWORD LdrShutdownThreadAdr; void SetHook(void* Dst, void* Hook, unsigned char buf[5]) { if(IsBadWritePtr(buf, 5) || IsBadReadPtr(Dst, 5)) { printf("bad params\n"); return; } memcpy(buf,Dst, 5); DWORD old = 0; VirtualProtect(Dst, 5,PAGE_EXECUTE_READWRITE, &old); DWORD offset = (DWORD) Hook - (DWORD) Dst - 5; *(BYTE*)Dst = 0xE9; *(DWORD*)((DWORD)Dst+1) = offset; VirtualProtect(Dst, 5, old, &old); } void UnsetHook(void* Dst, UCHAR buf[5]) { DWORD old = 0; VirtualProtect(Dst, 5,PAGE_EXECUTE_READWRITE, &old); memcpy(Dst, buf, 5); VirtualProtect(Dst, 5, old, &old); } typedef void (WINAPI *prot_ExitThread)(__in DWORD dwExitCode); void WINAPI HOOKfunc1(DWORD dwExitCode) { UnsetHook((void*)ExitThreadAdr,ExitThreadOrig); prot_ExitThread orig_ExitThread=(prot_ExitThread)ExitThreadAdr; printf("thread exit\n"); orig_ExitThread(dwExitCode); SetHook((void*)ExitThreadAdr,HOOKfunc1,ExitThreadOrig); } typedef NTSTATUS (NTAPI *prot_ZwTerminateThread)(IN HANDLE ThreadHandle,IN NTSTATUS ExitStatus); NTSTATUS NTAPI HOOKfunc2(HANDLE ThreadHandle,NTSTATUS ExitStatus) { NTSTATUS stat=0; UnsetHook((void*)ZwTerminateThreadAdr,ZwTerminateThreadOrig); prot_ZwTerminateThread ZwTerminateThreadOrigF=(prot_ZwTerminateThread)ZwTerminateThreadAdr; printf("thread exit\n"); stat=ZwTerminateThreadOrigF(ThreadHandle,ExitStatus); SetHook((void*)ZwTerminateThreadAdr,HOOKfunc2,ZwTerminateThreadOrig); return(stat); } typedef NTSTATUS (NTAPI *NtTerminateThread)(IN HANDLE ThreadHandle,IN NTSTATUS ExitStatus); NTSTATUS NTAPI HOOKfunc3(HANDLE ThreadHandle,NTSTATUS ExitStatus) { NTSTATUS stat=0; UnsetHook((void*)NtTerminateThreadAdr,NtTerminateThreadOrig); NtTerminateThread _NtTerminateThread=(NtTerminateThread)NtTerminateThreadAdr; printf("thread exit\n"); stat=_NtTerminateThread(ThreadHandle,ExitStatus); SetHook((void*)NtTerminateThreadAdr,HOOKfunc3,NtTerminateThreadOrig); return(stat); } typedef void (NTAPI *LdrShutdownThread)(); void NTAPI HOOKfunc4() { UnsetHook((void*)LdrShutdownThreadAdr,LdrShutdownThreadOrig); LdrShutdownThread _LdrShutdownThread=(LdrShutdownThread)LdrShutdownThreadAdr; printf("thread exit\n"); _LdrShutdownThread(); SetHook((void*)LdrShutdownThreadAdr,HOOKfunc4,LdrShutdownThreadOrig); } DWORD WINAPI Thr(LPVOID lParam) { printf("Thread!\n"); return(0); } void CRTThr(void* param) { printf("CRT Thread!\n"); } int _tmain(int argc, _TCHAR* argv[]) { HMODULE kernel32=GetModuleHandle(L"kernel32.dll"); ExitThreadAdr=(DWORD)GetProcAddress(kernel32,"ExitThread"); //SetHook((void*)ExitThreadAdr,HOOKfunc1,ExitThreadOrig); HMODULE ntdll=LoadLibrary(L"ntdll.dll"); ZwTerminateThreadAdr=(DWORD)GetProcAddress(ntdll,"ZwTerminateThread"); //SetHook((void*)ZwTerminateThreadAdr,HOOKfunc2,ZwTerminateThreadOrig); NtTerminateThreadAdr=(DWORD)GetProcAddress(ntdll,"NtTerminateThread"); //SetHook((void*)NtTerminateThreadAdr,HOOKfunc3,NtTerminateThreadOrig); LdrShutdownThreadAdr=(DWORD)(DWORD)GetProcAddress(ntdll,"LdrShutdownThread"); SetHook((void*)LdrShutdownThreadAdr,HOOKfunc4,LdrShutdownThreadOrig); WaitForSingleObject(CreateThread(0,0,Thr,0,0,0),INFINITE); _beginthread(CRTThr,0,0); getch(); return 0; } В чем же дело,откудого такая ощутимая разница???? Мне к сожалению перехват LdrShutdownThread неподходит,мне нада еще попутно получать хендл завершаемого потока.Как тут быть??