Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #113, МАЙ 2008 г.

Ты – повелитель армии лоадеров!

Сергей «_A1!3N» Аляев

Хакер, номер #113, стр. 113-062-1

Универсальные приемы бывалого крэкера

«Извините, но срок работы программы истек, пожалуйста, нажмите Выход, либо зарегистрируйте программу», «Вы исчерпали максимальное количество запусков»… Бьюсь об заклад, тебе много раз приходилось видеть подобные сообщения. Сейчас я расскажу, как раз и навсегда от них избавиться, не отдавая за софт ни копейки и даже не обладая глубокими познаниями в крэкинге.

В мануалах по крэкингу технология взлома с помощью простейших лоадеров типа «FindWindow-SendMessage», как правило, упоминается только вскользь. Тем не менее, ее использование весьма эффективно. Главная отличительная особенность – необязательность глубокого знания крэкерского ремесла. Домашнюю крэк-лабораторию может организовать даже школьник. Рассмотрим это дело более подробно.

Лоадер типа «FindWindow-SendMessage»

Начнем с самого простого – nagscreen, он же НАГ. Яркий пример – Total Commander. Стоит лишь запустить программу, как мы видим раздражающее окно с тремя кнопками.

Чтобы избавиться от НАГА, нужно нажать соответствующую кнопку – этим сложным действием товарищи разработчики, видимо, пытаются проверить наш интеллект. Попытаемся смоделировать ту часть мозга, которая будет решать эту сложную задачу. Разложим задачу на действия:

  1. Запустим прогу
  2. Дождемся появления НАГА
  3. Прочтем номер нужной кнопки
  4. Нажмем нужную кнопку

Теперь предстоит провернуть все в программном режиме – переведем прогу с русского на С или ASM, само собой с применением Win32 API. Я буду использовать свой блестящий Visual Studio, ну а ты можешь любимый Delphi-Builder.

Чтобы запустить прогу, нам нужна красивая функция WinExec (использовать очень красивую функцию CreateProcess не будем, чтобы не грузить голову заумными параметрами). Вот ее прототип:

UINT WinExec(

LPCST lpCmdLine – имя exe файла, можно с параметрами

UINT uCmdShow – состояние окна после запуска программы

);

Со вторым пунктом проблем быть не должно (используем цикл или Sleep()). А вот третий пункт интересен. Для начала нужно найти строку с номером нужной кнопки – для этого нам пригодятся следующие функции:

static CWnd* PASCAL FindWindow(

LPCTSTR lpszClassName – класс окна

LPCTSTR lpszWindowName – заголовок окна

);

static CWnd* FindWindowEx(

HWND hwndParent – описатель родительского окна

HWND hwndChildAfter – описатель дочернего окна

LPCTSTR lpszClass – класс окна

LPCTSTR lpszWindow – заголовок окна

Все они возвращают описатель найденного окна. FindWindow мы будем использовать для поиска главного окна, а FindWindowEx – для поиска дочерних окон, то есть контролов (Button, Edit, List, Panel и т.д и т.п.).

Чтобы найти строку, нужно знать где искать и что искать. Программа из Visual Studio Tools – Spy++ нам в этом поможет. Запускаем Total Commander и Spy++.

Находим нужное окно в списке, в нашем случае Window 000305CB «Total commander» TNASTYNAGSCREEN, где:

000305CB – описатель окна (нас не интересует),

«Total commander» – заголовок окна,

TNASTYNAGSCREEN – класс окна.

Развернем эту иерархию и приятно удивимся, увидев, как автор Total Commander или кто-то там еще упростил нам задачу. Я говорю о строчке Window 00010630 «1» TPanel.

Для получения номера нужной кнопки достаточно прочесть заголовок этого контрола. Читать будем функцией GetWindowText.

int GetWindowText(

HWND hWnd – описатель окна

LPTSTR lpString – буфер

int nMaxCount – количество считанных символов

);

Алгоритм разбора иерархии окон и получения строки с заголовком искомой кнопки будет следующим. При помощи FindWindow получаем описатель окна с классом TNASTYNAGSCREEN; далее с помощью FindWindowEx получаем описатель окна с заголовком «TNotebook», потом с заголовком «NagPage»; следующим идет описатель окна с классом TPanel и, наконец, хэндл окна с классом TPanel (является дочерним предыдущему окну).

Ну и последний этап: так как все контролы в окне – тоже окна дочерние и принадлежат другому классу, то, соответственно, им также можно послать сообщение, например, BM_CLICK для окна класса Button (означает программно нажать нужную кнопку). Посылать сообщение будем функцией SendMessage с сообщением BM_CLICK. Перед этим найдем HANDLE нужной кнопки.

LRESULT SendMessage(

HWND hWnd – описатель окна, которому посылаем сообщение

UINT Msg – сообщение

WPARAM wParam – параметры сообщения (для каждого свои)

LPARAM lParam – параметры сообщения (для каждого свои)

);

Осталось закинуть лоадер в папку с Total’ом и создать для него ярлык. У получившегося лоадера есть небольшой недостаток – если быстро запустить его два раза, то одна копия процесса зависнет. Поэтому я поставил в начало кода строки:

hWnd = ::FindWindow("TTOTAL_CMD", NULL);

if(! hWnd)

Сделано это, чтобы лоадер запускался только в случае отсутствия главного окна Total’a (а значит, две копии Total’a лоадером не запустить). В общем, программу есть куда улучшать. Например, можно сделать так, чтобы код отрабатывался только после появления НАГА. Это можно осуществить при помощи Hook, но тогда придется писать DLL или воспользоваться перехватом API функций. Другими словами, все это усложнит лоадер и уведет от главной цели – крякнуть программу всего за 15-20 минут. Согласись, что приятно устанавливать себе свежую версию Windows-Total Commandera сразу же после появления новой версии, пока все твои друзья усилено ждут и ищут лекарство.

Не могу не упомянуть о хорошей альтернативе Spy++ – Window Scanner от InqSoft. В ней есть множество удобных фич, например, подсветка выбранного окна-контрола (позволит не ошибиться при выборе контрола для посылки сообщения). Тут же, не выходя из программы, можно послать конкретному окну конкретное сообщение. Тулзой очень удобно проверять подопытные программы на «наш клиент или не наш».

Лоадер типа «DelTrialCounter-file»

Но это еще не все, на что способны подобные лоадеры. Поразмыслив, можно предусмотреть такую вещь, как удаление триального счетчика. Рассмотрим пример, когда программа хранит счетчик в файле (тему поиска trial-счетчиков рассматривать не будем, она уже освещалась на страницах журнала). В качестве примера возьмем редактор формул MathMagic Personal 3.6, который отказывается работать после 30 запусков.

Это «математическое волшебство» создает файл MathMagic Personal 3.6.INI в директории Windows, в котором и считает количество запусков, а также создает дублирующий файл msnasec.dIl в \System32.

Долго не разбираясь, решаем просто при каждом запуске программы удалять файлы-счетчики.

Стратегия нападения такова:

  1. Удаляем счетчик (файл(ы))
  2. Запустим прогу
  3. Дождемся появления НАГА
  4. Найдем нужную кнопку
  5. Нажмем кнопку.

Пункт номер 1 заключается в удалении или переписывании определенных файлов в Windows и System директориях. Для их нахождения есть соответствующие API функции.

UINT GetSystemDirectory(

LPTSTR lpBuffer – в этот буфер будет записан путь к системному каталогу

UINT uSize – размер буфера

);

UINT GetWindowsDirectory(

LPTSTR lpBuffer – в этот буфер будет записан путь к windows каталогу

UINT uSize – размер буфера

);

А пункт 4 выполняем по шаблону Total Commandera :).

Лоадер типа «DelTrialCounter-reg»

Триальные счетчики редко хранятся в файлах. Хитрые шароварщики ныкают их в системный реестр. Однако это не особо усложнит нам лоадер и жизнь, потому что у нас в запасе есть золотые функции:

LONG RegOpenKeyEx(

HKEY hKey

LPCTSTR lpSubKey – указатель на строку с именем подключа

DWORD ulOptions – зарезервирован = 0

REGSAM samDesired – режим доступа

PHKEY phkResult – хэндл открытого ключа

);

Функция открывает нужный ключ в реестре. Так, hKey – одно из следующих значений: HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS.

LONG RegDeleteKey(

HKEY hKey – то же, что в функции RegOpenKeyEx

LPCTSTR lpSubKey – то же, что в функции RegOpenKeyEx

);

Функция удаляет соответствующий ключ.

Стоит отметить, что функция RegDeleteKey довольно неудобна, так как не умеет удалять рекурсивно. Поэтому имеет смысл обратить внимание на функцию SHDeleteKey, у которой те же параметры.

Всем будущим повелителям лоадеров скажу, что удалять и изменять ключи (значения) из реестра на своем рабочем компе нужно крайне осторожно. Иначе можно остаться не только без лоадеров, но и без Windows :).

Проверять работу лоадера будем с помощью тулзы Digalo 2000 Russian, являющейся движком для озвучивания текстовых файлов на русском языке. Дело в том, что Digalo спроектирован как trial-проект. Этим мы сейчас и воспользуемся.

После установки Digalo в системной директории Windows волшебным образом появляется файл DigaloRegister.exe, который Digalo загружает при каждом запуске. Этот файл отвечает за регистрацию программы и управление триальным счетчиком. Одновременно он является лучшим кандидатом на замену нашим лоадером, который будет работать по следующим инструкциям:

  1. Проверяем, есть ли искомый ключ в реестре
  2. Если есть – удаляем счетчик (ключ в реестре)

Именно там, в реестре, Digalo хранит свои тайны. Собственно, перечисленных пунктов достаточно. Diglio 2000 сам будет запускать наш лодер, сам будет удалять свои счетчики (не без нашей помощи) – в общем, будет делать все, чтобы программа продолжала работать.

Лоадер типа «SetLocalTime»

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

BOOL SetLocalTime(

const SYSTEMTIME* lpSystemTime

);

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

Примером будет замечательная программа декомпилятор для .NET сборок – Reflector, которая является Freeware, но, тем не менее, через пару месяцев начинает кидать фразы «is out of date» или «do you want to update automatically?». Клиент наш, будем лечить. Лечение будет заключаться в следующих процедурах, которые мы воплотим в лоадере:

  1. Запомним текущую дату
  2. Установим нужное для Reflector’а время
  3. Сделаем паузу в пару секунд (чтоб Reflector успел запросить фальшивую дату)
  4. Запускаем прогу
  5. Возвращаем правильное время, предварительно откорректировав его с учетом паузы.

В качестве фальшивой даты сойдет дата создания файла Reflector.exe.

Лоадер типа «Combo»

Ну и наконец, рассмотрим этакий три в одном вариант – лоадер, который совмещает в себе несколько лоадеров. Его мы будем писать для продвинутой утилиты создания скриншотов и их редактирования – HyperSnap 6.

После небольшого обследования выяснилось, что защита сего творения ныкает счетчик в реестр. Если быть более точным, то счетчиков несколько и нычек тоже. Также мы имеем окно типа НАГ, паразитирующее на наших нервах. Но это еще не все: утилита периодически создает файл с trial-меткой во временной директории Windows, поэтому заучим еще одну удобную функцию:

DWORD GetTempPath(

DWORD nBufferLength – размер буфера обычно MAX_PATH

LPTSTR lpBuffer – буфер, в котором запишется путь

);

Функция дает нам путь к временной директории Windows. Защита HyperSnap по полной мусорит на нашем компьютере – придется за ней убирать. Дабы не портить собственные нервы, поручим это лоадеру, который будет смесью лоадера первого, второго и третьего типов. Составим план нападения:

  1. Удаляем ключи в реестре
  2. Удаляем файл-метку
  3. Запускаем программу
  4. Дожидаемся НАГА
  5. Находим нужную кнопку
  6. Активируем кнопку
  7. Нажимаем на кнопку

На скриншотах показаны места хранения trial-меток (на твоей машине они могут оказаться другими). Конечно, они страшно зашифрованы-закриптованы-засекречены. Такая таинственность нам ни к чему... поэтому мы просто их удалим :).

В сценарии нам незнаком только пункт 5. Его реализация проста, ведь, чтобы активировать кнопку, нужно послать ей сообщение WM_ACTIVATE с помощью уже известной функции SendMessage. Ну вот, только что мы заставили работать программу, защищенную серьезным протектором Armadilo, без SoftICE, без OllyDbg, без IDA – практически голыми руками.

Заключение

Подобными дырами в защите страдают даже серьезные и известные программы, например, очень давно на одном знакомом мне компьютере лоадер успешно загружал 3D MAX, прекрасно справлялся с Nero 6.xx, пока доблестные немцы не прикрыли лавочку в 7x версиях.

Статья не претендует на роль «Библии лоадеров», она лишь знакомит с основами лоадеростроения, показывает, откуда начать. Чтобы продолжить, нужны манускрипты Рихтера, Фень Юань’я, ну и, конечно, Криса Касперского. Их песни помогут «улучшить и углубить» код.

MSDN, cracklab.ru, wasm.ru не упоминаю. Это само собой разумеющиеся ресурсы.

В статье рассмотрены далеко не все способы борьбы с shareware-подобными лоадерами, а лишь самые простые и распространенные. На самом деле их столько, сколько есть способов хранить trial-счетчики.

Применение лоадеров не ограничивается сугубо деструктивными моментами – их можно применять и в мирных целях. К примеру, перед запуском какой-либо программы – для подготовки данных (отсортировать, отобрать нужные, отредактировать). Или, скажем, тебе приходится работать одновременно с несколькими программами. Можно написать лоадер, который будет их запускать, меняя позицию окон и их размер так, как тебе удобно. Кстати, можно создать этакий «суперлоадер», который будет управлять всеми лоадерами на твоей машине, так сказать, менеджер лоадеров. В общем, есть о чем подумать и где развернуться.

Полные листинги лоадеров с комментариями, конечно же, прилагаются к статье. Код лоадеров максимально упрощен, понять его несложно, ибо написаны они на С и Assembler (лоадеры модно писать на ASM’е, ну а мы с тобой, безусловно, модные перцы). Последний лоадер специально написан на VB.NET, чтобы показать, что грозой шароварщиков может стать даже школьница-старшеклассница со знанием такого мирного языка.

DVD

На диске ищи все упомянутые в статье программы для крякерского мастерства.

DANGER

Внимание! Информация представлена исключительно с целью ознакомления! Ни автор, ни редакция за твои действия ответственности не несет!

VIDEO

На DVD ищи видеоурок, в котором показаны основные аспекты взлома триальных программ.

Содержание