Обнаружение OllyDbg - IsDebuggerPresent и как его обойти. Крэкинг ч.19

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


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


Приложение к статье

Обнаружение OllyDbg - IsDebuggerPresent

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

Эта часть посвящена способу обнаружения отладчика с помощью API-функции IsDebuggerPresent, которая наиболее часто используется.

Для этого используем Crackme1.exe, который идёт вместе с данной лекцией. Загрузим его в OllyDbg.

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

Помните, что у моей OllyDbg пока что установлен только COMMAND BAR, а значит и нет никакого плагина, который мог бы избежать обнаружения с помощью IsDebuggerPresent, но как вообще работает эта функция?

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

Если запустим крэкми с помощью F9, то увидим, что не только не открылось окошко крэкми, но и программа не запустилась.

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

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

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

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

Видим список используемых API-функций.

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

И смотрите, что мы нашли, хе-хе.

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

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

Нажимаем RUN и останавливаемся на вызове этой функции.

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

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

Из стека видно, что это API-функция без параметров, единственное, что она делает, это проверяет, отлаживается ли сейчас программа или нет, а если у вас есть какие-либо сомнения относительно данной функции или того, как она работает, то проконсультируйтесь со справочником по API-функциям.

Вот страница руководства, которым пользуюсь я.

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

Это разъяснение функции. Переведём его.

API-функция IsDebuggerPresent показывает, находится ли процесс, который её вызывает, в контексте отладчика, то есть отлаживается ли он.

Далее говорится, что функция экспортируется из KERNEL32.dll, у которой, как видим, нет параметров, и если программа находится под отладкой, то возвращаемое значение равно единице, а если нет, то нулю.

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

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

Доходим до RET, где смотрим регистры.

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

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

Выделенное розовым цветом – это место, где изменяется EAX. Как практически все API-функции, IsDebbuggerPresent помещает возвращаемое значение в EAX, тогда если в нём 1, то это говорит о том, что программа находится под отладкой.

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

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

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

Делаем RUN.

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

Снова останавливаемся на API-функции, поэтому снова доходим до RET и меняем EAX на ноль.

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

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

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

Снова доходим до RET, теперь можем перейти к пошаговой отладке с помощью F8.

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

Когда доходим до RET, EAX равен 1, вернёмся в программу, нажав на F8.

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

Здесь мы, прежде всего, видим, что если нет DLL uxtheme, то вызова не произойдёт. Делаем RUN и теперь происходит остановка на API-функции.

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

Там останавливаемся во второй раз, доходим до RET и возвращаемся в программу с помощью F8.

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

Оказываемся у JE, где происходит тестирование, равен ли EAX нулю или нет. Идём дальше.

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

Видим, что если EAX отличается от нуля, то перехода не происходит, также замечаем, что если переход происходит, то выполнение программы продолжается функцией GetDlgItem, которая считывает информацию из окна крэкми.

После невыполнившегося перехода находится JMP, миновать который нельзя.

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

Продолжим трассировку, чтобы узнать, куда попадём.

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

Новая API-функция – PostQuitMessage, посмотрим её описание.

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

В переводе это означает, что данная API-функция посылает сообщение для закрытия окна WM_QUIT, то есть указание на то, что выполнение скоро будет завершено.

По возвращению оттуда:

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

И если у нас будет терпение оттрассировать достаточно до того момента, когда всё закрывается, то обнаружим, что вызывается API-функция ExitProcess, которая и завершает процесс (если терпения нет, то установите на неё ExitProcess и остановитесь прямо на ней).

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

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

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

Останавливаемся там и изменим JE на JMP 4011b2 (для этого нажмите пробел).

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

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

Сохраним программу с внесёнными нами изменениями под каким-нибудь другим именем. Нажимаем правую кнопку мыши.

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

И в открывшемся окне снова нажимаем правую кнопку.

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

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

Сохраняем под именем crackme1p, так что теперь у нас исходная программа и пропатченная.

Теперь откроем пропатченную программу в OllyDbg, чтобы проверить, выполнится ли она в отладчике. Никаких BP устанавливать не будем.

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

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

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

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

А сейчас загрузим исходный файл и рассмотрим API-функцию поподробнее.

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

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

Здесь три невзрачных инструкции MOV, с помощью которых данная API-функция каким-то образом определяет, отлаживается ли программа или нет. Первое, что мне пришло в голову – это то, что если программа отлаживается, то они не может выполнить эти три строки, и в EAX попадает значение 1. Попробуем перезагрузить исходный файл крэкми и добавить в точку входа следующие строки:

MOV EAX,DWORD PTR FS:[18]
MOV EAX,DWORD PTR DS:[EAX+30]
MOVZX EAX,BYTE PTR DS:[EAX+2]


Можем их просто скопировать их по очереди.

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

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

Итак, добавили три строки.

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

Видим, что после выполнения последней из них, в EAX содержится значение 1, также, как после выполнения API-функции, из которой мы и взяли эти строки.

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

Естественно, что программа не остановилась на IsDebuggerPresent, потому что мы её не вызывали, но тем не менее, мы определили, что программа отлаживается точно с таким же успехом.

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

Когда программа запускается, система сохраняет в определённом месте в памяти, находится ли она (программа) под отладкой, и если там находится ноль, то значит, что нет. Этот байт и считывают эти три строки и соответствующая API-функция.

Как мы можем найти этот байт? Давайте взглянем на первую строку из указанных трёх, и шаг за шагом их проанализируем.

Первая строка:

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

В OllyDbg идём сюда:

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

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

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

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

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

Посмотрим в окне M секцию стека.

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

Видим, что начинается в 12d000 и заканчивается там, где начинается следующая секция (130000).

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

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

Поищем его в стеке.

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

Видим, что оно помечено как END OF SEH CHAIN (конец SEH-цепочки). Пока что это нам мало что говорит, но это связано с исключениями.

Интересно то, что следуя определённому алгоритму можно достать из него любое значение, например, которое находится после Fs:[0].

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

Это Fs:[0], если поищем в command bar’е значение fs:[1], то получим:

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

Поэтому:

Fs: [0] на моей машине здесь содержится 7ffdf000
Fs: [1] на моей машине здесь содержится 7ffdf001
…………………………………………………………………….
…………………………………………………………………….
Fs: [18] на моей машине здесь содержится 7ffdf018


То есть, это значение, которое, как мы помним, было на первой строке API-функции.

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

То есть видим содержимое 77ffdf018 (оно же FS:[18]).

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

Вот это значение, которое сохранено в TIB в FS:[18] – значение, которое отображается в регистрах, указывающее на начало TIB.

Таким образом, первая строка загружает в EAX указатель на начало TIB, конкретное значение может отличаться на разных машинах. Нажав F8, мы переместим это значение в EAX.

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

Хорошо, теперь в EAX находится указатель на TIB.

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

Теперь следующая строка.

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

К EAX прибавляется 30, на моей машине в результате получается 7ffdf000 + 30 =7ffdf030.

Это fs:[30].

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

То есть в EAX помещается содержимое 7ffdf030 или fs:[30], на моей машине это содержимое равно 7ffdc000, не спутайте это с началом TIB, эти значения различаются.

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

Это указатель на что-то другое, посмотрим на что именно через DUMP:

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

Последняя строка:

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

Сумма 2 и EAX равна:

7FFDC000 + 2= 7FFDC002


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

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

Система сохраняет 1 в этом байт, который считывается API-функцией IsDebuggerPresent. У вас адрес этого байта может отличаться, но вы сможете легко его найти, используя вышеуказанный метод. Загрузим заново крэкми в OllyDbg.

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

Вот краткое изложение того, как найти искомый байт, используемый в IsDebuggerPresent.

Ищем начало TIB в окне регистров.

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

Смотрим TIB через DUMP (он уже не будет располагаться по тому адресу, что в прошлый раз).

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

Ищем fs:[30], то есть к адресу, указывающему на TIB, прибавляем 30 и смотрим содержимое, находящееся по получившемуся адресу.

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

Его содержимое (7ffde000) также является адресом, смотрим через DUMP.

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

И прибавляем 2 – вот и искомый байт. (Многие обращают внимание, что когда программа запускается, в EBX уже находится указатель на эту область, так вот, EBX=fs:[30]).

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

Ок, это и есть весь метод целиком, который можно использовать, если не находимся в начале программы и не знаем значения, которое имел EBX при старте. Теперь поместим ноль в найденный байт.

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

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

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

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

Трассируем до RET.

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

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

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

И поэтому выполняется без проблем.

Разумеется, есть множество плагинов, которые делают то же самое, один из них – это HideDebugger 1.24.

Сначала скачиваем его, затем копируем dll в директорию с плагинами.

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

Копируем, хехе.

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

Теперь перезапускаем OllyDbg.

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

Смотрим настройки плагина.

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

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

Нажимаем SAVE.

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

Запускаем по новой крэкми . Обратите внимание, что EBX указывает на область, где находится тот самый байт.

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

Теперь EBX-FOLLOW IN DUMP.

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

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

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

Обсуждение статьи: Обнаружение OllyDbg - IsDebuggerPresent и как его обойти. Крэкинг ч.19 >>>


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



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