SoftIce для начинающих        Развлекательный портал !!!


 

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