Тебе никогда не хотелось
иметь у себя программу, с помощью которой можно
ломать игрушки, shareware и trial программы и
вообще все, что запускается на компьютере? Я
думаю, что хотелось. А такая программа
существует! И уже достаточно давно. Это SoftICE
от NuMega Software. Просто считается, что ее
использование это удел избранных программистов,
разбирающихся в архитектуре процессора,
устройстве железа, в ассемблере и принципах
действия операционных систем. Но на самом деле и
минимальных знаний достаточно для работы с этой
программой. Сначала введу тебя в курс дела.
SoftICE является самым мощным отладчиком на
сегодняшний день (т.е. прогой, которая может
разобрать по кирпичику любую другую прогу и
каждый этот кирпичик изменить как захочется). А
это значит, что с его помощью можно исследовать
все: от ядра Windows до программ на С++.
Создавался он для отладки 32-битных приложений,
драйверов под Win NT и Win 95/98 и других
программ под Win и Dos (так по крайней мере
говорят его разработчики ;). Но люди со всего
мира нашли ему дополнительное применение :))
Ведь что собой представляет какая-нибудь
Trial-программа? Не что иное, как 32-битное WIN
приложение. А ее отладка? Правильно - устранение
защиты: или проверки времени, или проверки
наличия Key-файла, или еще чего-нибудь.
В связи с тем, что многие программы уже были
взломаны с помощью SI, производители ПО стали
вшивать в свои творения части кода, проверяющие
наличие SI в системе и, в случае его
обнаружения, не дающие программе вообще работать
(они думали, что это поможет, - вот наивные!).
Поэтому тебе могут понадобиться несколько
программ, скрывающих этот отладчик от чужих
глаз. Я тебе советую посетить сайт www.dore.ru,
а точнее его отдел www.dore.ru/files/debuggers,
где представлено много полезных прог, а именно
сам SI под WIN 95/98 и под WIN NT, примочки,
мешающие другим прогам определить наличие SI в
системе, дополнительные плагины к нему, делающие
работу с ним приятнее и удобнее. Если же тебе
нужен SOFTICE для Win ME, Win 2000 или Win XP,
то перепиши соответствующий апдейт с сайта
производителя: www.numega.com/drivercentral/icecentral.asp.
Под каждым апдейтом написано, как его
устанавливать. Итак, если у тебя уже есть
проинсталлированный SoftICE, можешь пропустить
следующий раздел, если нет, то прими его к
сведению.
Установка
В установке нет ничего сложного, просто после
нее НАДО ВНЕСТИ ИЗМЕНЕНИЯ в файл winice.dat (он
должен находиться в каталоге, куда ты установил
SI), а именно раскомментировать в нем несколько
строк:
; ***** Examples of export symbols that can be
included for Windows 95 *****
;Change the path to the appropriate drive and
directory
EXP=c:\windows\system\kernel32.dll - эти;
EXP=c:\windows\system\user32.dll - строки надо;
EXP=c:\windows\system\gdi32.dll -
раскомментировать;
Это нужно для того, чтобы видеть имена Win API
функций (стандартные функции, используемые
программами при работе под Win). А именно на них
мы и будем ловить программы, но об этом позже.
Что реально может делать SoftICE и как им
управлять?
Вообще SoftIce состоит из нескольких окон:
регистров, данных, кода и команд. В окне кода ты
видишь текст программы на ассемблере, а в окно
команд вводишь команды управления SI.
Перемещаться между окнами удобно с помощью
мышки, но можно и без нее, хотя это сложновато
для начала.
Основные команды (очень важный момент)
BPX адрес/имя функции - установить в указанный
адрес или на вызов функции точку останова (еще
ее называют брэйк опинтом).
BPM адрес - установить точку останова на адрес
памяти.
BL - вывести список всех установленных точек
останова (каждая имеет свой номер).
BD номер точки останова - сделать точку с
соответствующим номером не активной.
BE номер точки останова - команда, обратная
предыдущей.
BC номер точки останова - удалить точку останова.
Фактически, другие команды нам с тобой не
понадобятся. Итак, с помощью SI можно заморозить
все программы в любой момент (например, будет
вызвана стандартная функция или выполнена
команда по определенному адресу). Когда ты
взламываешь прогу, тебя можно сравнить с
хирургом, ковыряющимся во внутренностях человека,
твой компьютер - с операционным столом, а SI -
со скальпелем, ножницами и наркозом.
Если ты хочешь сломать какую-то программу, то
твоя основная задача состоит в том, чтобы узнать,
в какой момент нужно вызвать SI (если продолжить
аналогию, то в каком месте резать :), и
поковыряться в программе-пациентке. Поэтому нам
с тобой потребуется установить ловушки, чтобы
поймать в них программу, когда она либо
сравнивает твой серийный номер с правильным,
либо смотрит, какое сегодня число (чтоб сказать:
"Ага! Срок моего действия истек. Зарегистрируйся,
а то я обижусь и не буду работать!").
Ловушки. И собственно сам взлом
Итак, нам надо выбрать момент, когда перехватить
управление у программы. Проще всего ломаются
проги, использующие Win API функции. (Это
стандартные функции, облегчающие
программирование под WIN. Например, если тебе
нужно создать окно на рабочем столе, то ты
просто вызываешь какую-то функцию с параметрами,
а не пишешь код, создающий окно с нуля.) То есть
тебе нужно будет определить, на вызов какой из
этих функций будет реагировать SI. Алгоритм
твоих действий должен быть следующим:
1. Решить, на что ты будешь ловить свою
программу. На какую API функцию.
2. Установить на ее вызов точку останова (bpx
имя функции).
3. Запустить свою прогу и спровоцировать вызов
этой функции.
4. Нажав F11, перейти к тому месту в программе
(на тот адрес), откуда она вызывалась.
5. Установить точку останова на выполнение
команд строки с этим адресом.
6. Снова спровоцировать вызов этой функции.
7. Просмотрев регистры, узнать необходимые тебе
данные (к примеру, серийный номер) или адрес той
строки, в которой обрабатываются результаты
вызова функции (это могут быть какие-либо
команды ассемблера: cmp или jump).
8. Запустив HIEW или что-то похожее, внести
необходимые изменения (cmp можно заменить пустой
командой nop, а какую-нибудь разновидность
команды условного перехода - на безусловный jmp
и тот же адрес). Именно из-за последних
нескольких пунктов считается, что знание
ассемблера является очень желательным при работе
с SI.
Самыми часто используемыми Win API функциями
являются:
MessageBoxIndirect - работа с окном сообщений.
Используется в 16-битных приложениях.
MessageBox - работа с окном сообщений.
Используется в 16-битных приложениях.
MessageBoxA - то же самое, но 32-битное
приложение.
MessageBoxIndirectA - то же самое, что и
MessageBoxIndirect, но 32-битное приложение.
GetWindowText - обычная строка ввода типа
Windows Edit. Используется в 16-битных
приложениях.
GetWindowTextA - то же самое, но 32-битное
приложение. Строки используются однобайтовые.
GetDlgItemText - примерно то же, что и
предыдущая функция, отличия в деталях.
Используется в 16-битных приложениях.
GetDlgItemTextA - то же самое, но 32-битное
приложение. Строки используются однобайтовые.
Следует заметить, что GetWindowTextA и
MessageBoxA очень часто используются при
проверке серийного номера. Перед взломом
рекомендую посмотреть свойства ломаемой
программы и выяснить ее разрядность (щелкни на
ее ярлыке правой кнопкой мыши, появится окно
Свойств, там в левом верхнем углу обычно
написано "16" или "32 бит", это и есть
разрядность приложения).
Практика
Вроде теорию я тебе всю изложил. Теперь
практика: классический пример. Возможно, пример
немного трудноват, но даже если ты запомнишь
хотя бы малую часть, то сможешь почувствовать
себя настоящим хирургом-маньяком, ищущим себе
все новые и новые жертвы. Итак прога-пациент
называется TaskLock. Будем ловить на
GetWindowTextA (команда ":bpx getwindowtexta").
Ты можешь проверить, установилась ли точка
останова командой ":bl". В результате увидишь
что-нибудь типа: "00) BPX USER32!GetWindowTextA
C=01". Далее жми F5. Продолжим. Попробуй ввести
какое-нибудь значение в окне регистрации и нажми
OK. Ты получишь дурацкое сообщение о том, что
код был неправильным. Значит, это была не
функция GetWindowTextA. Попробуем
GetDlgItemTextA. Удали старый брейкпоинт ":bc 0"
(0 - это номер брейкпоинта в списке
брейкпоинтов) и установи новый ":bpx
getdlgitemtexta". Вводи номер заново. Теперь ты
в SoftICE, в самом начале функции
GetDlgItemTextA. Чтобы попасть туда, откуда она
была вызвана, нажми F11. Теперь ты внутри модуля
SGLSET.EXE. Сейчас ты уже можешь запретить
реакцию на вызов функции ":bd 0".
Первая строка в окне кода выглядит так: "CALL
[USER32!GetDlgItemTextA]"
Чтобы посмотреть строчки над ней, нажимай
Ctrl+Up ("стрелка вверх") до тех пор, пока не
увидишь нижеприведенный кусок кода. Если ты
ничего не понимаешь в Ассемблере, я добавил
комментарии, которые могут помочь.
RET ; Конец функции
PUSH EBP ; Начало другой функции
MOV EBP, ESP ; ...
SUB ESP, 0000009C ; ...
PUSH ESI ; ...
> LEA EAX, [EBP-34] ; EAX = EBP-34
PUSH EDI ; ...
MOVE ESI, ECX ; ...
PUSH 32 ; Макс. длина строки
> PUSH EAX ; Адрес текстового буфера
PUSH 000003F4 ; Идентификатор управления
PUSH DWORD PTR [ESI+1C] ; Идентификатор окна
диалога
CALL [USER32!GetDlgItemTextA] ; Получить текст
Команды PUSH означают сохранение значений для
последующего использования. Я пометил важные
строчки символом '>'. Глядя на этот код, мы
видим, что адрес текстового буфера хранился в
регистре EAX и что EAX был EBP-34h. Поэтому
стоит взглянуть на EBP-34h ":d ebp-34". Ты
должен увидеть текст, который ввел в диалоговом
окне. Теперь ты должен найти место, где твой
номер сравнивается с реальным серийным номером.
Поэтому мы пошагово трассируем программу при
помощи F10 до тех пор, пока не встретим
что-нибудь о EBP-34. Не пройдет и нескольких
секунд, как ты наткнешься на следующий код:
> LEA EAX, [EBP+FFFFFF64] ; EAX = EBP-9C
LEA ECX, [EBP-34] ; ECX = EBP-34
PUSH EAX ; Сохраняет EAX
PUSH ECX ; Сохраняет ECX
> CALL 00403DD0 ; Вызывает функцию
ADD ESP, 08 ; Удаляет сохраненную информацию
TEST EAX, EAX ; Проверяет значение функции
JNZ 00402BC0 ; Прыгает, если не "ноль"
Мне кажется, что это выглядит как вызов функции
сравнения двух строк. Эта функция работает так:
на входе - две строки, на выходе - 0, если они
равны, и любое другое значение, если не равны. А
зачем программе сравнивать какую-то строчку с
той, что ты ввел в окне диалога? Да затем, чтобы
проверить ее правильность. Значит этот номер
скрывался по адресу [EBP+FFFFFF64]. SoftICE не
совсем корректно работает с отрицательными
числами, и поэтому настоящий адрес следует
посчитать: 100000000 - FFFFFF64 = 9C.
Ты можешь сделать это вычисление прямо в
SoftICE: "? 0-FFFFFF64". Число 100000000 слишком
велико для SoftICE, а вычитание из 0 дает тот же
самый результат. Наконец пришло время взглянуть,
что же скрывается по адресу EBP-9C (команда ":d
ebp-9c"). В окне данных SoftICE ты увидишь
длинную строчку цифр - это серийный номер! Но в
программе есть два типа регистрации,
следовательно, и два разных серийных номера.
Поэтому после того, как ты записал на бумажечку
первый серийный номер, продолжай трассировать
программу при помощи F10. Мы дошли до следующего
куска кода:
> LEA EAX, [EBP-68] ; EAX = EBP-68
LEA ECX, [EBP-34] ; ECX = EBP-34
PUSH EAX ; Сохраняет EAX
PUSH ECX ; Сохраняет ECX
> CALL 00403DD0 ; Снова вызывает функцию
ADD ESP, 08 ; Удаляет сохраненную информацию
TEST EAX, EAX ; Проверяет значение функции
JNZ 00402BFF ; Прыгает, если не "ноль"
И что ты видишь по адресу EBP-68? Второй
серийный номер! Вот и все...
|
|