Обработчик исключений, что такое SEH. Крэкинг ч.25

Обсудить статью на форуме


Свежая 2020 года подборка видеоуроков, инструментов крэкера, книг и статей - здесь.


ИСКЛЮЧЕНИЯ

В этой главе мы рассмотрим обработчики исключений, которые обычно являются камнем преткновения для новичков, но на самом деле это не слишком сложная тема, если немного в неё углубиться.

Исключение создаётся программой, когда процессор выполняет неправильную операцию. Мы увидим различные примеры того, как это случается в OllyDbg, для чего откроем крэкми CrueHead’а.

Взлом программ отладчиком OllyDbg

Мы находимся в точке входа и в первой строке будем писать разные инструкции ассемблера, которые приводят к возникновению исключений. Будем использовать туториал Mr Silver’а об исключениях и иллюстрировать последние конкретными примерами.

Нет доступа к памяти: возникает, когда тред пытается получить доступ к памяти не в том режиме, на который у него есть права. Данный тип исключения, например, может случиться, если поток попытается записать что-то в ячейку памяти, имея только права на её чтения.

Напишем в OllyDbg следующую строку.

Взлом программ отладчиком OllyDbg

В данном случае есть только к ячейке памяти по адресу 401057 есть только право на чтение и исполнение, но не на запись, поэтому при попытке записать что-либо в данную позицию возникает исключение. Нажмём F8.

Взлом программ отладчиком OllyDbg

У каждой секции есть начальные настройки доступа, хранящиеся в заголовоке, до того как программа не выполнит какую-нибудь API-функцию, например VirtualProtect, позволяющую изменить настройки доступа, заданные изначально, во время выполнения.

Где в OllyDbg мы можем посмотреть начальные настройки доступа для каждой секции и изменить, если нужно?

Для этого нажмём кнопку M.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Видим, что секция, начинающаяся с 400000, т.е. первая, являющаяся заголовком PE (исполняемого файла), имеет небольшой размер в 1000 байт, в котором хранятся данные о секциях, именах, размере, в общем, всю необходимую информацию о запуске файла.

Смотрим заголовок через DUMP.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Вводим 400000, то есть адрес, откуда начинается заголовка.

Взлом программ отладчиком OllyDbg

У OllyDbg есть опция для интерпретация большинства параметров заголовка. Находясь в DUMP, нажимаем на правую кнопку мыши.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Видим, что OllyDbg отобразила нам различную информацию, содержащуюся в заголовке.

Взлом программ отладчиком OllyDbg

Если начнём спускаться вниз, то первое, что мы встретим – это PE SIGNATURE, являющееся значением, которое говорит нам, где действительно расположена информация о заголовке. Видим, что оно содержит 100, так что нужно прибавить это число к 400000 и получим 400100. Спускаемся туда.

Взлом программ отладчиком OllyDbg

Как видим, никакой ошибки – именно отсюда начинается важная информация о программе.

Поясним более подробно, что означают некоторые из этих параметры.

Взлом программ отладчиком OllyDbg

То есть, значение этого указателя (1000) надо прибавить к 400000, и получим адрес точки входа программы. Если хотим изменить его, например на 2000, нажимаем на правую кнопку мыши.

Взлом программ отладчиком OllyDbg

Мы можем написать любое число, которое ходим, например, если нужно, чтобы программа начиналась с 402000, то пишем тут 2000, так как отсчёт всегда начинается с 400000, то есть с этого адреса начинается заголовок, который является первой секцией программы.

Взлом программ отладчиком OllyDbg

Затем, чтобы сохранить изменения в файле, нажимаем правую кнопку мыши – COPY TO EXECUTABLE, а в возникшем окне ещё раз правая кнопка мыши и SAVE FILE. Сейчас этого делать не будем, я просто хотел, чтобы вы знали об этой возможности.

Ок, продолжаем идти вниз по заголовку.

Взлом программ отладчиком OllyDbg

Здесь начинаются данные секций, видим, что секция начинается с позиции 1000, т.е. 401000, а её характеристиками являются CODE, EXECUTE и READ.

Если мы хотим, чтобы у этой секции было разрешение на запись, то нужно изменить значение этого поля с 60000020 на E0000020. Это число задаёт сразу права на всё, хе-хе, пробуем.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Хорошо, теперь сохраняем значения с помощью обычной процедуры.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Меняем имя на CRACKME 3, чтобы знать, что это модифицированный нами вариант.

Взлом программ отладчиком OllyDbg

Теперь откроем этот crackme 3 в OllyDbg.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Вернём обычный режим отображения DUMP’а.

Теперь попробуем ту инструкцию, которая вызывала ошибку при записи.

Взлом программ отладчиком OllyDbg

Нажимаем F8.

Видим, что исключения не возникло и значение EAX прекрасно сохранилось по адресу 401057.

Другим типом исключения является:

Деление на 0: вызывается, когда пытаемся поделить число на 0.

Например, напишем в OllyDbg:

Взлом программ отладчиком OllyDbg

Здесь происходит деление ECX на EAX, и если последний равен нулю, то будет вызвано исключение.

Взлом программ отладчиком OllyDbg

Нажимаем F8.

Взлом программ отладчиком OllyDbg

Не всегда OllyDbg предоставляет ясную информацию, в данном случае, она не сказала, что происходит деление на ноль. Перепрыгиваем через исключение.

Неверная инструкция, попытка запуска привилегированной инструкции: возникает, когда процессоры пытается выполнить инструкцию, не относящуюся к набору, поддерживаемого им, например, при встрече неизвестной операции.

Этот случай мы не сможем опробовать, так как OllyDbg не даёт нам задавать инструкции, которые не существуют, но программист может задать такую, которую процессор не будет поддерживать, и тогда выдастся соответствующая ошибка.

Также очень известным является INT 3, которое генерирует исключение, и используется отладчиком, когда устанавливаем обычный BPX, чтобы остановить программу и передать управление ею туда, где INT 3 был вызван.

Также некоторые программы вызывают INT 3 напрямую, это исключение является одним из наиболее возможных.

Есть много других исключение, и все мы рассматривать не будем. Вот простой пример.

Мы теперь знаем, что программа может генерировать исключения, но что именно при этом происходит? Рассмотрим следующую схему:

Взлом программ отладчиком OllyDbg

На этом графике, который я стащил из туториала SILVER’а, изображено, как возникает исключение при условии, что процесс находится под отладкой.

В случае, если программа находится под отладкой, контроль получает отладчик, который (как это изображено на картинке, смотрит, может ли он контролировать исключение или нет, почти всегда ответ утвердительный и тогда, если включена опция в DEBUGGING OPTIONS-EXCEPTIONS для перепрыгивания через этот тип исключений, контроль возвращается обратно программе, если не включена, то для этого нужно нажать SHIFT+F9, то есть на графике, где сказано CONTROLA LA EXCEPCION-SI отсутствует изображение, отображающее процесс принятия решения, останавливать или продолжать выполнение программы в зависимости от вышеуказанной опции. Смотрим следующую схему.

Взлом программ отладчиком OllyDbg

Здесь видим весь процесс полностью – добавлена красная стрелка. После CONTROLAR LA EXCEPCION происходит определение, нужно ли останавливать или продолжать выполнение программы в зависимости от того, включена ли соответствующая опция, если происходит остановка, то ждём нажатия SHIFT+F9.

Далее видим, что когда возвращаемся из OllyDbg, то происходит проверка, установлен ли SHE, если да, то переходим к нему, если нет, то используем SEH по умолчанию. Это может показаться сложным, но на самом деле, это не так. Объясню поподробнее.

ЧТО ТАКОЕ SEH

SEH или Structured Exception Handling – это обработчик, который служит для того, чтобы программа имела возможность восстановиться после ошибки, то есть, если не установили собственный SHE-обработчик, то при возникновении ошибки выполняется системный обработчик, который отображает нам сообщение об ошибке в приложении, программа закрывается и адью. Установив же собственный SEH-обработчик, можем перехватить ошибку, обработать её и возвратить управление программе, которая, вместо закрытия и назойливых сообщений от системы, продолжит выполняться.

Также, хотя мы и не рассматривали серьёзно треды, вот минимальное определение этого термина: это «нити» программы или части, которые могут выполняться одновременно, соответственно, у каждого треда есть собственный обработчик исключений, то есть, если тред установил его, то последний будет выполняться только в нём, а не в других.

Как устанавливается обработчик исключений

Ок, снова откроем крэкми CRUEHEAD’а и посмотрим в стек.

Взлом программ отладчиком OllyDbg

Это SEH-обработчик по умолчанию, устанавливаемый системой, и он будет срабатывать при любой ошибке до тех пор, пока не будет заменён на наш собственный, выдавая зловещее сообщение об ошибке. Посмотрим, где находятся указатели на системный SEH-обработчик.

Как можем видеть, в FS:[0] находится текущий указатель на обработчик исключений, можем здесь перейти в DUMP.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Как можно видеть, FS:[0] – это содержимое памяти по адресу, отмеченное OllyDbg, оно может быть разным на разных машинах, но в моём случае FS:[0] всегда содержит 12ffe0.

Взлом программ отладчиком OllyDbg

Как видим в стеке, 12ffe0 указывает на последний обработчик в цепочке, то есть на тот, который работает именно в данном треде, и именно по этому адресу происходит передача управления, когда возникает исключение. Системный обработчик при этом отображает нам знаменитое сообщение об ошибке в приложении.

Взлом программ отладчиком OllyDbg

И если перейдём по VIEW-SEH CHAIN:

Взлом программ отладчиком OllyDbg

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

Так как крэкми CRUEHEAD’а не устанавливает собтсвенных обработчиков исключений, используем программку под названием SMARTMOUSE, которая прилагается к этой главе.

Загрузим её в OllyDbg.

Взлом программ отладчиком OllyDbg

Здесь видно, что в начале программа собирается установить собственный обработчик исключений, о чём прямо говорится в комментарии OllyDbg.

Оттрассируем по шагам и объясним каждый из них.

Взлом программ отладчиком OllyDbg

Инструкция, с которой, как указывает OllyDbg, начинается установка обработчика исключений, это PUSH адреса, на который должна переходить программа при возникновении исключения. В данном случае этот адрес будет. Выполняем данную инструкцию.

Взлом программ отладчиком OllyDbg

Адрес сохраняется в стек.

Взлом программ отладчиком OllyDbg

Следующая строка перемещает действительное значение fs : [0] в EAX. Посмотрим, чему равен FS:[0] через DUMP.

Взлом программ отладчиком OllyDbg

Идём туда.

Взлом программ отладчиком OllyDbg

Видим, что fs:[0] равно 12ffe0. Можем посмотреть, какую информацию предоставляет по этому поводу OllyDbg.

Взлом программ отладчиком OllyDbg

Теперь выполняем эту строку.

Взлом программ отладчиком OllyDbg

Перемещаем это значение в EAX.

Ahora hace un PUSH con ese valor

Теперь делаем PUSH с этим значением.

Взлом программ отладчиком OllyDbg

SEH CHAIN означает, что это цепочка. Сохраняемое значение указывает на предыдущий обработчик, являющийся на данный момент активным.

Взлом программ отладчиком OllyDbg

Последняя строка меняет содержимое fs:[0], куда помещается содержимое ESP, указывающая туда, где находится новая структура.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

После выполнения строки:

Взлом программ отладчиком OllyDbg

Наш обработчик установлен по адресу 12ffb0, как всегда видим, что fs:[0] указывает на действующий в настоящее время обработчик.

Взлом программ отладчиком OllyDbg

OllyDbg говорит нам, что это SEH-обработчик, первое значение указывает на старый, а второй – это адрес, по которому будет передано управление, когда возникнет исключение.

То есть, вот что происходит, когда возникает исключение:

Взлом программ отладчиком OllyDbg

Система передаёт управление отладчика, который останавливает выполнение программы или нет (в зависимости от того, включена ли соответствующая данному исключению опция), а затем возвращает управление программе – сразу или ожидая нажатия SHIFT+F9, и как показывает рисунок, теперь, когда установлен SEH-обработчик, выполнение продолжается по адресу 4066d8.

Если посмотрим SEH CHAIN, то теперь увидим:

Взлом программ отладчиком OllyDbg

Видим, что здесь присутствуют как активный обработчик, установленный нами, так и системный, который в данный момент не функционирует.

Вызовем исключение в программе.

Взлом программ отладчиком OllyDbg

Изменим данную строку на:

Взлом программ отладчиком OllyDbg

Это вызовет ошибку, так как не можем писать по адресу 0. Выключим все опции в DEBUGGING OPTION-EXCEPTIONS, кроме первой.

Взлом программ отладчиком OllyDbg

Делаем RUN.

Взлом программ отладчиком OllyDbg

Показывается ошибка и выполнение программы прерывается.

Взлом программ отладчиком OllyDbg

Теперь программа должна продожить выполнение с SHE-обработчика, пытаясь восстановиться после ошибки.

Обработчик установлен по адресу 4066d8. Идём туда и ставим BP.

Взлом программ отладчиком OllyDbg

Как видим, OllyDbg всегда нам всё рассказывает, хе-хе, нажимаем SHIFT+F9, чтобы продолжить выполнение программы.

Взлом программ отладчиком OllyDbg

Как видим, останавливаемся на обработчике. Узнаем, что он делает, и может ли он оправиться от такой серьёзной ошибки как изменение кода программы.

Взлом программ отладчиком OllyDbg

Видим, что не можем продолжить выполнение и переходим на системный обработчик.

Взлом программ отладчиком OllyDbg

Это произошло, потому что ошибка очень серьёзная, которую программа преодолеть не смогла и передала управление системному обработчику, показавшему зловещее окошко с сообщением и закрывшему приложение.

Очевидно, что обработчик исключений, установленный программой, ожидает другой тип исключений, а не тот, что вызывается из-за изменения кода, но зато увидели, что происходит, если происходит неконтролируемое исключение.

Чтобы рассмотреть другой случай, когда исключение успешно обрабатывается, посмотрим крэкми SDUE, которое прилагается к данной главе.

Откроем его в OllyDbg и сообщение отладчика о том, что приложение может самомодифицироваться и т.д. и т.п., говорит нам о том, что крэкми запакован.

Взлом программ отладчиком OllyDbg

Снимем все галочки кроме первой в DEBUGGING OPTIONS-EXCEPTIONS.

Взлом программ отладчиком OllyDbg

И делаем RUN.

Взлом программ отладчиком OllyDbg

Останавливаемся на исключении.

Взлом программ отладчиком OllyDbg

Где находится обработчик:

Взлом программ отладчиком OllyDbg

На вашей машине этот адрес может отличаться, так как секция создаётся во время выполнения программы.

Устанавливаем сюда BP.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Устанавливаем сюда UN BPX.

Взлом программ отладчиком OllyDbg

Нажимаем SHIFT+F9.

Взлом программ отладчиком OllyDbg

Происходит остановка на обработчике, который, если нет никаких странных изменений, должен вернуться на строку следующую за той, что вызвала исключение, после чего выполнение программы продолжится.

Взлом программ отладчиком OllyDbg

Установим UN BP на следующую строку после той, где генерируется исключение, и нажмём RUN.

Взлом программ отладчиком OllyDbg

Видим, что ошибка была обработана и программа продолжает выполняться без каких-либо сообщений об ошибках.

Как видим, это простая процедура, и в обычном случае возвращение происходит на строку следующей за той, которая вызвала исключение, хотя адрес возврата можно изменить в самом обработчике. В этом случае можно установить BPM ON ACCESS на секцию, где возникает исключение, и когда оттрассируем обработчик строка за строкой с помощью F9 и вернёмся в программу, то сработает BPM ON ACCESS и мы точно узнаем, где находимся.

Очевидно, что если хотим остановиться в том момент, когда программа устанавливает обработчик исключений, то лучше создать HARDWARE BPX ON WRITE в FS:[0]. Во многих случаев DLL также устанавливают обработчики, затем они убираются и при возвращении в программу остаются те, которые были раньше, и вышеуказанным образом можно контролировать их установку и снятие во время выполнения программы.

Установить обработчик исключений можно и другим способом – с помощью API-функции SetUnhandledExceptionFilter, которой передаётся адрес обработчика.

Ладно, думаю, что мы рассмотрели полезную информацию, которая позволит нам продвинуться дальше в крэкинг. В дальнейшем мы рассмотрим подробные примеры по этой теме.

Файлы к статье

  [C] Рикардо Нарваха, пер. Aquila

Обсуждение статьи: Обработчик исключений, что такое SEH. Крэкинг ч.25 >>>


При перепечатке ссылка на https://exelab.ru обязательна.



Видеокурс ВЗЛОМ