# новый способ ловли fs

Тема в разделе "WASM.HEAP", создана пользователем kaspersky, 20 дек 2007.

  1. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    все мы знаем сколько интересного находится в сегменте на который указывает fs и как защиты используют эти данные в своих коварных целях. вот мыщъх и задумался - как отслеживать любые обращения к содержимому сегмента, адресуемого fs на чтение/запись из _любого_ (подчеркиваю, из _любого_) отладчика. покурив хорошей травы (прошлогодних мануалов от Intel), мыщъх вспомнил о нулевых селекторах. грузим в fs ноль (или один, два, три...) и все! это можно сделать и с прикладного режима. теперь после всякого обращения к нему (типа mov eax, fs:[00000000h]) будет генерироваться исключение, перехватываемое отладчиком. что мы делаем?! мы врубаемся в ситуацию, восстанавливаем fs, выполняем инструкцию (или эмулируем ее выполнение :derisive: после чего вновь сбрасываем fs в ноль.

    кстати, это можно использовать в качестве навесного протектора для создания программ, расшифровывающихся на лету. я раньше писал такую штуку. ставил все страницы в no_access и ловил исключения. проблема, однако, в том, что практически все программы сами активно юзают исключения и потому приходилось ставить аппаратный бряк на fs:[00000000h], чтобы мой фильтр был всегда наверху. использование нулевого селектора значительно все упрощает. бряки можно не ставить.

    фемида и другие протекторы, расшифровывающие код на лету, идут несколько другим путем и порождают отладочный процесс, получающий уведомления об исключениях без всяких заморочек, однако, порождать отладочный процесс не есть хорошо. мой способ лучше ;) ИМХО, конечно.

    в аттаче пример использование нулевого селектора. попытайтесь его отладить ;) просто прогнать под отладчиком. хоть пошаговым исполнением, хоть по F9 (run) в Olly.
     
  2. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    А если защита сделает так?
    Код (Text):
    1. mov ax,fs
    2. cmp ax,4
    3. jb somebody_tries_to_hack_us ; format_drive_C
     
  3. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    kaspersky

    Технологию пользовал в своем отладчике года 2,5 назад... Только в 64 битах не тестировал, должно по идее исключение вызывать

    Кстати поделюсь еще одним способом, он гораздо менее эффективен, но. Если сделать так
    mov ax,fs
    mov es,ax
    mov ds,ax

    а потом что-то вроде int 2E (ну или sysenter)? то по исключению можно найти код обработки указанного прерывания - XP не меняет принудительно селекторы в этих сегментах и есстественно при записи в память (а память kernel mode) будет исключение. А вот fs меняется принудительно при переходе в кернел моде, но пользовать его можно..
    Ктстати таким способом ловятся все перемещения системных таблиц (вызова функций, числа параметров и т.д)
     
  4. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    схожую тему обсуждали нидавно, только применительно к йадру и там идейа загадить гдт была, а не ФС :) но как сказал nobody - детектецо это и правицо :) хотя можно сделоть
    mov ax,ds
    mov fs,ax
    и активно работать с данными через fs, тогда это действительно затруднит отладку в разы (да исчо и исключенийа кидать почаще)
     
  5. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    нет
    нужно менять IA32_FS_BASE
     
  6. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    Freeman
    люди, да вы що?!
    fs нещадно эксплуатирует нефигасе API-функций, и сишных либ. так это перед каждым вызовом API его придется восстанавливать... смысла нет ;(

    diamond
    нулевым слектором считается селектор с номером 0, 1, 2 или 3
    mov ax, 4
    mov fs, ax
    вызовет что? правильно - исключение. а вот если в fs у нас 0,1,2,3
    то исключения отдыхают ;) поскольку адрес обработчика лежит в fs,
    а fs недоступен. с прикладного режима можно перехватывать такие
    исключения только через SetUnhandledExceptionFilter, которая
    (внимание!!!) не вызывается под отладчиком (порождение
    отладочного процесса или аттач. так что олька идет лесом,
    работают только soft-ice и syser. в примере который я закинул выше
    это наглядно продемонстрировано... а раз SetUnhandledExceptionFilter
    не вызвается, то...

    кстати, нашел способ детекта некторых эмулирующих отладчиков.
    они не эмулируют потерю трассировочного прерывания после
    модификации ss. пишем самотрассирующую программу и смотрим:
    если потери трассировочного прерывания не происходило, то мы
    под эмулирующим отладчиком. или под обычным отладчиком,
    который фиксит потерю трассировочного прерывания.

    аналогичным путем можно играться с флагами. меня умиляет

    MOV AX, SS
    PUSHFD
    MOV SS,AX
    POPFD

    суть в том, что отладчик "вычищает" TF флаг из PUSHFD,
    но из-за потери трассировочного прерывания, POPFD
    реально сбрасывает TF флаг ;)
     
  7. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    Уже давно никто не отлаживает программы пошагово - ставят несколько бряков по коду и пускают дебаггер по F9. Накой приводить аж в 2-х топиках "баянный" трюк я не понимаю.
     
  8. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    dermatolog
    1) некоторые фрагменты программы (распаковщики, например) отлаживаются именно пошагово;

    2) для Olly существует множество плагинов, реализующих тот или иной функционал именно посредством трассировки;

    3) многие распаковщики находят OEP именно трассировкой;

    4) указанный трюк позволяет отличать эмулирующие отладчики даже без трассировки (программа трассирует сама себя)

    5) если это баян, почему на нем палятся все отладчики?!
    почему они старательно вычищают TF из PUSHFD, причем половина из них
    знает о префиксах типа REP PUSHFD и лихо их обходит, но вот про потерю
    трассировочного прерывания не вспоминает никто...

    6) был бы не баян, не размешал бы я его в хипе ;)
     
  9. zoool

    zoool New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2007
    Сообщения:
    412
    push ss
    pop ss
    mov eax, 0x12345678

    что должно было произойти?
    В ольке мы перепрыгнули через
    mov eax, 0x12345678
    но в еах-е оказалось 12345678

    т.е. отлично все эмулится.
    С кодом КК про флаги - аналогично...

    Или я что-то не так делаю?
     
  10. zoool

    zoool New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2007
    Сообщения:
    412
    А разве выполнение кода в стеке везде разрешены? В Висте и дальнейших системах этот трюк прокатывает?
     
  11. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    ты никак не запретишь интерпретацию данных как кода
    без Execute Disable Bit и/или использования сегментации
    ОС тут не причем
     
  12. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    zoool
    > В Висте и дальнейших системах этот трюк прокатывает?
    в 32-битных системах по умолчанию DEP задействован только для системы и некоторых прикладных приложений типа IE. и хотя есть возможность задействовать DEP для всех приложений, очень немногие юзеры пользуют эту опцию:
    а) потому что не знают о ней
    б) потому что тогда не будет работать куча других программ

    ну вообще-то мне было просто лень вызывать VirtualProtect :) ведь это тестовый код и меня больше интересует работает ли инструкция mov ss,ax/mov ax,ss без префикса 66h или нет ;) сейчас покурил мануалы и понял, что работает ;)

    а вот под 9x данный пример не работоспособен, т.к. я использую часть стека выше esp, то есть свободную ;) там короче маленький прикол ;)
    в eax толкаются команды pop ss/pushfd и значение ss. команда push eax
    засылает это дело в стек, стек опускается и на push eax передается управление.

    push eax затирает саму себя, но закидывает на вершину стека ss и команды pop ss/pushfd, которые получают управление.

    pushfd затирает саму себя ;) хе-хе ;) чтобы не так бросалась в глаза ;)
    ну и оставляет в стеке флаги, включая TF флаг.

    это чисто анти-olly. потрассируйте это в olly и в soft-ice/syser/windbg и почувствуйте разницу ;)
     
  13. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Гм... это, безусловно, так, но я не про то... mov ax,fs запихивает в ax значение fs, то есть 0,1,2,3 при предлагаемом методе и 0x3B (кажется, под NT+ это всегда так) при нормальном выполнении. При этом никаких исключений не происходит и отладчик не имеет никаких шансов этому помешать. Ну а далее защита может проверить, что получилось в ax, и если там явно не то, что должно быть, то над программой издевается хакер и дальнейшие действия могут быть любыми в зависимости от фантазии разработчика защиты.
     
  14. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    diamond
    38h на w2k == fs, другие не проверял.
    защит, проверяющих значение fs в настоящий момент не обнаружено ;)
    хотя да, они могут очень быстро появится и начать плодиться как кролики в сахаре. или в глазури ;)

    кстати, с точки зрения защиты... я же предлагал потрассировать или просто запустить по F9 указанный пример под отладчиком. суть в том, что если fs = 0,
    то команда mov eax, fs:[00000000h] (очень популярная команда :derisive: генерит исключение. вот только чтобы передать управление обработчику, она _должна_ прочитать fs:[00000000h], а это невозможно. поэтому возникает ситуация "необрабатываемое исключение", которую можно поймать функцией SetUnhandledExceptionFilter и сделать там что-то полезное.

    и вот мы подошли к самой сути. под отладчиком SetUnhandledExceptionFilter _НЕ_ вызывается. это не баг отладчика, это фича системы. следовательно, код обработчика при выполнении под отладчиком просто не получит управления.

    кстати, чем вам не идея генерить необрабатываемое исключение и осуществлять проверку валидности серийного номера в обработчике, установленном SetUnhandledExceptionFilter? под отладчком этот код вообще не получит управление. то есть абсолютно. хоть ставь бряк на введенную строку с именем пользователя -- ее никто не бдует читать. ну разве что создать подложный код, который при выполнении под отладчиком вычисляет сернум слегка по другому ;)
     
  15. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    kaspersky
    HideDebugger by Asterix вроде решает эту проблему (для Оли)
     
  16. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    leo
    Кури MSDN.
    Там русским по белому написано - под отладчиком обработчик, установленный с помощью SetUnhandledExceptionFilter _НЕ_ вызывается. Так что проблему эту решить врядли получится... ;)
     
  17. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    Twister
    мыщъх не юзал HideDebugger by Asterix,
    но проблему решить можно.
    bpx SetUnhandledExceptionFilter,
    запоминаем адрес переданного ей обработчика,
    и когда Olly скажет, что больше не может отлаживать программу,
    меняем EIP на адрес обработчика... только еще в стек придется покласть STRUCT _EXCEPTION_POINTERS *ExceptionInfo, что геморно. и уж точно не всякий хакер догадается это сделать ;) тем более что...

    Код (Text):
    1. .text:77E878A7                SetUnhandledExceptionFilter proc near
    2. .text:77E878A7
    3. .text:77E878A7                lpTopLevelExceptionFilter= dword ptr  4
    4. .text:77E878A7
    5. .text:77E878A7 8B 4C 24 04                        mov ecx, [esp+lpTopLevelExceptionFilter]
    6. .text:77E878AB A1 4C 04 EE 77                     mov eax, dword_77EE044C
    7. .text:77E878B0 89 0D 4C 04 EE+                    mov dword_77EE044C, ecx
    8. .text:77E878B6 C2 04 00                           retn 4
    9. .text:77E878B6                SetUnhandledExceptionFilter endp
    мыщъх знает несколько способов как найти dword_77EE044C в памяти, так что SetUnhandledExceptionFilter можно и не вызывать ;) и тогда бряк на нее не сработает.

    а по-моему очень хорошая идея использовать SetUnhandledExceptionFilter, чтобы изменить поведение защиты под отладчиком. критический код просто не получит управления и все. и ласты. под отладчиком можно тупо говорить, что программа зарегистрирована успешно и все проверки пройдены на ура. вот только проверки в обработчике SetUnhandledExceptionFilter под отладчиком управления не получат ;)
     
  18. PaCHER

    PaCHER New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    852
    kaspersky
    И как его создать если у нас необрабатываемое исключение под отладкой.
     
  19. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Согласен. Оценил этот способ по достоинству. Заюзаю его в своем проекте - а то там у меня слишком жесткий способ антиотладки: в тихую вызывается процедура, которая закрывает все хэндлы Debug-объектов в системе. ;) Кстати, а нет ли какой инфы по Debug-объектам? Нужно по хэндлу определить, какой процесс отлаживается.
     
  20. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    leo
    ага, вроде должен ;)