Win32 EXCEPTION_INT_OVERFLOW vs EXCEPTION_INT_DIVIDE_BY_ZERO
У меня есть вопрос об исключениях EXCEPTION_INT_OVERFLOW и EXCEPTION_INT_DIVIDE_BY_ZERO.
Windows будет ловить ошибки #DE, сгенерированные инструкцией IDIV, и закончит генерировать и исключение SEH с одним из этих двух кодов.
У меня есть вопрос, как он отличается от двух условий? Информация о idiv в руководстве Intel указывает, что он будет генерировать #DE как в "делении на ноль", так и "в случае сбоя".
Я быстро просмотрел раздел о ошибке #DE в томе 3 руководства Intel, и лучшее, что я смог собрать, это то, что ОС должна декодировать инструкцию DIV, загружать аргумент divisor и затем сравнивать его к нулю.
Это кажется мне немного сумасшедшим. Почему разработчики чипов не используют какой-либо флаг, чтобы различать две причины ошибки? Я чувствую, что мне что-то не хватает.
Кто-нибудь знает наверняка, как ОС отличает две разные причины отказа?
Ответы
Ответ 1
Ваши предположения кажутся правильными. Единственной информацией, доступной в #DE, является CS и EIP, которая дает инструкцию. Поскольку два кода состояния различны, ОС должна декодировать инструкцию, чтобы определить, какой из них.
Я бы также предположил, что разработчикам чипов действительно не нужны два отдельных прерывания для этого случая, так как все, что делится на ноль, бесконечно, что слишком велико, чтобы вписаться в ваш регистр назначения.
Что касается "уверенности" в том, как он отличается, всем тем, кто знает, вероятно, не разрешают его раскрывать, либо чтобы люди не эксплуатировали его (не совсем уверен, как, но прыгать в режим ядра - это хорошее место для начните искать эксплойт) или сделайте предположения на основе детализации реализации, которая может измениться без уведомления.
Изменить: После игры с kd я могу хотя бы сказать, что в конкретной версии Windows XP (32-разрядная версия) у меня был доступ к (и процессору, на котором он работал) nt!Ki386CheckDivideByZeroTrap
обработчик прерываний должен декодировать значение ModRM команды, чтобы определить, следует ли возвращать STATUS_INTEGER_DIVIDE_BY_ZERO
или STATUS_INTEGER_OVERFLOW
.
(Очевидно, что это оригинальное исследование, нигде не гарантируется ничем, а также происходит с выводами, которые могут быть сделаны на основе руководств Intel.)
Ответ 2
Ответ Zooba суммирует Windows, анализирует инструкцию, чтобы узнать, что делать.
Но вы не можете полагаться на то, что программа правильно выбирает код.
Я наблюдал следующее на 64-битной Windows 7 с 64-разрядными инструкциями DIV:
- Если операнд (делитель) является операндом памяти, он всегда поднимает EXCEPTION_INT_DIVIDE_BY_ZERO, независимо от значения аргумента.
- Если операнд является регистром и нижнее dword равно нулю, он вызывает EXCEPTION_INT_DIVIDE_BY_ZERO, независимо от того, верхняя половина не равна нулю.
Пришел мне день, чтобы это выяснить... Надеюсь, это поможет.