И еще раз инжект. Некоторые приложения иногда падают.

Тема в разделе "WASM.BEGINNERS", создана пользователем l_inc, 20 ноя 2007.

  1. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    пардон, не увидел пост о MSDN.

    P.S.
    не очень-то понятно с первого раза, переспрашивают ;)
     
  2. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    l_inc
    Primary - в контексте потока первичный, поскольку с него приложение начинает свое исполнение. Но если он один, то он и будет основным. Другое дело, что для Windows все созданные одинаковы, она не выделяет никакого приоритета (если не задать принудительно) никакому потоку процесса. Поэтому слово основной или главный не совсем подходит (если поток один тогда да).

    Да, но под конкретную проактивку скорее всего можно :)
     
  3. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Как вариант.

    Если заглянуть в OllyDbg в стек, то можно заметить следующее:

    0096FFB8 7C80B683 RETURN to kernel32.7C80B683
    0096FFBC 00000000
    0096FFC0 008437F0
    0096FFC4 00842EC0
    0096FFC8 00000000
    0096FFCC 7FFDC000
    0096FFD0 825C2600
    0096FFD4 0096FFC0
    0096FFD8 8237E688
    0096FFDC FFFFFFFF End of SEH chain
    0096FFE0 7C839AA8 SE handler
    0096FFE4 7C80B690 kernel32.7C80B690
    0096FFE8 00000000
    0096FFEC 00000000
    0096FFF0 00000000
    0096FFF4 00401080 th.00401080 <-- То, что передавали в CreateThread(x, x, 00401080,x, x, x);
    0096FFF8 00000000
    0096FFFC 00000000




    0012FFC4 7C816FD7 RETURN to kernel32.7C816FD7
    0012FFC8 7C910738 ntdll.7C910738
    0012FFCC FFFFFFFF
    0012FFD0 7FFDE000
    0012FFD4 80543FFD
    0012FFD8 0012FFC8
    0012FFDC 8227EC10
    0012FFE0 FFFFFFFF End of SEH chain
    0012FFE4 7C839AA8 SE handler
    0012FFE8 7C816FE0 kernel32.7C816FE0
    0012FFEC 00000000
    0012FFF0 00000000
    0012FFF4 00000000
    0012FFF8 00401374 th.<ModuleEntryPoint> < -- То, что нужно.
    0012FFFC 00000000


    Соответсвенно, сканируем значения в стеке, которые должны:
    а) лежать в границах кодовой секции,
    б) равняться ЕР.


    Как сие выглядит на других системах (я просто бегло посмотрел
    под XP SP2) не знаю, может ещё будут какие-то вариации
    в зависимости от установленного софта (антивирус, hips и т.п.) или
    от извратов самой программы, но я хз, ибо нафик мне не нужно сие проверять :)

    [+]

    Код (Text):
    1. #include <stdio.h>
    2. #include <windows.h>
    3.  
    4.  
    5. DWORD WINAPI ThreadProc(
    6.   LPVOID lpParameter
    7. )
    8. {
    9.     MessageBox(NULL, "Thread", "Thread", MB_OK);
    10.     return (0);
    11. }
    12.  
    13.  
    14. int
    15. main()
    16. {
    17.  
    18.     HANDLE hThread;
    19.     DWORD ThreadId;
    20.     hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, &ThreadId);
    21.    
    22.     //WaitForSingleObject(hThread, INFINITE);
    23.    
    24.     return (0);
    25. }
    С таким кодом мессаджбокса мы не увидим, но если раскоментировать вызов WaitForSingleObject(hThread, INFINITE);,
    то появится окошко. Видимо, тут есть какие-то ньюансы. Кстати, lsass.exe - это служба, а она не убивается пока есть хоть
    один поток, ибо каждая служба может пускаться в отдельном потоке.
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Только что поэкспериментировал. Открылись новые обстоятельства.
    1) Останавливаю все потоки, кроме первичного (официально перехожу на использование этого термина)
    2) Останавливаю первичный
    3) Запускаю первичный
    4) Запускаю остальные потоки.
    При этом алгоритме все в порядке. Но! если между вторым и третим пунктом внедряю код, то счетчик suspend'ов первичного потока повышается ровно на количество потоков оперы (без понятия как =-O)!
    Если после этого я нужное количество раз делаю ResumeThread, то по достижении нуля отрабатывает внедренный код, и опера вылетает (опять таки не всегда). Причем это не зависит от того, запустил я остальные потоки до того, как счетчик suspend'ов первичного потока дошел до нуля, или после.
    Может кто-нибудь объяснить такое поведение?
     
  5. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    nester7
    Код (Text):
    1. Соответсвенно, сканируем значения в стеке, которые должны:
    2. а) лежать в границах кодовой секции,
    3. б) равняться ЕР
    Если более документированных методов кроме сканирования стэка нету, то забью я на это дело. Могу удовлетвориться и не первичным. :)
    [ADDED]
    Я не спец, но смею предположить, что не увидим только из-за того, что новый поток просто не успеет создаться.
    [ADDED 2]
    Хотя нет. Бред, т.к. CreateThread должен вернуть хэндл к уже существующему потоку.
     
  6. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    nester7
    Cтописят раз уже этот код обсуждался. ExitProcess вызывается _раньше_ чем ThreadProc !
     
  7. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    z0mailbox
    Я все эти стописят пропустил, а сам не догадался.
    Спасибо.
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Ерунда какая-то. Попробовал на VMWare и на ноутбуке (везде система WinXP SP2)... раз пятьдесят внедрил код в оперу - ни одного падения. Причем на VMWare (в отличие от ноутбука и компа) прикол со счетчиком suspend'ов потока (описанный в посте 44) не проявляется. Такое ощущение, что у меня в системе (где опера часто после внедрения падает) кроме меня еще кто-то орудует.
    Чуть не забыл: версия оперы везде одна и та же.
     
  9. EvilPhreak

    EvilPhreak New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    154
    Хочу вернуться к теме про основные и неосновные потоки. Следуя логике понятия основного потока нет, есть понятие первичного потока. Он создается вместе с процессом и начинает исполнять EP EXE. И вот как можно отличить первичный поток от не первичного (вторичного)? У всех вторичных потоков будет на вершине стека значение X. У первичного потока при этом будет значение Y.
     
  10. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    EvilPhreak
    На самом деле не совсем EP. В момент старта потока EIP указывает совсем не на EP, а на предварительный код инициализации. А на EP, и об этом написано хотя бы у Нэббета, указывает содрежимое регистра EAX. Чем, кстати, пользуется для подгрузки своей DLL Outpost: он перехватывает ZwCreateThread в нулевом кольце и подменяет содержимое EAX так, чтобы он указывал на код подгрузки DLL Oupost'а.
    Код начальной инициализации инициализирует, например, SEH, а потом уже передает управление на EP (или на то, чем подменили содержимое EAX), указанный изначально в EAX.
     
  11. EvilPhreak

    EvilPhreak New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    154
    Если бы ты понял мой пост полностью, то не довал мне эти ненужные очевидные объяснения. Причем я не говорил, что EIP указывает на EP, я сказал что этот поток будет исполнять EP. Вот EIP его и будет Y.
     
  12. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    EvilPhreak
    Ну извиняюсь, если ненужные. Но тем не менее фраза
    неверна, т.к. первичный поток, когда создается после создания и инициализации структур, отвечающих за наличие процесса в системе, НЕ начинает исполнять EP EXE, а начинает с того, о чем я написал. Иначе с таким же успехом можно было бы сказать, что после создания первичный поток начинает исполнять LdrLoadLibrary, хотя он, конечно, начинает не с этого, но все равно к этому может прити когда-нибудь после своего создания.
     
  13. t00x

    t00x New Member

    Публикаций:
    0
    Регистрация:
    15 фев 2007
    Сообщения:
    1.921
    EvilPhreak
    Y'?
     
  14. EvilPhreak

    EvilPhreak New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    154
    l_inc
    Можно было догадатся, что имел ввиду опосредованное исполнение EP. Чтож могу пояснить -
    Код (Text):
    1. .text:7C810665                 xor     ebp, ebp
    2. .text:7C810667                 push    eax
    3. .text:7C810668                 push    0
    4. .text:7C81066A                 jmp     loc_7C816FB4
    Здесь представлен вызов функции Win32StartOfProcess. Вот ее прототип -
    Код (Text):
    1. void Win32StartOfProcess(LPTHREAD_START_ROUTINE lpStartAddr, LPVOID lpvThreadParam);
    При создании процесса стартовый адрес вызывает Win32StartOfProcess. В EAX как можно догадаться, процесс родитель при создании контекста первичного потока записывает EP из опционального заголовка.

    t00x
    X - это фрейм одного финального обработчика потока, Y - другого. Ну почти вершина. Детали не обсуждаются за ненадобностью.
     
  15. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    EvilPhreak
    Ну Вы только пояснили, что Вы это знаете. :) Мне, чайнику, это было известно.
    А если перейти к Вашему вопросу, то ИМХО анализом стека определить первичность потока, если и можно, то очень нелегко. На дне стека будет лежать EAX, который, как я говорил, может быть подменен любым желающим. А на вершине вообще непонятно что. Вы ведь хотите определить первичность потока не в момент его создания (иначе проблемы просто нет: при перехвате ZwCreateThread тупо сверяете ID родительского процесса с ID процесса для которого создается поток), а в произвольный момент времени, когда процесс уже во всю дымит и пашет?
    В общем, когда я пытался решить эту проблему, то экспериментально получилось, что, если первичный поток еще существует, то он будет первым, который Вы получите при перечислении потоков обычными Toolhelp-функциями. Кроме того я просто глобализовал сплайсинг ZwCreateThread, оставляя в перхватчике на дне стэка потока метку для себя, по которой можно определить первичность потока.
     
  16. EvilPhreak

    EvilPhreak New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    154
    l_inc
    Да, тоже один из вариантов. Еще можно сравнивать TID'ы по величине, ведь они выделяются поочередно (почти). Но это не очень надежный метод - может быть как часть общей методики. Вообще про затирание вершины стека - надо все таки на что-то полагатся, и затирают оооочень не часто. Вот есть способ поиска не экспортируемых переменных анализом кода, также код ктото может поправить, но это редкие очень случаи и они не рассмариваются, хотя и безусловно должны для создания стабильного и надежного кода. Дискуссия по делу. Спасибо.
     
  17. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Эм... Я бы даже и про "почти" не говорил. Опять таки экспериментально TID'ы выделяются никак не упорядоченнее PID'ов. И следующий поток может иметь практически равновероятно, как меньший, так и больший TID.
     
  18. EvilPhreak

    EvilPhreak New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    154
    l_inc
    Отнють. У меня в тестах было как раз всегда больше. И Вам для справки - TID'ы и PID'ы выделяются из одного пространства, что может подвердить их родное происхождение.
     
  19. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    EvilPhreak
    Ну если Вас убедит произвольное упорядочивание PID'ов, то просто откройте диспетчер задач и упорядочите процессы по PID'у. Среди минимальных PID'ов будут далеко не smss, csrss, winlogon, а калькулятор с лёгкостью может получить трехзначный PID. Еще попробуйте во время тестов не создавать сразу еще 20 потоков в момент создания процесса, а перед созданием каждого нового потока завершать какое-нибудь многопоточное приложение.
     
  20. EvilPhreak

    EvilPhreak New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    154
    l_inc
    Да, убедило =)