Облом с внедрением кода

Тема в разделе "WASM.BEGINNERS", создана пользователем SnugForce, 17 авг 2006.

  1. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    Читаю статьи Ms Rem`а. Делаю через приостановление потока и установку EIP. Код выполняется на ура, но после жертва умирает (( Единственное отличие от статьи, восстановление EIP я делаю из внедряемого потока, для этого из жертвы выставляю событие, а в своем потоке уже приостанавливаю поток жертвы и возвращаю его контекст.
    Вот внедряемы код:
    Код (Text):
    1. procedure RemoteProc(p: pointer);stdcall;
    2. var
    3.   FCreateEvent: function (lpEventAttributes: PSecurityAttributes;
    4.                bManualReset, bInitialState: BOOL; lpName: PChar): THandle; stdcall;
    5.   FSetEvent: function (hEvent: THandle): BOOL; stdcall;
    6.   FMessageBox: function (hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
    7.   //FGetLastError: function (): DWORD; stdcall;
    8.   FSleep: procedure (dwMilliseconds: DWORD); stdcall;
    9.   h: THandle;
    10.   pInfo: pTRemoteInfo;
    11. begin
    12.   asm
    13.     mov  pInfo, esi
    14.     mov  esi, [pInfo].TRemoteInfo.old_esi
    15.   end;
    16.   with pInfo^ do
    17.   begin
    18.     @FCreateEvent := FGetProcAddress(FLoadLibrary(Kernel32), CreateEventA);
    19.     @FSetEvent := FGetProcAddress(FLoadLibrary(Kernel32), SetEvent);
    20.     //@FGetLastError := FGetProcAddress(FLoadLibrary(Kernel32), GetLastError);
    21.     @FSleep := FGetProcAddress(FLoadLibrary(Kernel32), Sleep);
    22.     @FMessageBox := FGetProcAddress(FLoadLibrary(User32), MessageBoxA);
    23.  
    24.     h := FCreateEvent(nil, TRUE, FALSE, NameEvent);
    25.  
    26.     FMessageBox(0, Text, Title, 0);
    27.     FSetEvent(h);
    28.     while true do
    29.       Fsleep(1000);
    30.   end;
    31. end;
    Может проблема в том что вызыватся sleep?
     
  2. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    SnugForce
    Уточни, сумбурно как-то
     
  3. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    EvilsInterrupt
    Делаю вот что:
    Код (Text):
    1. ... // открытие процесса и нити
    2.   // тормозим нить
    3.   SuspendThread(ht);
    4.   // Получение контекста нити
    5.   old.ContextFlags := CONTEXT_FULL;
    6.   GetThreadContext(ht, old);
    7. ... // запись кода и данных в процесс
    8.   // Копируем в новый контекст и выставляем регистры
    9.   new := old;
    10.   // Указатель на след команду
    11.   new.Eip := DWORD(p_code);
    12.   // Указатель на данные
    13.   Info.old_esi := new.Esi;
    14.   new.Esi := DWORD(p_data);;
    15.  
    16.   // Устанавливаем новый контекст
    17.   SetThreadContext(ht, new);
    18.   // Запускаем внедренный код в нитке
    19.   ResumeThread(ht);
    20.   // Ожидаем когда внедренный код выставит событие
    21.   WaitForSingleObject(hEvent, INFINITE);
    22.   // Приостанавливаем нить
    23.   SuspendThread(ht);
    24.   // Устанавливаем "родной" контекст
    25.   SetThreadContext(ht, old);
    26.  
    27.   // Запускаем "родной" код
    28.   ResumeThread(ht);         // Вот после этого жерта умирает ((
     
  4. SnugForce

    SnugForce New Member

    Публикаций:
    0
    Регистрация:
    2 май 2005
    Сообщения:
    373
    Адрес:
    Из домУ
    А да, забыл - Жерта умирает тихо без сообщений и без т.п. просто нет и все...
     
  5. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    аналогичная проблема.
    Код (Text):
    1. InjectCode:
    2.         call $+5
    3.         pop ebx
    4.         sub ebx,$-InjectCode-1
    5.         lea edx,[ebx-InjectCode+new_thread]
    6.         CreateThread(0,0,edx,esp,0,0);создали уже наш поток.
    7.         CreateMutex(0,0,"SERY mutex")
    8. @@:     Sleep(1)
    9.         jmp @B;ждём пока нас вернут в родной контекст.
    10.         align 4
    11.         context2 CONTEXT
    12. new_thread:
    13.         call $+5
    14.         pop ebx
    15.         sub ebx,$-InjectCode-1
    16.         Sleep(100)
    17. tid_param:
    18.         db 68h  ;push
    19.         rb 4    ;for pointer ;we will change it on fly.
    20.         OpenThread(THREAD_ALL_ACCESS,0);открыли тот поток, который нас создал.
    21.         mov edi,eax
    22. @@:     SuspendThread(edi);тормозим.
    23.         test eax,eax
    24.         jz @b
    25.         lea edx,[ebx-InjectCode+context2]
    26.         mov ecx,sizeof.CONTEXT
    27.         sub esp,ecx
    28.         mov esi,esp
    29.         dec esi
    30.         dec edx
    31. @@:     inc edx
    32.         inc esi
    33.         mov al,[edx]
    34.         mov [esi],al
    35.         loop @b;перенесли структуру контекста в стэк. Сделано для выравнивания.
    36.         SetThreadContext(edi,esp);вернули контекст.
    37.         add esp,sizeof.CONTEXT
    38. @@:     ResumeThread(edi);пускаем его.
    39.         dec eax
    40.         jnz @B
    41.         CloseHandle(edi)
    Ну а теперь сама проблема. Всё работает для некоторых прог, у которых нет окна, а если есть программа у которой есть окно(к примеру Минипад из примеров к фасму), то он вылетает молча, там GetMessage возвращает ноль. :dntknw:
    К примерам с диалогом и остальными ехе, всё работает нормально.

    Что сделать, что бы обойти ету ерунду с GetMessage ?
     
  6. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    проверил с пример ОпенГл из фасмА, работает нормально, а с нотепадом винды он заканчивает сразу свою работу.

    *Ушел танцевать с бубном*
     
  7. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    поиграл в варкрафт, потом взял бубен и вот что нашел.

    Взял пример ОпенГЛ из пакета фасм.
    По умолчанию внедряеться нормально.
    Убрал обработку вм_паинт. - Нормально.
    Убрал "invoke InvalidateRect,[hwnd],NULL,FALSE " - происходит то же что и с нотепадом.

    Вылетам в трубу.

    Если просто убрать, "invoke InvalidateRect,[hwnd],NULL,FALSE ", но оставить вм_паинт то работает нормально.

    До этого думал, что у меня где то может в коде ошибка, но если было бы так, то ошибка проявлялась бы не так странно.

    У этой проблемы есть какое то решение? Бубен уже не помогает, что делать неясно.
     
  8. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    решение есть, но оно кривое, поэтому или не читай дальше, или не пинай :)

    Дык вот, можно попробовать изменить способ передачи управления. Например, взять в таблице импорта функцию, например, GetMessage и заменить ее адрес на свой. В последствии, при первом же вызове этой функции, восстановить адрес в таблице импорта и дальше работать спокойно. Если же этой функции нет в импортах, тогда использовать приведенный метод. Ессно это как-то криво, некрасиво и геморойно, но пока что ниче умного придумать не удалось
     
  9. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    MSoft
    интересно, вроде тот способ которым я делаю должен работать.

    И работает, но не во всех случаях. Когда не работает, я описал, теперь надо найти решение проблемы...
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    а ты разобрался в чём проблема?
     
  11. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    n0name
    думаю что да.

    При смене контекса, GetMessage возвращает WM_QUIT, и только в том случае, если окно не обрабатывает само WM_PAINT.
    Вроде, у каждого потока есть своя очередь сообщений, и GetMessage оттуда их и берет.
    То есть проблема в том, откуда в этой очереди взялося WM_QUIT.

    Где можно почитать, ка работает GetMessage ?

    З.Ы.:
    Появилось пока глупое предположение, что GetMessagе сидит и засаспендино ждёт сообщения, а я его засаспендиваю еще раз, потом меняю контекст, потом возвращаю назад, и разсаспендиваю, но так как очередт сообщений пуста, то нам возвращает GetMessage 0.
    То есть оно сидит ждёт сообщения, потом мы отработали, оно сдит ждёт и тут баз я делаю Резюме и оно в панике возвращает ноль, так как ему не дали дождать до сообщения.
     
  12. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    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 не приведёт к возобновлению приостановленных потоков
     
  13. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    бегал с бубном, бегал...
    добегался, что как-то заработало.

    Код который запускаеться и работает внутри.

    Код (Text):
    1. InjectCode:
    2.         call $+5
    3.         pop ebx
    4.         sub ebx,$-InjectCode-1
    5.         lea edx,[ebx-InjectCode+new_thread]
    6.         CreateThread(0,0,edx,esp,0,0)
    7.         lea esi,[ebx-InjectCode+msg]
    8.  
    9. @@:     PeekMessage(esi,0,0,WM_ERASEBKGND,PM_REMOVE) ;без это строки не работает!
    10. ;после её добавления, проблема решилась!
    11. ;Строка убирает все сообщения, пока нас не засаспендять и не вернуть в родное лоно.
    12.         jmp @b
    13.  
    14.         align 4
    15.         context2 CONTEXT
    16.         guithreadinfo GUITHREADINFO
    17.         msg MSG
    18. new_thread:
    19.         call $+5
    20.         pop ebx
    21.         sub ebx,$-InjectCode-1
    22.         Sleep(100)
    23. tid_param:
    24.         db 68h  ;push
    25.         rb 4    ;for pointer ;we will change it on fly.
    26.         OpenThread(THREAD_ALL_ACCESS,0)
    27.         test eax,eax
    28.         jz start_to_work
    29.         mov edi,eax
    30.         SuspendThread(edi)
    31.         lea edx,[ebx-InjectCode+context2]
    32.         mov ecx,sizeof.CONTEXT
    33.         sub esp,ecx
    34.         mov esi,esp
    35.         dec esi
    36.         dec edx
    37. @@:     inc edx
    38.         inc esi
    39.         mov al,[edx]
    40.         mov [esi],al
    41.         loop @b
    42.         SetThreadContext(edi,esp)
    43.         add esp,sizeof.CONTEXT
    44.         test eax,eax
    45.         jz start_to_work
    46. @@:     ResumeThread(edi)
    47.         dec eax
    48.         jnz @B
    49.         CloseHandle(edi)
    50.         MessageBox(0,"We are here",0,0)
    51.         ExitThread(0)
    в чём было проблема(кто помещал WM_QUIT в поток сообщения) так и не нашел. :dntknw: