Как завершаеться поток?

Тема в разделе "WASM.BEGINNERS", создана пользователем _nic, 31 окт 2011.

  1. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Код (Text):
    1. DWORD WINAPI ThrFunc(LPVOID lParam)
    2. {
    3. return(0);
    4. }
    5. CreateThread(0,0,ThrFunc,0,0,0);
    Какая функция вызываеться после окончания работы ThrFunc? Как освобождаеться память после потока?
     
  2. GRRRLPower

    GRRRLPower New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    46
    Если я правильно понял вопрос,

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659%28v=vs.85%29.aspx

    Хэндл, возвращенный CreateThread, можно закрыть сразу (CloseHandle), если он не нужен.
     
  3. ziral2088

    ziral2088 New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    283
    Если стек в порядке, после return, поток окажеться или в kernel или в ntdll, и там уже сам вызовет ExitThread/ZwTerminateThread.
    Отладчиком глянь любым, стек потока.
     
  4. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    NtTerminateThread(Если это не основной поток). Дальше в ядро ...

    Не в кое случае так как память потока не будет освобождена.



    Это относится к удалению описателя потока. так что на завершение не как не повлияет.
     
  5. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Сколько экспортируемых ф-ций,для завершения потока, вызываеться до LdrShutdownThread ?
    Провел небольшое исследование в своей 7ке.И теперь я вполном неудомение.Если завершение потока созданного обычной CreateThread можно перехватить,при помощи хука ExitThread,ZwTerminateThread,NtTerminateThread и LdrShutdownThread.То завершение потока, созданного при помощи цртшной _beginthread.МОжно перехватить только в LdrShutdownThread.Смотрел в IDA что из себя представляет _beginthread, и оно оказалось просто оберткой с CreateThread внутри.
    Код (Text):
    1. unsigned char ExitThreadOrig[5];
    2. DWORD ExitThreadAdr;
    3.  
    4. unsigned char ZwTerminateThreadOrig[5];
    5. DWORD ZwTerminateThreadAdr;
    6.  
    7. unsigned char NtTerminateThreadOrig[5];
    8. DWORD NtTerminateThreadAdr;
    9.  
    10. unsigned char LdrShutdownThreadOrig[5];
    11. DWORD LdrShutdownThreadAdr;
    12. void SetHook(void* Dst, void* Hook, unsigned char buf[5])
    13. {
    14.     if(IsBadWritePtr(buf, 5) || IsBadReadPtr(Dst, 5))
    15.     {
    16.         printf("bad params\n");
    17.         return;
    18.     }
    19.     memcpy(buf,Dst, 5);
    20.     DWORD old = 0;
    21.     VirtualProtect(Dst, 5,PAGE_EXECUTE_READWRITE, &old);
    22.     DWORD offset = (DWORD) Hook - (DWORD) Dst - 5;
    23.     *(BYTE*)Dst = 0xE9;
    24.     *(DWORD*)((DWORD)Dst+1) = offset;
    25.     VirtualProtect(Dst, 5, old, &old);
    26. }
    27. void UnsetHook(void* Dst, UCHAR buf[5])
    28. {
    29.     DWORD old = 0;
    30.     VirtualProtect(Dst, 5,PAGE_EXECUTE_READWRITE, &old);
    31.     memcpy(Dst, buf, 5);
    32.     VirtualProtect(Dst, 5, old, &old);
    33. }
    34. typedef void (WINAPI *prot_ExitThread)(__in  DWORD dwExitCode);
    35. void WINAPI HOOKfunc1(DWORD dwExitCode)
    36. {
    37.     UnsetHook((void*)ExitThreadAdr,ExitThreadOrig);
    38.     prot_ExitThread orig_ExitThread=(prot_ExitThread)ExitThreadAdr;
    39.     printf("thread exit\n");
    40.     orig_ExitThread(dwExitCode);
    41.     SetHook((void*)ExitThreadAdr,HOOKfunc1,ExitThreadOrig);
    42. }
    43. typedef NTSTATUS (NTAPI *prot_ZwTerminateThread)(IN HANDLE ThreadHandle,IN NTSTATUS ExitStatus);
    44. NTSTATUS NTAPI HOOKfunc2(HANDLE ThreadHandle,NTSTATUS ExitStatus)
    45. {
    46.     NTSTATUS stat=0;
    47.     UnsetHook((void*)ZwTerminateThreadAdr,ZwTerminateThreadOrig);
    48.     prot_ZwTerminateThread ZwTerminateThreadOrigF=(prot_ZwTerminateThread)ZwTerminateThreadAdr;
    49.     printf("thread exit\n");
    50.     stat=ZwTerminateThreadOrigF(ThreadHandle,ExitStatus);
    51.     SetHook((void*)ZwTerminateThreadAdr,HOOKfunc2,ZwTerminateThreadOrig);
    52.     return(stat);
    53. }
    54. typedef NTSTATUS (NTAPI *NtTerminateThread)(IN HANDLE ThreadHandle,IN NTSTATUS ExitStatus);
    55. NTSTATUS NTAPI HOOKfunc3(HANDLE ThreadHandle,NTSTATUS ExitStatus)
    56. {
    57.     NTSTATUS stat=0;
    58.     UnsetHook((void*)NtTerminateThreadAdr,NtTerminateThreadOrig);
    59.     NtTerminateThread _NtTerminateThread=(NtTerminateThread)NtTerminateThreadAdr;
    60.     printf("thread exit\n");
    61.     stat=_NtTerminateThread(ThreadHandle,ExitStatus);
    62.     SetHook((void*)NtTerminateThreadAdr,HOOKfunc3,NtTerminateThreadOrig);
    63.     return(stat);
    64. }
    65. typedef void (NTAPI *LdrShutdownThread)();
    66. void NTAPI HOOKfunc4()
    67. {
    68.     UnsetHook((void*)LdrShutdownThreadAdr,LdrShutdownThreadOrig);
    69.     LdrShutdownThread _LdrShutdownThread=(LdrShutdownThread)LdrShutdownThreadAdr;
    70.     printf("thread exit\n");
    71.     _LdrShutdownThread();
    72.     SetHook((void*)LdrShutdownThreadAdr,HOOKfunc4,LdrShutdownThreadOrig);
    73. }
    74. DWORD WINAPI Thr(LPVOID lParam)
    75. {
    76.     printf("Thread!\n");
    77.     return(0);
    78. }
    79. void CRTThr(void* param)
    80. {
    81.     printf("CRT Thread!\n");
    82. }
    83. int _tmain(int argc, _TCHAR* argv[])
    84. {
    85.     HMODULE kernel32=GetModuleHandle(L"kernel32.dll");
    86.     ExitThreadAdr=(DWORD)GetProcAddress(kernel32,"ExitThread");
    87.     //SetHook((void*)ExitThreadAdr,HOOKfunc1,ExitThreadOrig);
    88.     HMODULE ntdll=LoadLibrary(L"ntdll.dll");
    89.     ZwTerminateThreadAdr=(DWORD)GetProcAddress(ntdll,"ZwTerminateThread");
    90.     //SetHook((void*)ZwTerminateThreadAdr,HOOKfunc2,ZwTerminateThreadOrig);
    91.     NtTerminateThreadAdr=(DWORD)GetProcAddress(ntdll,"NtTerminateThread");
    92.     //SetHook((void*)NtTerminateThreadAdr,HOOKfunc3,NtTerminateThreadOrig);
    93.     LdrShutdownThreadAdr=(DWORD)(DWORD)GetProcAddress(ntdll,"LdrShutdownThread");
    94.     SetHook((void*)LdrShutdownThreadAdr,HOOKfunc4,LdrShutdownThreadOrig);
    95.     WaitForSingleObject(CreateThread(0,0,Thr,0,0,0),INFINITE);
    96.     _beginthread(CRTThr,0,0);
    97.     getch();
    98.     return 0;
    99. }
    В чем же дело,откудого такая ощутимая разница???? Мне к сожалению перехват LdrShutdownThread неподходит,мне нада еще попутно получать хендл завершаемого потока.Как тут быть??
     
  6. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    _nic
    А слабо взять дебаггер и посмотреть ну ли apimonitor? вопрос чисто из интереса.