Допустим есть какой то процесс,есть дллка спроецированная в его адресное пространство.Как при помощи этой дллки перехватывать создание потоков в процессе?
нотифи тредаттачь, я бы на вашем месте посмотрел колстек на дллмейн а потом почитал про нотифи матчасть. Ну или наоборот хз %
Что то я не нахожу в гугле об этом ничего,для винапи. А если используется динамически _beginthreadex из какой то msvcrt ? ЗЫ:мне не просто надо отследить факт создания потока,еще надо получить содержимое переменных которые передаются в ф-цию создающую поток.
Что то у меня ничего не получается( Код (Text): struct jmp_far { BYTE instr_push; DWORD arg; BYTE instr_ret; }; BYTE original[6]; jmp_far jump; DWORD ifnc; 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) { NTSTATUS stat; printf("thread start!\n"); DWORD w; if(WriteProcessMemory(GetCurrentProcess(), (void*)ifnc, (void*)&original, 6, &w)!=TRUE) { printf("%d\n",GetLastError()); } stat=( (NTSTATUS(__stdcall*)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,HANDLE,PCLIENT_ID,PCONTEXT,PINITIAL_TEB,BOOLEAN))ifnc)(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,ThreadContext,InitialTeb,CreateSuspended); if(WriteProcessMemory(GetCurrentProcess(), (void*)ifnc,(void*)&jump, 6,&w)!=TRUE) { printf("%d\n",GetLastError()); } return(stat); } void SetIntercept() { ifnc=(DWORD)GetProcAddress(LoadLibraryA("ntdll.dll"),"NtCreateThread"); if(ifnc!=NULL) { jump.instr_push = 0x68; jump.arg = (DWORD)&hook; jump.instr_ret = 0xC3; DWORD w=0; if(ReadProcessMemory(GetCurrentProcess(),(void*)ifnc, (void*)&original, 6, &w)!=TRUE) { printf("%d\n",GetLastError()); } if(WriteProcessMemory(GetCurrentProcess(), (void*)ifnc, (void*)&jump, sizeof(jmp_far), &w)!=TRUE) { printf("%d\n",GetLastError()); } } else { printf(":(\n"); } } DWORD WINAPI Thr(LPVOID lParam) { MessageBoxA(0,"","",MB_OK); return 0; } int _tmain(int argc, _TCHAR* argv[]) { SetIntercept(); CreateThread(0,0,Thr,0,0,0); getch(); return 0; }
Скомпилированый дайте И как вы пишите в кодовую секцию, если туда запись запрещена? VirtualProtect() вставьте.
_nic Код (Text): .data NtInitRoutine PVOID ? DisableNotify BOOLEAN FALSE .code CR equ 13 LF equ 10 $DbgIcpInitRoutine CHAR "Address of ntdll initial routine: %p", CR, LF, 0 $DbgInitialCalled CHAR "Initial routine: %p, %p, %p, %p", CR, LF CHAR " - Backtrace frame: (Esp, Ebp, Eip) - ", CR, LF, 0 $DbgTraceFrame CHAR "%p, %p, %p", CR, LF, 0 $DbgContextFrame CHAR "Context: %p", CR, LF, 0 $DbgStartupRoutine CHAR "Thread startup routine: %p", CR, LF, 0 $DbgStartupParam CHAR "Thread startup parameter: %p", CR, LF, 0 STACK_FRAME struct Next PVOID ? ; PSTACK_FRAME Ip PVOID ? STACK_FRAME ends PSTACK_FRAME typedef ptr STACK_FRAME assume fs:nothing InitialRoutine proc uses ebx DllHandle:HANDLE, Reason:ULONG, Context:PCONTEXT cmp Reason,DLL_THREAD_ATTACH jne Chain invoke DbgPrint, addr $DbgInitialCalled, addr InitialRoutine, DllHandle, Reason, Context mov ebx,ebp assume ebx:PSTACK_FRAME @@: invoke DbgPrint, addr $DbgTraceFrame, ebx, [ebx].Next, [ebx].Ip mov eax,[ebx].Next cmp fs:[TEB.Tib.StackBase],eax jna @f cmp fs:[TEB.Tib.StackLimit],eax ja @f mov ebx,eax jmp @b @@: .if dword ptr [ebx + sizeof(STACK_FRAME)] == NULL add ebx,sizeof(STACK_FRAME) + 3*4 .else mov ebx,dword ptr [ebx + sizeof(STACK_FRAME)] .endif assume ebx:PCONTEXT invoke DbgPrint, addr $DbgContextFrame, ebx invoke DbgPrint, addr $DbgStartupRoutine, [ebx].regEip mov ebx,[ebx].regEsp invoke DbgPrint, addr $DbgStartupParam, STACK_FRAME.Ip[ebx] Chain: pop ebx leave .if DisableNotify mov eax,TRUE retn 3*4 .else jmp NtInitRoutine .endif InitialRoutine endp StartupRoutine proc StartupParameter:PVOID invoke RtlExitUserThread, STATUS_SUCCESS int 3 StartupRoutine endp %NTERR macro .if Eax Int 3 .endif endm Entry proc Local ThreadHandle:HANDLE, ClientId:CLIENT_ID Local Cookie:ULONG invoke LdrLockLoaderLock, LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED, NULL, addr Cookie %NTERR mov eax,fs:[TEB.Peb] lea ecx,InitialRoutine mov eax,PEB.Ldr[eax] mov eax,PEB_LDR_DATA.InLoadOrderModuleList[eax] assume eax:PLDR_DATA_TABLE_ENTRY mov eax,LDR_DATA_TABLE_ENTRY.InLoadOrderModuleList.Flink[eax] ; ntdll.dll lock xchg [eax].EntryPoint,ecx btr [eax].Flags,4 ; LDRP_DONT_CALL_FOR_THREADS mov NtInitRoutine,ecx setc byte ptr [DisableNotify] invoke LdrUnlockLoaderLock, LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED, Cookie invoke DbgPrint, addr $DbgIcpInitRoutine, NtInitRoutine invoke RtlCreateUserThread, NtCurrentProcess, NULL, FALSE, 0, 0, 0, addr StartupRoutine, 123456H, addr ThreadHandle, addr ClientId .if Eax int 3 .endif invoke ZwClose, ThreadHandle ret Entry endp
thuwiaki Годный кодес +1. Развития вопроса: Как оттросировать завершение потока(включая TerminateThread)? Всегда будет приходить нотификация во все ДЛЛ?
_nic И что я должен вам на это ответить. К сожалению я недостаточно хорошо знаю то, что понимаете вы. Ну какбы глупо В любом случае вам нужно понять принцип, тоесть я могу описать псевдокодом, если вы на асме не понимаете, но мне весьма лень сейчас это делать.
Можно ли вообще перехватить NtCreateThread в юзермоде?Если нет,то есть ли юзермодная альтернатива перехвату NtCreateThread?
Может кто то показать пример перехвата NtCreateThread или RtlCreateUserThread в юзер моде без драйвера?