Тебе никогда не хотелось иметь у себя программу, с помощью которой можно ломать игрушки, 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? Второй серийный номер! Вот и все..
|