Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #57, АВГУСТ 2005 г.

Борьба с отладчиком

Mario555

Спецвыпуск: Хакер, номер #057, стр. 057-084-3


77E7E5AA MOV DWORD PTR [77ED73B4],ECX

77E7E5B0 RETN 4

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

Ниже адреса 77E93114 лежит процедура, передающая управление обработчику, установленному SetUnhandledExceptionFilter. Под отладкой этот код не получает управление, так как осуществляется переход по адресу 77E9310E. Соответственно, если занопить этот переход, то управление будет передаваться обработчику, как если бы отладчика не было. Здорово!

Теперь о CheckRemoteDebuggerPresent. Ее применение я впервые увидел в Obsidium 1.2, там же был и трюк с SetUnhandledExceptionFilter.

BOOL CheckRemoteDebuggerPresent(

HANDLE hProcess,

PBOOL pbDebuggerPresent)

Эта функция, в принципе, аналогична IsDebuggerPresent, но только по возвращаемым результатам. А ее начинка не похожа на IsDebuggerPresent совсем. Она, как видно, может проверять и другой процесс на наличие отладки, и способ проверки отличается от простого просмотра байта в PEB. Впервые она появилась в Windows XP SP1, поэтому ее использование не универсально. Функцию CheckRemoteDebuggerPresent можно, как обычно, перехватывать, а и возвращаемые ею значения – подменять. Однако не остановимся на достигнутом и копнем поглубже, чтобы найти способы обхода. Смотрим код функции на скриншоте.

И опять видно использование NtQueryInformationProcess, как и в UnhandledExceptionFilter. Именно она определяет наличие отладчика, информацию о котором берет из ring0. Вызов NtQueryInformationProcess с параметром InfoClass = 7 (7 = ProcessDebugPort из структуры EPROCESS) является еще одним способом определить, отлаживают ли нас. Если устранить эту проверку с помощью перехвата данной API, антиотладочные трюки и с SetUnhandledExceptionFilter, и с CheckRemoteDebuggerPresent будут обезврежены. В чистом виде проверка через NtQueryInformationProcess есть, например, в Safedisk и SoftDefender, а косвенные (то есть с использованием двух вышеупомянутых API) есть в Obsidium и Execryptor2.

Баг в OllyDbg при работе с OutputDebugString

В Windows есть несколько функций API, предназначенных для взаимодействия с отладчиком, одна из них - OutputDebugString. Она посылает отладчику строку, которую тот в свою очередь показывает пользователю. В отсутствие отладчика OutputDebugString ничего не делает. Баг заключается в неправильной обработке посылаемой строки в OllyDbg. Если эта строка будет вида "%s%s%s%s...", то Olly упадет с ошибкой чтения по адресу 00000001h. Соответственно, сдохнет и отлаживаемая программа. Чтобы не дать уронить Olly, нужно не дать выполниться OutputDebugString с такой строкой либо пропатчить Olly, чтобы он вообще не реагировал на посылаемые строки. Мне больше нравится последнее, тем более что это нетрудно сделать. Этот антиотладочный трюк применяется в Armadillo, Execryptor2.

Проверки времени (RDTSC, GetTickCount и т.п.)

Под отладчиком программа выполняется медленнее, чем без него – на этом и основывается следующий метод антиотладки. Команду RDTSC обычно используют для определения тактовой частоты процессора и для измерения малых интервалов времени, она считает число тактов процессора с момента нажатия RESET. Замерив, сколько времени исполняется код без отладчика, можно внести его как эталон, и если время выполнения будет намного больше него, делаем вывод, что программу отлаживают. Таким же образом используют функцию GetTickCount, которая возвращает количество миллисекунд, прошедших с момента запуска Windows. Бороться с такими трюками сложно. Если GetTickCount еще можно перехватывать, то за RDTSC зацепиться трудно: приходится искать ее в коде и смотреть, где именно происходит проверка, которая может быть не единственной и далеко не единственной. Но, к счастью, использование таких трюков крайне ненадежно, так как процессоры бывают разные и скорость выполнения на них тоже бывает разная, да и многозадачность идет не на пользу таким проверкам. Поэтому для обнаружения отладчика они применяются все реже и реже. Однако более мягкие проверки, нацеленные на обнаружение остановок во время выполнения, являются довольно надежными (задан относительно большой допустимый интервал времени) и применяются часто, но об этом позже. Жесткие проверки особенно извращенно применяются в SoftDefender и еще некоторых малоизвестных пакерах, авторы которых не слишком заботятся о совместимости. SoftDefender - это глюковатый китайский протектор, который ты вряд ли когда-нибудь встретишь на скачанной шароваре. Но с точки зрения антиотладки в нем есть некоторые интересные вещи, и об одной из них сейчас расскажу.

Назад на стр. 057-084-2  Содержание  Вперед на стр. 057-084-4