Защита от NMI
(С) Пичугин И.А.,
г.Норильск, 1995.
Поводом для письма послужили многочисленные заметки о NMI-кнопках и использовании для взлома режима немаскируемого прерава-ния (NMI). Хочется еще раз повторить старинную китайскую мудрость: "Бесплатных пирожных не бывает". Кнопка NMI надолго заставила забросить все дела, но, в конце концов оказалось/ что все подобные кнопки, использующие немаскируемое прерывание, в безобидности не уступают только режи^ му IM 1. В чем, собственно, дело? Конечно, дело в стеке. Не углубляясь в детали, поясню, что как ни переставляй стек, NMI автоматически заносит в него адрес возврата. Предлагаю простейший вариант, как обнаружить факт нажатия "чудо-кнопок", а потом расскажу вкратце, как это лучше всего использовать:
DI |
|
|
|
XOR |
A |
— |
|
PUSH |
AF |
|
Заносим |
PUSH |
AF |
|
под стек |
POP |
AF |
|
"ноль". |
POP |
AF |
_ |
|
CALL |
PROG |
|
DEC |
SP |
— |
|
DEC |
SP |
|
|
DEC |
SP |
|
Проверяем... |
DEC |
SP |
|
|
POP |
AF |
|
|
OR |
A |
— |
|
RET |
NZ |
|
- что-то было! |
POP |
AF |
|
|
EI |
|
|
|
RET |
|
|
- Все нормально. |
Что это |
такое? Все очень прос- |
то. CALL PROG - вызов подпрограммы, во время которой наиболее вероятно нажатие NMI-кнопки. Это может быть опрос клавиатуры как порта #FE, процедура записи из ПЗУ с адреса 1222, любая подпрограмма, не использующая стек. Такое вот ограничение (надеюсь, пока) . Почему именно такие подпрограммы? Потому, что они достаточно длительные, чтобы во время их работы нажать какую-нибудь кнопку.
Идеи дальше. В самом начале в два байта под стеком заносим ноль (важно) и флаговый регистр (не важно). Если во время работы подпрограммы PROG нажата NMI-кнопка, или пришло прерывание, эти два байта неизбежно будут уничтожены, что потом в данном случае и делается.
О практической стороне. Что хранить под стеком - дело вкуса и фантазии, но, на мой взгляд, лучше всего эти два байта использовать как "ключ" для особо важной части программы, которая раскодируется только на время выполнения, после чего закодируется новым ключом, а результат, то есть ключ - помещает в то же место -под стек. Я использовал эти два байта как ячейки статического RND-генератора (см. ZX-PEBI0-93, N7-8). Результат - превосходный. Программа абсолютно нечитаемая. Подобрать уничтоженный своими руками ключ не удается.
Надеюсь, что из вышесказанного кое-что понятно. К тем, кому понятно, хочу обратиться с просьбой не забрасывать и продолжить это, на мой взгляд, интересное дело. Это дело чистой защиты будет интересно даже тем, кого защита не интересует вовсе - имею в виду "портных", любящих шить-кроить ПЗУ, как заблагорассудится.
И если позволите, небольшой прогноз по поводу "новейших разработок" . Следующим шагом в этом направлении будет "перекроенное" ПЗУ с остановкой программы по RESET, подобно TURBO-90, но, возможно, более продуманно.
И, в заключение, для тех, кого интересуют подробности по этому и многим другим режимам работы Z80, рекомендую книгу "Центральный процессор Z80CPU", (С) УКИК "ЦЕНТР", 1990. В книге детально рассмотрены все режимы работы
Z80, команды и сигналы.
* * *