Главный минус этого приема в том, что его очень легко обойти. Достаточно, например, просто подогнать курсор к команде pushf, сказать отладчику "HERE" (т. е. выполняй программу до этого места без трассировки), затем подогнать курсор к jnz и сказать "HERE" еще раз. Таким образом, защищенный фрагмент будет исполняться в обычным режиме и присутствие отладчика окажется незамеченным, поэтому, многие программисты предпочитают сохранять регистр флагов в одном месте программы, а проверять его в другом. Начинающих хакеров это сбивает с толку, но опытных так не проведешь. На конструкцию pushf/pop reg/xxx reg,100h у них уже давно выработался безусловный рефлекс, к тому же взломщику ничего не стоит заменить and eax,100h на and eax,0h и тогда программа навсегда утратит способность распознавать отладчик. Можно (и нужно), конечно, добавить проверку собственной целостности, но только навряд ли она надолго остановит хакера.
А вот слегка модифицированный вариант той же самой защиты, который распознает присутствие отладчика независимо от того исполняется ли программа в пошаговом режиме или нет. Алгоритм работы в общих чертах выглядит так: мы самостоятельно взводим флаг трассировки и выполняем следующую команду. Процессор послушно генерирует исключение, которые мы перехватываем предварительно установленным SEH-обработчиком, передающим управление нашему коду. Но при наличии отладчика, исключение "поглощается" и SEH-обработчик уже не получает управления!
; устанавливаем новый обработчик структурных исключений
xor eax,eax ; обнуляем регистр eax
push offset SEH_handler ; кладем в стек указатель на новый обработчик
push dword ptr fs:[eax] ; кладем в стек указатель на старый обработчик
mov fs:[eax],esp ; регистрируем новый SEH-обработчик
; взводим флаг трассировки
pushf ; заталкиваем в стек регистр флагов