Читаю статьи Ms Rem`а. Делаю через приостановление потока и установку EIP. Код выполняется на ура, но после жертва умирает (( Единственное отличие от статьи, восстановление EIP я делаю из внедряемого потока, для этого из жертвы выставляю событие, а в своем потоке уже приостанавливаю поток жертвы и возвращаю его контекст. Вот внедряемы код: Код (Text): procedure RemoteProc(p: pointer);stdcall; var FCreateEvent: function (lpEventAttributes: PSecurityAttributes; bManualReset, bInitialState: BOOL; lpName: PChar): THandle; stdcall; FSetEvent: function (hEvent: THandle): BOOL; stdcall; FMessageBox: function (hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall; //FGetLastError: function (): DWORD; stdcall; FSleep: procedure (dwMilliseconds: DWORD); stdcall; h: THandle; pInfo: pTRemoteInfo; begin asm mov pInfo, esi mov esi, [pInfo].TRemoteInfo.old_esi end; with pInfo^ do begin @FCreateEvent := FGetProcAddress(FLoadLibrary(Kernel32), CreateEventA); @FSetEvent := FGetProcAddress(FLoadLibrary(Kernel32), SetEvent); //@FGetLastError := FGetProcAddress(FLoadLibrary(Kernel32), GetLastError); @FSleep := FGetProcAddress(FLoadLibrary(Kernel32), Sleep); @FMessageBox := FGetProcAddress(FLoadLibrary(User32), MessageBoxA); h := FCreateEvent(nil, TRUE, FALSE, NameEvent); FMessageBox(0, Text, Title, 0); FSetEvent(h); while true do Fsleep(1000); end; end; Может проблема в том что вызыватся sleep?
EvilsInterrupt Делаю вот что: Код (Text): ... // открытие процесса и нити // тормозим нить SuspendThread(ht); // Получение контекста нити old.ContextFlags := CONTEXT_FULL; GetThreadContext(ht, old); ... // запись кода и данных в процесс // Копируем в новый контекст и выставляем регистры new := old; // Указатель на след команду new.Eip := DWORD(p_code); // Указатель на данные Info.old_esi := new.Esi; new.Esi := DWORD(p_data);; // Устанавливаем новый контекст SetThreadContext(ht, new); // Запускаем внедренный код в нитке ResumeThread(ht); // Ожидаем когда внедренный код выставит событие WaitForSingleObject(hEvent, INFINITE); // Приостанавливаем нить SuspendThread(ht); // Устанавливаем "родной" контекст SetThreadContext(ht, old); // Запускаем "родной" код ResumeThread(ht); // Вот после этого жерта умирает ((
аналогичная проблема. Код (Text): InjectCode: call $+5 pop ebx sub ebx,$-InjectCode-1 lea edx,[ebx-InjectCode+new_thread] CreateThread(0,0,edx,esp,0,0);создали уже наш поток. CreateMutex(0,0,"SERY mutex") @@: Sleep(1) jmp @B;ждём пока нас вернут в родной контекст. align 4 context2 CONTEXT new_thread: call $+5 pop ebx sub ebx,$-InjectCode-1 Sleep(100) tid_param: db 68h ;push rb 4 ;for pointer ;we will change it on fly. OpenThread(THREAD_ALL_ACCESS,0);открыли тот поток, который нас создал. mov edi,eax @@: SuspendThread(edi);тормозим. test eax,eax jz @b lea edx,[ebx-InjectCode+context2] mov ecx,sizeof.CONTEXT sub esp,ecx mov esi,esp dec esi dec edx @@: inc edx inc esi mov al,[edx] mov [esi],al loop @b;перенесли структуру контекста в стэк. Сделано для выравнивания. SetThreadContext(edi,esp);вернули контекст. add esp,sizeof.CONTEXT @@: ResumeThread(edi);пускаем его. dec eax jnz @B CloseHandle(edi) Ну а теперь сама проблема. Всё работает для некоторых прог, у которых нет окна, а если есть программа у которой есть окно(к примеру Минипад из примеров к фасму), то он вылетает молча, там GetMessage возвращает ноль. К примерам с диалогом и остальными ехе, всё работает нормально. Что сделать, что бы обойти ету ерунду с GetMessage ?
проверил с пример ОпенГл из фасмА, работает нормально, а с нотепадом винды он заканчивает сразу свою работу. *Ушел танцевать с бубном*
поиграл в варкрафт, потом взял бубен и вот что нашел. Взял пример ОпенГЛ из пакета фасм. По умолчанию внедряеться нормально. Убрал обработку вм_паинт. - Нормально. Убрал "invoke InvalidateRect,[hwnd],NULL,FALSE " - происходит то же что и с нотепадом. Вылетам в трубу. Если просто убрать, "invoke InvalidateRect,[hwnd],NULL,FALSE ", но оставить вм_паинт то работает нормально. До этого думал, что у меня где то может в коде ошибка, но если было бы так, то ошибка проявлялась бы не так странно. У этой проблемы есть какое то решение? Бубен уже не помогает, что делать неясно.
решение есть, но оно кривое, поэтому или не читай дальше, или не пинай Дык вот, можно попробовать изменить способ передачи управления. Например, взять в таблице импорта функцию, например, GetMessage и заменить ее адрес на свой. В последствии, при первом же вызове этой функции, восстановить адрес в таблице импорта и дальше работать спокойно. Если же этой функции нет в импортах, тогда использовать приведенный метод. Ессно это как-то криво, некрасиво и геморойно, но пока что ниче умного придумать не удалось
MSoft интересно, вроде тот способ которым я делаю должен работать. И работает, но не во всех случаях. Когда не работает, я описал, теперь надо найти решение проблемы...
n0name думаю что да. При смене контекса, GetMessage возвращает WM_QUIT, и только в том случае, если окно не обрабатывает само WM_PAINT. Вроде, у каждого потока есть своя очередь сообщений, и GetMessage оттуда их и берет. То есть проблема в том, откуда в этой очереди взялося WM_QUIT. Где можно почитать, ка работает GetMessage ? З.Ы.: Появилось пока глупое предположение, что GetMessagе сидит и засаспендино ждёт сообщения, а я его засаспендиваю еще раз, потом меняю контекст, потом возвращаю назад, и разсаспендиваю, но так как очередт сообщений пуста, то нам возвращает GetMessage 0. То есть оно сидит ждёт сообщения, потом мы отработали, оно сдит ждёт и тут баз я делаю Резюме и оно в панике возвращает ноль, так как ему не дали дождать до сообщения.
Each thread has a suspend count (with a maximum value of MAXIMUM_SUSPEND_COUNT). If the suspend count is greater than zero, the thread is suspended; otherwise, the thread is not suspended and is eligible for execution. Calling SuspendThread causes the target thread's suspend count to be incremented. Attempting to increment past the maximum suspend count causes an error without incrementing the count. The ResumeThread function decrements the suspend count of a suspended thread. так что пара Suspend/Resume не приведёт к возобновлению приостановленных потоков
бегал с бубном, бегал... добегался, что как-то заработало. Код который запускаеться и работает внутри. Код (Text): InjectCode: call $+5 pop ebx sub ebx,$-InjectCode-1 lea edx,[ebx-InjectCode+new_thread] CreateThread(0,0,edx,esp,0,0) lea esi,[ebx-InjectCode+msg] @@: PeekMessage(esi,0,0,WM_ERASEBKGND,PM_REMOVE) ;без это строки не работает! ;после её добавления, проблема решилась! ;Строка убирает все сообщения, пока нас не засаспендять и не вернуть в родное лоно. jmp @b align 4 context2 CONTEXT guithreadinfo GUITHREADINFO msg MSG new_thread: call $+5 pop ebx sub ebx,$-InjectCode-1 Sleep(100) tid_param: db 68h ;push rb 4 ;for pointer ;we will change it on fly. OpenThread(THREAD_ALL_ACCESS,0) test eax,eax jz start_to_work mov edi,eax SuspendThread(edi) lea edx,[ebx-InjectCode+context2] mov ecx,sizeof.CONTEXT sub esp,ecx mov esi,esp dec esi dec edx @@: inc edx inc esi mov al,[edx] mov [esi],al loop @b SetThreadContext(edi,esp) add esp,sizeof.CONTEXT test eax,eax jz start_to_work @@: ResumeThread(edi) dec eax jnz @B CloseHandle(edi) MessageBox(0,"We are here",0,0) ExitThread(0) в чём было проблема(кто помещал WM_QUIT в поток сообщения) так и не нашел.