Re: Re:самомодифицирующийся код?

From
Gennady Mayko ()
To
Vladimir Ivanov
Date
2002-10-08T11:25:19Z
Area
SU.WINDOWS.NT.PROG
From: "Gennady Mayko" <gennady.mayko@broadcom.com>

Добрый день!

 VI> Расскажу свой способ, сводящий вероятность к нулю:
--
Рискну в данной случае с этим не согласится...


 VI> 1. Поднимаем приоритет потока (достаточно, чтобы он был выше по
 VI> приоритету других потоков процесса)
--
Как я понимаю, предлагается повысить приоритет своего потока (наверное с
помощью функций SetPriorityClass/SetThreadPriority, нет?). Но никто не
гарантирует, что сразу же после этой операции другой поток так же не поднимет
свой приоритет до такого же уровня.
Можно попытаться уменьшить приоритет других потоков или вообще их остановить
(SuspendThread), но непонятно, как это сделать "атомарно" так, что бы за время
таких операций другие thread'ы не создались или не изменили состояния тех, с
которыми наш thread окончил работать.



 VI> 2. Вызываем Sleep(1). В момент возврата из сна будем находится в начале
 VI> кванта времени
--
Кстати, если гарантируется, что в потоке работает только один thread, то эта
операции не нужна. А если работают несколько, то она не поможет. Windows NT не
гарантирует, что в выделенный квант времени будет выполнена даже 1 команда.
Поэтому переключение на выполнение другого thread'a может произойти в любой
момент времени, в том числе и "внутри" замены 5 байт. Более того, другой
thread может параллельно работать на другом процессоре и делать такую же
замену или вызывать "заменяемую" функцию.

 
 VI> 3. Выполняем замену пяти байт, вызываем FlushInstructionCache()
--
Здесь замена 5 байт не будет являться атомарной и поэтому проблемы могут по
прежнему возникнуть.

 VI> 4. Восстанавливаем приоритет потока


--
Наверное, самым простым способом замены небольшого участка кода (для
архитектуры x86) будет являться использование команды CMPXCHG8B - в таком
случае можно "атомарно" заменить 8 байт. Ну, а если процессор не имеет такой
команды, то тогда надо аккуратно задокументировать процесс замены участка кода
- например, когда гарантировано работает только один thread (непосредственно
сразу же после функции main()). Я думаю, что ничего страшного в этом нет - в
Windows достаточно много ситуаций, в которых запрещается или не рекомендуется
тот или иной вызов функций.

Как ни странно, есть (удивительно!) много способов видоизменить код или, что
по-моему, фактически то же самое, гарантировано получить управление при
выполнении данного участка кода. Я насчитал еще не менее 5 и, думаю, это не
предел...

 VI> С уважением, Владимир

С уважением,
Геннадий Майко.

--- ifmail v.2.15dev5
 * Origin: FidoNet Online - http://www.fido-online.com (2:5020/400)