Введение в крэкинг с нуля, используя OllyDbg - Глава 25

  • На форуме работает ручное одобрение пользователей. Это значит, что, если Ваша причина регистрации не соответствует тематике форума, а также Вы используете временную почту, Ваша учётная запись будет отклонена без возможности повторной регистрации. В дальнейшем - пожизненная блокировка обоих аккаунтов за создание мультиаккаунта.
  • Мы обновили Tor зеркало до v3!
    Для входа используйте следующий url: darkv3nw2...bzad.onion/
  • Мы вновь вернули telegram чат форуму, вступайте, общайтесь, задавайте любые вопросы как администрации, так и пользователям!
    Ссылка: https://t.me/chat_dark_time

AnGel

Администратор
Команда форума

AnGel

Администратор
Команда форума
27 Авг 2015
3,411
2,025
ИСКЛЮЧЕНИЯ

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

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

e4cb740412a71b6ec76e41103e2e352a.png

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

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

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

a2e584a0db75f29559ba87a4cf373284.png

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

f48886dbd25117fa10967f889a75bab3.png

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

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

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

024577b86132dcbbd3a2a7cebd88aad0.png

bc03b8b8244a98e4a4ba05a0e6394d06.png

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

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

f93e11d7269fb0b27014ebc2bc7db595.png

7912759f0a5ac14588bc5ba139275d1b.png

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

6639e209ac9857562effe6998d8259e2.png

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

a9bc424157336517f5e06f2dbe4d1bf9.png

45438c9515489354d98b1c55772b1521.png

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

9e5db405d4c6449d82972fdb90c59105.png

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

09c04f17d96b9c7d7b9ece6619ae8571.png

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

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

9432cdbb036c9f177dcb45089ca7b291.png

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

88505ddc5252a7ec3908284e87098bb7.png

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

965a38e375ed9fd8907030110cddf39f.png

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

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

21b2992bb53880ffee5612b6dced5d37.png

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

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

01d5acfff8595f8c624b2e9b44f51555.png

e83bccceea7e8b8b5b987f1e3653456a.png

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

c33fe7523a455f26371d11a8a7615cee.png

c69baf93c9f8b82699b009dd9755c18a.png

eccac0e0ec5e824dc1caedd908ec3ecb.png

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

0ff72afc29130b0dfe1365f7d3269dc9.png

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

e3368a076b6712d682d59ff176696491.png

1ec00fe2d8479ece47dbefb3bda80bc8.png

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

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

6bdec91db666bab3f3f1e6d2520bf6ce.png

Нажимаем F8.

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

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

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

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

378165ea1cc49b9f3c020a00cc7bed77.png

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

5c17ada3e9ae9a31335bcc059a83be9f.png

Нажимаем F8.

a275a2e7ffef5f016a16a7c278f55772.png

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

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

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

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

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

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

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

cbfd089c6aeb22cd150fbd7ba4d195d0.png

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

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

ffd8765601de7afa4d9d5011608d7790.png

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

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

ЧТО ТАКОЕ SEH

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

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

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

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

44ebdca3423dddaf6a7541a9fddf75d5.png

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

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

4c9a4010610ca46586aace3f31fdce20.png

5848a9a55b189b8f8e49f74b11d04cef.png

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

1df2d3dcc4d026c6d1d5ad6b09d5c7f4.png

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

bea167ac6b7b0f41832bd721d1752b1c.png

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

628fa904e4442b7d4fd08b4581adb70d.png

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

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

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

6009362efc9bb55a17c26807df58d6e8.png

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

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

412fd49274cbf437a08f3ee3213c3c5b.png

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

030c38cef52e1d4afd64251359703d52.png

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

db361c6381464ab233c8ab2172d46015.png

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

38bdf30409c890f7fda9aa42f9656b29.png

Идём туда.

6dc1aad0e5ac66dbd98a315c1852d453.png

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

58dc563238add0c9b3c29487aeb5ef91.png

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

aa98c443b468a6d932ebcafa8f1ff7ed.png

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

Ahora hace un PUSH con ese valor

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

660055c835a5b77ac6522a799bb526d5.png

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

80162d09b0aa14851f6c69d313a108ad.png

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

56bb774bc4f88da50ed6b9e2862f4340.png

93cdd6302632b283204a2b76745e1f2b.png

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

df5d08406cd2263eb10a1bef97dc6f60.png

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

36de6319ebc848d7efdde4a7e302ab9b.png

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

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

e1dace712f8650ff8925505b63ec1554.png

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

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

a49b496428f733eb3b1f6c8dedac5491.png

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

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

e82ce3bf25bda9713f9442930835fdd8.png

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

e7e73460fd2a3d4b39b19f8c48fbd4e9.png

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

a9e91f9f45750da769457ed4c1ce0885.png

Делаем RUN.

05517884560ea80ae32d2da1f5c50875.png

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

5e1804461ff85a3d04a4f54696cb70cd.png

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

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

62d3c3cda6a6e600b30bdfb6c811de54.png

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

06d303b316dd7b7617f7a59d1f1a00f6.png

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

a26db7abc2cbc95877fc770342ea21a8.png

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

df92b62295fa86919a5b8bfe38d72016.png

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

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

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

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

ecac853d96cbd549ccd9d322e3e59a17.png

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

e427ae97d6fc7f7830342e0365f932ca.png

И делаем RUN.

edee9a12c594d21dcbcb261ba5410313.png

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

6559d1d049991cc1be7e978264b3d7b4.png

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

87aa739a65df081cc818a549f722eb05.png

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

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

b9a187b3252979b551f4842808991703.png

1d6e5465347e6c293bd997c2d1e725a7.png

558b4a80410d76eef2d13e332e521da7.png

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

d7b95029f7cbec08816b26b7b5d65108.png

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

6938a7ff427b97ff1c9241c9ec013e43.png

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

e3923be202fc32a9c09b70f84f23ef15.png

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

6d4be566ec5e470769e1da82994e3fad.png

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

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

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

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

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

Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
 

О нас

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

    Dark-Time 2015 - 2022

    При поддержке: XenForo.Info

Быстрая навигация

Меню пользователя