· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.RESEARCH —› "патч самого себя" vs "конвеер"

. 1 . 2 . >>

Посл.отвђт Сообщенiе


Дата: Апр 21, 2004 16:34:36

Слышал я про существование хитрого приема анти-трассировки. Если пропатчить код сразу же за выполняемой инструкцией, то разумеется при трассировке отладчик выполнит пропатченный код.

А при обычном запуске к моменту выполнения команды, которая патчит, несколько следующих команд уже якобы будут загружены в конвеер команд, и поэтому будут выполнены непропатченые команды.

Хочу уточнить у специалистов - действительно ли это так? Если да, то дальше куча вопросов.

- Для каких процессоров это верно?
- Сколько команд загружается в конвеер?
- Как заполняется конвеер - блоками (выполнили весь код из конвеера, загрузили новый) или побайтно (выполнили одну инструкцию, на ее место загрузили следующую)?
- Что произойдет, если несколько таких команд будет
выполняться в цикле? А если не весь цикл помещается в конвеер?
- Нет ли инструкций (не функций, про FlushInstructionCache я в курсе, а именно ассемблерных инструкций), сбрасывающих конвеер?

P.S. Если на какие-то из вопросов ответы нетривиальны и/или требуют экспериментов, просто скажите об этом, и я постараюсь разобраться сам. Просто не хотелось бы изобратать велосипед :)
P.P.S. Все это для ring3 под Win2K+.


Дата: Апр 21, 2004 16:48:35

У меня этот прием проходил на процессорах 80486 и на 1-ом пентиуме MMX. На новеньком Celerone этот фокус не прошел. То есть он выполнял модифицированную инструкцию. Поподробнее можешь почитать об этом в моей теме на форуме, которая называется "Крякмис". Там в моем крякмисе использование этого приема не работает на новых компах. Если будут непонятности, то спрашивай.


Дата: Апр 23, 2004 11:57:04 · Поправил: RobinFood

Почитал "Крякмис", почитал "книгу двойных слов"... Кое-что в голове "утряслось", на свои собственные вопросы я теперь могу дать ответы. Если возникнут еще какие-то вопросы по этой теме - обращайтесь :)

- Для каких процессоров это верно?
В одном месте написано, что верно только для 486, в другом - только для 486-Pentium, в третьем - только для PentiumPro-Pentium4... В общем, этого достаточно, чтобы НЕ полагаться на такой метод обнаружения трассировки.

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

- Как заполняется конвеер - блоками (выполнили весь код из конвеера, загрузили новый) или побайтно (выполнили одну инструкцию, на ее место загрузили следующую)?
Информации об этом я не нашел, но если немного подумать, то можно прийти к выводу, что блочная загрузка конвеера только замедлит его работу, а рз конвееры делаются для ускорения, значит, загрузка всегда (кроме, возможно, наличия пустого конвеера) выполняется побайтно.

- Что произойдет, если несколько таких команд будет
выполняться в цикле? А если не весь цикл помещается в конвеер?
Зависит от процессора. На 486 команда jmp гарантированно сбрасывает конвеер. На других процессорах - в зависимости от правильности "предсказания" перехода конвеер либо будет сброшен, либо нет... Если же цикл в конвеер не поместился, то тут и говорить не о чем - естественно будут прочитаны модифицированные команды.

- Нет ли инструкций (не функций, про FlushInstructionCache я в курсе, а именно ассемблерных инструкций), сбрасывающих конвеер?
Есть. На 486 - jmp, на P4 - cpuid. Наверняка есть и другие, но они недокуметированы. Для их обнаружения надо делать эксперименты, а мне лень.

Вывод. Нет смысла пользоваться таким ненадежным методом, если есть другие, гораздо более надежные.


Дата: Апр 23, 2004 17:04:51

Как заполняется конвеер - блоками или побайтно

В 24896607.pdf пишется что для NetBurst архитектуры (PIV):
The hardware instruction fetcher reads instructions along the path predicted by the BTB into the instruction streaming buffers. Data is read in 32-byte chunks starting at the target address.

Дальше:
The front end of the Intel NetBurst micro-architecture has a single decoder that can decode instructions at the maximum rate of one instruction per clock. Some complex instructions must enlist the help of the microcode ROM.

и наконец:
The execution trace cache (TC) is the primary instruction cache in the Intel NetBurst micro-architecture. The TC stores decoded IA-32 instructions, or µops. This removes decoding costs on frequently-executed code, such as template restrictions and the extra latency to decode instructions upon a branch misprediction.

Т.е. происходит кеширование уже декодировенных инструкций (µops). Тут уже явно видно, что внутри RISC архитектура и ни о каких x86 инструкциях речи нет совсем. Отсюда и проблемы с бранчами и т.п. Зато какая частота ядра :)


Дата: Апр 23, 2004 18:17:18

угу... это я очень невнятно выразился :(.

Хотел спросить - большими блоками (сравнимыми с размером кэша) или маленькими (сравнимыми с размером инструкции). Значит, маленькими, как я и думал. Спасибо за цитаты - это место я как-то проморгал.

Ну, разве что кэш совсем пустой - может, тогда и побольше загрузят... но это уже к первоначальному вопросу отношения не имеет :).


Дата: Апр 23, 2004 19:03:41

Дык длинна конвеера-то всего несколько стадий, а кеш - килобайты ;-)

Но я не про это. Процессоры сейчас имеют внутреннее RISC ядро, что и как оно делает - Know How производителя.
И в общем-то информация как-то все больше скрывается :( Я вот смотрел - однозначного ответа на вопрос так и не нашел :(


Дата: Апр 28, 2004 21:27:47

Не совсем в тему, но всеже думаю полезно будет взглянуть на это


Дата: Май 22, 2004 05:15:51

начиная с P6 (P Pro, P II...) программная длина конвейера равна нулю, т.к. проц. ослеживает модификацию команд уже находящихся на конвейере и перезагружает последний. обычно это дает тормоза, но может и не дать, во всяком случае, делать самомодифицируюшийся код _можно_.


Дата: Май 22, 2004 22:25:10

> программная длина конвейера равна нулю

Хотелось бы подробнее узнать об отличаях программной и аппаратной длин конвеера.


> во всяком случае, делать самомодифицируюшийся код _можно_

Конечно, можно.
Только работать он может по-разному.


Дата: Май 22, 2004 23:04:53

http://www.x86.org/secrets/prefetchqueue.htm

И поищи в гугле - есть сайт со списком багов IA32 процессоров. Возможно там че-нить полезное найдешь.


Дата: Май 23, 2004 03:45:04

аппаратная длина конвейера определяется архитектурными особенностями ЦП и у всех камней она сильно неодинакова.
в эпоху диназавров, когда о пнях еще никто и не слыхом не слыхивал, процессоры не учитывали существование самомодифицирующегося кода и потому инструкция, уже попавшая на конвейер, игнорировала попытки своей модификации в памяти, во всяком случае до второго пришествия, тьфу, исполнения ;)
можно найти много программок которые таким образом длину конвейера и определяли. правда, на пнях они перестали работать, бо те поумнени настолько, что смотрели куда происходит запись и сбрасывали ковейер при необходимости, что создавала обманичивое впечатление, что длина конвейера равна нулю. вот это и есть программная длина.
на пнях самомомодифицирующийся код всегда исполняется правильно, поэтому за это можно не переживать. и "по-разному" он работать не может.
некоторые защиты поступают так: они модифицируют свой код и засекают время его выполнения, которое при выполнении на живом процессоре скачнообразно увеличивается, но эмуляторы этого не учитывают... пока... к тому же процессоры в любом момент могут преодолеть эту задержку, тогда защита откажает в работе.
короче: привязываться к задержка низя, а просто юзать самомодификацию - сам бог велел.


Дата: Май 23, 2004 04:21:20

а просто юзать самомодификацию - сам бог велел

Это ты имеешь в виду в защитах?


Дата: Май 23, 2004 05:25:13

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


Дата: Май 23, 2004 22:22:30

> юзать самомодификацию - сам бог велел.

Это медленно работает.


Дата: Май 24, 2004 10:48:14

а это уже смотря как модифицировать ;)
тем более, что никто не предлагает делать самомодифицирующимися критические участки кода, а для защиты самомодификация это самое то, т.к. она:
1) чрезвычано затрудняет дизассемблирование;
2) делает невозможным установку программных точек останова;
3) облмамывает отладчики на степах;
4) обламывает дамперы
5) и т.д. и т.п.

. 1 . 2 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.081