Structured Exception Handler
SEH - это очень классная фича, которая есть во всех средах окружения Win32. Очень легко понять, что она делает: если происходит (general protection fault (сокращенно GPF), контроль автоматически передается текущему SEH-обработчику. Вы видите, насколько это может быть полезным? Если что-то пойдет не так, это позволит вашему вирусу оставаться незамеченным :). Указатель на SEH-обработчик находится в FS:[0000]. Поэтому вы можете легко поместить туда ваш собственный SEH-обработчик (но не забудьте сохранить старый!). Если произойдет ошибка, контроль будет передан вашему SEH-обработчику, но стек накроется. К счастью, Micro$oft помещает стек в том виде, в каком он был до установки нашего SEH-обработчика, в ESP+08 :). Поэтому нам надо будет просто восстановить его и поместить старый SEH-обработчик на его старое место :). Давайте посмотрим небольшой пример использования SEH:
;---[ CUT HERE ]-------------------------------------------------------------
.386p .model flat ; 32 бита рулят
extrn MessageBoxA:PROC ; Задаем API extrn ExitProcess:PROC
.data
szTitle db "Structured Exception Handler [SEH]",0 szMessage db "Intercepted General Protection Fault!",0
.code
start: push offset exception_handler ; Push'им смещение нашего ; обработчика push dword ptr fs:[0000h] ; mov dword ptr fs:[0000h],esp
errorhandler: mov esp,[esp+8] ; Помещаем смещ. ориг. SEH ; Ошибка дает нам старый ESP ; в [ESP+8]
pop dword ptr fs:[0000h] ; Восст. старый SEH-обработчик
push 1010h ; Параметры для MessageBoxA push offset szTitle push offset szMessage push 00h call MessageBoxA ; Показываем сообщене :]
push 00h call ExitProcess ; Выходим из приложения
setupSEH: xor eax,eax ; Генерируется исключение div eax
end start ;---[ CUT HERE ]-------------------------------------------------------------
Как было показано в главе "Антиотладка под Win32", у SEH есть еще полезные применения :). Он одурачивает большинство отладчиков уровня приложения. Для облечения работы по установке нового SEH-обработчика есть следующие макросы, которые делают это за вас (hi Jacky!):
; Put SEH - Sets a new SEH handler
; Put SEH - Устанавливаем новый SEH-обработчик
pseh macro what2do local @@over_seh_handler call @@over_seh_handler mov esp,[esp+08h] what2do @@over_seh_handler: xor edx,edx push dword ptr fs:[edx] mov dword ptr fs:[edx],esp endm
; Restore SEH - Восстанавливает старый SEH-обработчик
rseh macro xor edx,edx pop dword ptr fs:[edx] pop edx endm
Использовать эти макросы очень просто. Например:
pseh >jmp SEH_handler&rt; div edx push 00h call ExitProcess SEH_handler: rseh [...]
Код, приведенный выше, будет выполняться после макроса 'rseh' вместо прерывания процесса. Это понятно? :)