Как можно перехватывать создание потоков?

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

  1. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Допустим есть какой то процесс,есть дллка спроецированная в его адресное пространство.Как при помощи этой дллки перехватывать создание потоков в процессе?
     
  2. thuwiaki

    thuwiaki New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2011
    Сообщения:
    25
    нотифи тредаттачь, я бы на вашем месте посмотрел колстек на дллмейн а потом почитал про нотифи матчасть. Ну или наоборот хз %
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    _nic
    Новосозданные потоки вызывают точку входа каждой dll процесса с параметром DLL_THREAD_ATTACH.
     
  4. Toxasoft

    Toxasoft New Member

    Публикаций:
    0
    Регистрация:
    20 сен 2010
    Сообщения:
    188
    Перехват CreateThread ну или читай http://www.wasm.ru/article.php?article=apihook_1
     
  5. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Что то я не нахожу в гугле об этом ничего,для винапи.

    А если используется динамически _beginthreadex из какой то msvcrt ?

    ЗЫ:мне не просто надо отследить факт создания потока,еще надо получить содержимое переменных которые передаются в ф-цию создающую поток.
     
  6. Sunzer

    Sunzer Member

    Публикаций:
    0
    Регистрация:
    25 май 2008
    Сообщения:
    256
    В итоге-то вызовется все равно NtCreateThread()
     
  7. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Что то у меня ничего не получается(

    Код (Text):
    1. struct jmp_far
    2. {
    3.   BYTE instr_push;
    4.   DWORD arg;        
    5.   BYTE  instr_ret;  
    6. };
    7.  
    8. BYTE original[6];
    9. jmp_far jump;
    10. DWORD ifnc;
    11.  
    12. NTSTATUS NTAPI hook(OUT PHANDLE ThreadHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,IN HANDLE ProcessHandle,OUT PCLIENT_ID ClientId,IN PCONTEXT ThreadContext,IN PINITIAL_TEB InitialTeb,IN BOOLEAN CreateSuspended)
    13. {
    14.     NTSTATUS stat;
    15.     printf("thread start!\n");
    16.     DWORD w;
    17.     if(WriteProcessMemory(GetCurrentProcess(), (void*)ifnc, (void*)&original, 6, &w)!=TRUE)
    18.     {
    19.         printf("%d\n",GetLastError());
    20.     }
    21.     stat=( (NTSTATUS(__stdcall*)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,HANDLE,PCLIENT_ID,PCONTEXT,PINITIAL_TEB,BOOLEAN))ifnc)(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,ThreadContext,InitialTeb,CreateSuspended);
    22.     if(WriteProcessMemory(GetCurrentProcess(), (void*)ifnc,(void*)&jump, 6,&w)!=TRUE)
    23.     {
    24.         printf("%d\n",GetLastError());
    25.     }
    26.     return(stat);
    27. }
    28.  
    29. void SetIntercept()
    30. {
    31.     ifnc=(DWORD)GetProcAddress(LoadLibraryA("ntdll.dll"),"NtCreateThread");
    32.     if(ifnc!=NULL)
    33.     {
    34.         jump.instr_push = 0x68;
    35.         jump.arg = (DWORD)&hook;
    36.         jump.instr_ret = 0xC3;
    37.         DWORD w=0;
    38.         if(ReadProcessMemory(GetCurrentProcess(),(void*)ifnc, (void*)&original, 6, &w)!=TRUE)
    39.         {
    40.             printf("%d\n",GetLastError());
    41.         }
    42.         if(WriteProcessMemory(GetCurrentProcess(), (void*)ifnc, (void*)&jump, sizeof(jmp_far), &w)!=TRUE)
    43.         {
    44.             printf("%d\n",GetLastError());
    45.         }
    46.     }
    47.     else
    48.     {
    49.         printf(":(\n");
    50.     }
    51. }
    52.  
    53. DWORD WINAPI Thr(LPVOID lParam)
    54. {
    55.     MessageBoxA(0,"","",MB_OK);
    56.     return 0;
    57. }
    58. int _tmain(int argc, _TCHAR* argv[])
    59. {
    60.     SetIntercept();
    61.     CreateThread(0,0,Thr,0,0,0);
    62.     getch();
    63.     return 0;
    64. }
     
  8. Sunzer

    Sunzer Member

    Публикаций:
    0
    Регистрация:
    25 май 2008
    Сообщения:
    256
    Скомпилированый дайте

    И как вы пишите в кодовую секцию, если туда запись запрещена?

    VirtualProtect() вставьте.
     
  9. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Sunzer
    WriteProcessMemory сам делает VirtualProtect при необходимости.
     
  10. thuwiaki

    thuwiaki New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2011
    Сообщения:
    25
    _nic
    Код (Text):
    1. .data
    2. NtInitRoutine       PVOID ?
    3. DisableNotify       BOOLEAN FALSE
    4.  
    5. .code
    6. CR  equ 13
    7. LF  equ 10
    8.  
    9. $DbgIcpInitRoutine  CHAR "Address of ntdll initial routine: %p", CR, LF, 0
    10. $DbgInitialCalled   CHAR "Initial routine: %p, %p, %p, %p", CR, LF
    11.                 CHAR " - Backtrace frame: (Esp, Ebp, Eip)  - ", CR, LF, 0
    12. $DbgTraceFrame      CHAR "%p, %p, %p", CR, LF, 0
    13. $DbgContextFrame    CHAR "Context: %p", CR, LF, 0
    14. $DbgStartupRoutine  CHAR "Thread startup routine: %p", CR, LF, 0
    15. $DbgStartupParam    CHAR "Thread startup parameter: %p", CR, LF, 0
    16.  
    17. STACK_FRAME struct
    18. Next        PVOID ? ; PSTACK_FRAME
    19. Ip      PVOID ?
    20. STACK_FRAME ends
    21. PSTACK_FRAME typedef ptr STACK_FRAME
    22.  
    23.     assume fs:nothing
    24. InitialRoutine proc uses ebx DllHandle:HANDLE, Reason:ULONG, Context:PCONTEXT
    25.     cmp Reason,DLL_THREAD_ATTACH
    26.     jne Chain
    27.     invoke DbgPrint, addr $DbgInitialCalled, addr InitialRoutine, DllHandle, Reason, Context
    28.     mov ebx,ebp
    29.     assume ebx:PSTACK_FRAME
    30. @@:
    31.     invoke DbgPrint, addr $DbgTraceFrame, ebx, [ebx].Next, [ebx].Ip
    32.     mov eax,[ebx].Next
    33.     cmp fs:[TEB.Tib.StackBase],eax
    34.     jna @f
    35.     cmp fs:[TEB.Tib.StackLimit],eax
    36.     ja @f
    37.     mov ebx,eax
    38.     jmp @b
    39. @@:
    40.     .if dword ptr [ebx + sizeof(STACK_FRAME)] == NULL
    41.         add ebx,sizeof(STACK_FRAME) + 3*4
    42.     .else
    43.         mov ebx,dword ptr [ebx + sizeof(STACK_FRAME)]
    44.     .endif
    45.     assume ebx:PCONTEXT
    46.     invoke DbgPrint, addr $DbgContextFrame, ebx
    47.     invoke DbgPrint, addr $DbgStartupRoutine, [ebx].regEip
    48.     mov ebx,[ebx].regEsp
    49.     invoke DbgPrint, addr $DbgStartupParam, STACK_FRAME.Ip[ebx]
    50. Chain:
    51.     pop ebx
    52.     leave
    53.     .if DisableNotify
    54.         mov eax,TRUE
    55.         retn 3*4
    56.     .else
    57.         jmp NtInitRoutine
    58.     .endif
    59. InitialRoutine endp
    60.  
    61. StartupRoutine proc StartupParameter:PVOID
    62.     invoke RtlExitUserThread, STATUS_SUCCESS
    63.     int 3
    64. StartupRoutine endp
    65.  
    66. %NTERR macro
    67.     .if Eax
    68.         Int 3
    69.     .endif
    70. endm
    71.  
    72. Entry proc
    73. Local ThreadHandle:HANDLE, ClientId:CLIENT_ID
    74. Local Cookie:ULONG
    75.     invoke LdrLockLoaderLock, LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED, NULL, addr Cookie
    76.     %NTERR
    77.     mov eax,fs:[TEB.Peb]
    78.     lea ecx,InitialRoutine
    79.     mov eax,PEB.Ldr[eax]
    80.     mov eax,PEB_LDR_DATA.InLoadOrderModuleList[eax]
    81.     assume eax:PLDR_DATA_TABLE_ENTRY
    82.     mov eax,LDR_DATA_TABLE_ENTRY.InLoadOrderModuleList.Flink[eax]   ; ntdll.dll
    83.     lock xchg [eax].EntryPoint,ecx
    84.     btr [eax].Flags,4   ; LDRP_DONT_CALL_FOR_THREADS
    85.     mov NtInitRoutine,ecx
    86.     setc byte ptr [DisableNotify]
    87.     invoke LdrUnlockLoaderLock, LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED, Cookie
    88.     invoke DbgPrint, addr $DbgIcpInitRoutine, NtInitRoutine
    89.     invoke RtlCreateUserThread, NtCurrentProcess, NULL, FALSE, 0, 0, 0, addr StartupRoutine, 123456H, addr ThreadHandle, addr ClientId
    90.     .if Eax
    91.         int 3
    92.     .endif
    93.     invoke ZwClose, ThreadHandle
    94.     ret
    95. Entry endp
     
  11. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    thuwiaki
    Годный кодес +1. Развития вопроса: Как оттросировать завершение потока(включая TerminateThread)? Всегда будет приходить нотификация во все ДЛЛ?
     
  12. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    К сожалению я недостоточно хорошо знаю ассемблер.
     
  13. thuwiaki

    thuwiaki New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2011
    Сообщения:
    25
    _nic
    И что я должен вам на это ответить. К сожалению я недостаточно хорошо знаю то, что понимаете вы. Ну какбы глупо :)
    В любом случае вам нужно понять принцип, тоесть я могу описать псевдокодом, если вы на асме не понимаете, но мне весьма лень сейчас это делать.
     
  14. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Можно ли вообще перехватить NtCreateThread в юзермоде?Если нет,то есть ли юзермодная альтернатива перехвату NtCreateThread?
     
  15. thuwiaki

    thuwiaki New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2011
    Сообщения:
    25
    _nic
    Можно, работайте.
     
  16. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    thuwiaki
    Так как на счет получения нотификации завершении потока по TerminateThread?
     
  17. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    На каком уровне цепочки ф-ций тянущихся за CreateThread происходит инициализация TEBа ?
     
  18. _nic

    _nic New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2007
    Сообщения:
    372
    Может кто то показать пример перехвата NtCreateThread или RtlCreateUserThread в юзер моде без драйвера?