$ головоломка для мыщъх'а

Тема в разделе "WASM.HEAP", создана пользователем PROFi, 28 сен 2008.

  1. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Тут пролистывал хакера августовского - статью Криса про приемы антиотладки. Любителя пошевелить серые клеточки вопросами - вопрос к нему.

    Вот такая задача - имеется 2 хадварных бряка по одному и тому же адресу исполняемого кода (не важно какому, но пусть будет код ядра)

    1) й бряк на исполнение пусть будет в DR0
    2) второй бряк на чтение (запись) пусть будет в DR1

    Теперь вопрос - при пошаговой отладке какой бряк исполнится быстрее (сама программа по адресу бряка не читает). Чтобы правильно быть понятым - какие будут значения битов B0-B1 в DR6 при исполнении под отладчиком и при реальной работе программы? PS: вопрос с маленьким подвохом :)
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    PROFi
    Если говорить про полноценную отладку то:
    Они сразу все сработать могут. Для большинства инструкций при срабатывании точки останова не имеет значения флаг TF. Регистр Dr6 нужен чтобы понять что произошло.
    Если говорить про реальные отладчики то обработчики исключений кривые и может быть всякое.
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    PROFi
    Я ляпну. Если что, то сильно не бейте. :)
    В общем это разве не зависит от способа трассировки? Т.е. Olly, например, ставит одноразовые int3 при пошаговом исполнении. Соответственно тогда раньше сработает аппаратный брэйкпоинт на чтение/запись. А если трассировка через TF, то на чтение/запись вообще по идее не должен сработать.
     
  4. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    PROFi
    вопрос, конечно, интересный, но не могу сообразить как его можно реально заюзать.
    ответ (молчаливо полагается, что ты имеешь ввиду команду типа l1:mov eax, [l2], при этом бряк один стоит на l1, бряк два на l2, бряк на чтение/запись на l1 все равно не сработает, так что это даже не обсуждается):

    1) бряк на исполнение срабатывает первым;
    2) при этом регистр EIP указывает на l1;
    3) отладчик взводит RF флаг (см. "Masking Instruction Breakpoints" в Intel sys. man);
    4) исключение от второго бряка подавляется;
    5) это работает как под отладчиком, так и без него;
    6) теоритически отладчик может и не взводить RF флаг, тогда сработают обе точки останова одна за другой.

    гм, а вообще интересный момент. если как-то вынудить хакера постаить точку останова на команду, которая обращается, например, к паролю в памяти, на который хакер так же поставил бряк, то второй бряк будет пропущен... наверное, можно будет пустить в антиотладку с thx2PROFi. след. выпуск как раз посвящен точкам останова и ситуациям когда они _не_ срабатывают. а должны ;)
     
  5. PROFi

    PROFi New Member

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

    "при этом бряк один стоит на l1, бряк два на l2" - ошибочка
    при этом бряк один стоит на l1 и бряк два на l1

    "бряк на чтение/запись на l1 все равно не сработает"
    тоже ошибочка - сработает при определенных условиях :) "6) теоритически отладчик может и не взводить RF флаг, тогда сработают обе точки останова одна за другой." - это только одно из них, и почему только отладчик "может и не взводить"?

    Реально юзается в динамическом распаковщике кода, с защитой от снятия дампа :)

    А вчем подвох - в том, что ряд отладчиков читает пямять вперед и выводит дизасемблерный листинг, в том числе и программа креш дампа (естественно на винчестер может быть записан дамп но толко через DMA доступ к памяти, а есили проц к ней обратится ...) - а как заюзать - ну я больше технологии люблю - код это дело вторичное - не судите строго :)
     
  6. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    PS: согласно мануалам интела (старым еще 386 проца) если срабатывют 2 и более условий, то устанавливаются все биты Bx, для тех бряков которые выполнились. (ответ Clerk) но не стоит забывать, что останов по инструкции это исключение, а останов по данным это ловушка :)
     
  7. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    PROFi
    > согласно мануалам интела (старым еще 368 проца) если срабатывют 2 и более условий
    в твоем примере этого не происходит. бряк на выполнение срабатывает раньше бряка на доступ к данным, т.к. бряк на выполнение срабатывает (по мануалам) до выполнения команды, а бряк на доступ - после.

    а вот если мы поставим два бряка на выполнение, тогда да, они сработают оба, хотя исключение будет выброшено только одно (а больше и не надо). как поведут себя отладчики? ну они вообще-то не позволяют ставить сразу два бряка, но туже ольгу легко обмануть, отредактировав udd файл. ольга видит только первый (в порядке возростания номеров DR регистров) бряк, что логично.
     
  8. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Ок следующий вопрос можно:
    Что делает программа (пусть будет режим пользователя) программа запущена на Win32, процессор ну пусть будет core 2 duo?

    Код (Text):
    1. .00403854: BC59384000                mov         esp,000403859
    2. .00403859: 8F442404                   pop         d,[esp][04]
    3. .0040385D: 33C0                         xor         eax,eax
    4. .0040385F: 8B00                         mov         eax,[eax]
    5. ...
     
  9. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    PROFi
    >> "бряк на чтение/запись на l1 все равно не сработает"
    > тоже ошибочка - сработает при определенных условиях :)
    а, ну если инструкцию кто-то прочтет...
    но это уже другой случай. даже если инструкция читает сама себя
    или перезаписывает сама себя, то все равно бряк на исполнение первый.
    мыщъх хотел сказать, что выполнение инструкции ЦП не считается чтением.

    >> "6) теоритически отладчик может и не взводить RF флаг,
    >> тогда сработают обе точки останова одна за другой."
    > это только одно из них, и почему только отладчик "может и не взводить"?
    как вариант, он может погасить бряк на исполнение, тогда при выполнении
    инструкции выпрыгнет бряк по чтению.

    > Реально юзается в динамическом распаковщике кода, с защитой от снятия дампа :)
    в смысле программа сама себя через DR регистры распаковывает?
    на днях дизассемблил малварь, запротекченную протектором, который я не опознал, и который именно через бряки на исполнение расшифровывает код. правда, отладчку это совершенно не мешает. и код расшифровщика элементарно рипается и переносится в статический распаковщик, т.к. он обращается всего к десятку глобальных переменных, которые приходится переносить руками, а остальное - тупой копи-пасте.

    > А вчем подвох - в том, что ряд отладчиков читает пямять вперед
    > и выводит дизасемблерный листинг, в том числе и программа креш дампа
    на счет крэша подвох в другом. ему нельзя вообще доверять.
    возмьмем, например, разогнанный проц или проц с битым/глючным L2 кэшем.
    допустим, MOV EAX, EBX в результате сбоя превращается в инструкцию,
    вызывающую исключение. но в дампе (или в JIT отладчике) все будет пучком,
    т.к. происходит перечитывание памяти. и можно очень долго ломать голову
    что за фигня творится...

    так же существует куча способов (от легальных до хаков) нарушить
    когерентность кэш-памяти, в результате чего в кэше будет одно,
    а в оперативке - другое. и тогда ни крэш-дамп, ни даже просто дамп
    ничего не даст и можно убить кучу времени, пытаясь понять что тут
    происходит и какого черта творится.... возможности прочитать
    кэш команд у нас все равно нет ;( и что там было - можно только гадать.
     
  10. PROFi

    PROFi New Member

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

    бряк на выполнение срабатывает раньше бряка на доступ к данным

    Основная работа идет в программе расшифровки кода который после бряка идет. Если первым отработал бряк на выполненние - то все ок если на чтение - что-то неладное.

    " бряк на выполнение срабатывает (по мануалам) до выполнения команды, а бряк на доступ - после."
    это тоже самое "но не стоит забывать, что останов по инструкции это исключение, а останов по данным это ловушка :)"

    Все что приведено после PS это в контексте, а не ответ на вопрос, или конкретная ситуация, я не знаю квалификации читателей форума - потому пишу подробнее.

    Ответ на превый вопрос простой: если код исполняется без просмотра кода отладчиком (не каждый отладчик сможет), то сначала исполняется бряк на исполненея, потом на доступ в память. Если нас кто хочет читать, сдампить и т.д. то первым естествено будет бряк на чтение.
     
  11. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    PROFi
    > Что делает программа (пусть будет режим пользователя)
    юзает одну из многих ошибок когерентности кэша в core?
    (модификация команды, следующей за командой, вызывающей исключение).

    а вообще много неоднозначностей. ты мне скажи:
    а) запись в .00403ххх разрешена?
    б) и сикоко у нас памяти? обработчику исключения нужен стек, а если он в ходе разбирательств столкнуется с тем, что записать данные не получится, то система просто прибьет процесс...
     
  12. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    "а) запись в .00403ххх разрешена?" - да разрешена - забыл указать :)
    "б) и сикоко у нас памяти? обработчику исключения нужен стек" - ну хватит если нужно

    эта прога просто уничтожает сама свой код

    "просто прибьет процесс..." - именно это и происходит самоуничтожение

    "на днях дизассемблил малварь, запротекченную протектором, который я не опознал, и который именно через бряки на исполнение расшифровывает код." - не одну ли и туже мы малварь ресечили ;)
     
  13. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    PROFi
    Это неправда.
    Соответственно
    .00403859: 8F442404 pop d,[esp][04]
    запишет себя по адресу после инструкций
    .0040385D: 33C0 xor eax,eax
    .0040385F: 8B00 mov eax,[eax]
    , а не вместо. Т.е. исполнится команда mov eax,[eax], и возникнет исключение. "Самоуничтожение" можно было бы сделать командой
    .00403859: 8F442400 pop d,[esp][00]
     
  14. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    PROFi
    > "просто прибьет процесс..." - именно это и происходит самоуничтожение
    так если запись разрешена и стека хватит, то самоуничтожения не произойдет. стека не хватает. проверь свой код еще раз. если в одном из потоков происходит исключение в ходе обработки которого ядру не хватает стека пользовательского пространства, то процесс уничтожается в очень интересной манере отследить которую сложно даже айсом. у ольги, кстати, тут есть забавный глюк. процесс уже сдох, но ольга об этом не знает и мы даже можем продолжить трассировать код какое-то время... но поскольку процесса у нас нету, а есть только его дохлая тушка, то попытка вызова API (например) обламывается. ну нельзя вызывать API из процесса, которого нет. весь прикол в том, что если хакер проморгает кончину процесса и продолжит его трассировать ему буде очень трудно разобраться почему отладчик перестал фурычить. (при таком завершии процесса его адресное пространство остается, именно поэтому ольга может еще протянуть чуть-чуть... но паджинг уже не работает, т.е. загрузка странц PE-файла, которые не были загружены ранее. выделение стека не работает... короче ни черта не работает. но трассировать уже загруженные страницы можно. и вызывать API целиком реализованные в юзер-спейсе и находящиеся в загруженных страницах так же можно)

    l_inc
    ну так я и написал, что модифицируюется команда следующая за командой вызывающей исключение. в данном случае это mov eax,[eax]. затирания кода не происходит (если ты это имешь ввиду). пример с затиранием кода приведен ниже.

    // TF lost before PUSH EAX
    mov edx, 0D18E6669h ; ??/MOV SS, CX

    // prepare the EAX for PUSH
    mov eax, 9C176699h ; ??.??/POP SS/PUSHFD
    mov cx, ss
    mov ax, cx ; <= for POP SS

    // jmp -> back to home
    mov edi, offset back_home
    mov ebx, 6969E7FFh ; ??.??/JMP EDI

    // to stack
    push ebx ; // LOST TF
    mov ebx, 696950F3h ; ??/??/??/PUSH EAX
    push ebx ; // LOST TF, PUSHFD, OVERWRITE PUSHFD
    push edx ; // jmp to home

    mov esi, esp
    inc esi ; skip first uf byte
    ; inc esi ; skip prefix (don't skip if it doesn't work!)
    jz back_home ; facked jx, it never takes

    // put esp on the place
    pop ebx
    pop edx

    jmp esi ; goooo
     
  15. PROFi

    PROFi New Member

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

    "почему отладчик перестал фурычить." - т.е. удаления объекта процесс не происходит, но либы все уже выгрузились или как?

    l_inc

    Угу промахнулся - пасибо
     
  16. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    kaspersky
    Ну так я ж и не Вам замечание делаю. :) Еще не хватало. Просто PROFi рассчитывал на самозатирание.
     
  17. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    PROFi
    > т.е. удаления объекта процесс не происходит, но либы все уже выгрузились или как?
    скажем так - объект процесс переходит в состояние комы.
    система уже не занимается планированием его потоков, паджингом страниц, выделением памяти, etc, но если процесс находится под отладкой, то хэнделы процесса остаются валидными и Read/WriteProcMem работают. так же процесс сохраняет регистровый контекст, и потому его можно трассировать. точнее что при этом происходит сказать не могу, т.к. глубоко в этот вопрос не зарывался.
     
  18. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    l_inc
    > Просто PROFi рассчитывал на самозатирание.
    гм, а получилось, что он натолкнулся на ошибку семейства core.
    номер по errata сейчас не скажу, но она там описана. модификация команды за командой вызывающей исключение расположенной в пределах досягаемости конвейера. при этом мы имеем шанс нарушить когерентность кэша, т.е. может быть выполнена как новая, так и старая инструкция (от чего зависит не совсем понятно...). кому интересно - может поэкспериментировать. только прежде - взглянуть на степпинг ЦП, чтобы убедиться, что ошибка там не пофиксена и запретить обновление микрокода в BIOS.
     
  19. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Ну вроде все, всем спасибо. Думаю до следующей малвари. Тему можно закрывать?
     
  20. kaspersky

    kaspersky New Member

    Публикаций:
    0
    Регистрация:
    18 май 2004
    Сообщения:
    3.006
    маленький трюк на последок. возьмем код типа:
    00000000: 3EFF10 call d,ds:[eax]
    ...
    0000000X: call 000000001

    кажется - ну и що? а вот что - бряк на 00h очевидно не сработает,
    т.к. первый байт просто не выполняется... но догадаться _почему_
    бряк не выполняется не так-то просто, особенно если мы не видим
    кода, который его вызывает (а этот код может быть очччень далеко).
    причем, можно давать как call 00h так и call 01h, т.е. в первом случае
    бряк таки сработает, а во втором нет. и мы можем замаскировать
    вызов функции [eax]

    самое смешное, что я споткнулся об него в своей же программе.
    специально подложил мышеловку и сказал: нате, ломайте.
    меня спрсили: все понятно, не понятно, почему точки останова
    не всегда срабатывают... а мыщъх к тому времени уже и забыл,
    что он нахимичил и потому стал разбираться убив минут с полчаса :derisive:))