Перехват исключений (SEH)

Создание библиотек dll

Перехват сообщений Windows

Перехват API

Примеры

Способы обработки отладочных событий

1. Читать и писать в память отлаживаемого процесса
ReadProcessMemory, WriteProcessMemory
5 параметров:

a. Дескриптор процесса

b. Адрес в памяти процесса, куда читать

c. Адрес строки в отладчике куда читать

d. Количество байтов

e. Реально прочитанное количество байт

2. Работа с контекстом (работа с регистрами отлаживаемого процесса)
GetThreadContext – получить контекст
SetThreadContext – сохранить контекст
2 параметра:

a. Дескриптор потока

b. Адрес структуры CONTEXT (хранятся значения регистров)
CONTEXT STRUCT
ContextFlags dd ?
CONTEXT_SEGMENTS
regGS dd ?
reg FS dd ?
reg ES dd ?
reg DS dd ?
CONTEXT_INTEGER
regEdi dd ?
reg Esi dd ?
reg Ebx dd ?
reg Ecx dd ?
reg Eax dd ?
CONTEXT_CONTROL // управления
regEbp dd ?
regEip dd ?
regCs dd ?
regFlag dd ?
regEsp dd ?
regSS dd ?

3. Точки остановки BREAKPOINTS
int 3 ; 3 – номер прерывания
точка остановки
int – interrupt (0CCh)
0CCh поставим во время работы отлаживаемого процесса в нужное нам место памяти.
Когда программа дойдет до этого места, она остановится, мы сможем обрабатывать отладочное событие EXCEPTION_BREAKPOINT. Предварительно нужно байт, вместо которого будет ставиться int 3 сохранить в отладчике а потом восстановить, а потом ещё вернуться на байт назад для работы программы.


 

 

Отладка wink.exe

Запуск wink.exe

При нажатии на кнопку расчет получится число 6.
6 = 3 + 2 + 1.

Нужно написать отладчик, чтобы wink.exe под отладчиком работала иначе. Она выводит ImageBase (при CREATE_PROCESS_DEBUG_EVENT), потом значение регистра EIP (EXCEPTION_BREAKPOINT, 1 раз), Key (пароль, выводится при EXCEPTION_BREAKPOINT, 2 раз) и только после этого появится тот диалог.
И на экран выводится не 6, а 3ка (также при CREATE_PROCESS_DEBUG_EVENT: 03h заменить на 02h). При закрытии должно появиться окошко, где будет написано DEBUG_EXIT.

Int 3 – ставится тоже при CREATE_PROCESS_DEBUG_EVENT (также предварительно записывается байт)

При ECXEPTION_BREAKPOINT – наращиваем счётчик брэйкпоинта

При втором брэйке, вывести ключ, восстановить программу

Когда конец работы – выводим MessageBox._

Джерри Рихтер - создание эффективных Win32 приложений

Structure Exception Handler

В языках высокого уровня это на уровне try/catch, но программа громадно раздувается. Мы рассмотрим обработку исключений на уровне Win32 (на низком уровне)

Есть область TIB (системная область), на нее указывает регистр FS, в начале области находится адрес структуры SEH, а одно из полей структуры указывает на обработчик исключений. (Косвенная адресация на обработчик исключений)

Структура SHE содержит 5 полей, но мы рассмотрим 2 из них:

1. prevLink – указывает на следующий SEH (структуру SEH)

2. currentHandler() – напрямую указывает на обработчик исключений

3. …

Структура должна находится в системном стеке, у каждой структуры свой обработчик

Обработчики работают на уровне ядра.

Наша задача – написать обработчик, который при доступе к нижнему предохранительному блоку, выдаётся сообщение

Пример:

При обращении к адресу 0, выводим MessageBox.

Нам нужно сделать новый SEH, указать на него и prevLink’ом указать на следующую структуру и создать свой обработчик


 

.data
str1 db 'Exception, access to address 0'
.code
start:
push offset SehHandler

push FS: [0] ; prevLink

mov FS:[0], ESP ;сформировали 2 действие (указатель на наш SEH)

mov eax, 0

mov [eax], eax

SehHandler PROC

invoke MessageBox, 0, addr str1, NULL, MB_ICONERROR

pop FS:[0]

add ESP, 8

mov eax, 1 ;передано управление следующему обработчику

ret

endp

 

Если мы хотим, чтобы серого окошка не было, мы можем добавить поля в SEH. В структуре SEH могут существовать 3 поля, которые позволяют после исключения не выходить из программы, а переходить на безопасное место в программе (исправление исключений)