Крякми. Или тут (привет из 2к17 если ссылка затерлась)
Инструменты: IDA, HxD, CFF Explorer, DbgView, PEChecksum, KmdManager
Последние три инструмента довольно специфичны, многие крекеры уже поняли в чем вся соль крякми.
После скачивания файла оказалось, что он не имеет расширения. В мою голову начали лезть пакостные мысли про то, что это очередная ctf чушь а-ля найди как меня использовать. Хекс листинг вернул меня в состояние атараксии:

Заветные сигнатуры Марка Збиковски оказались на месте, продолжаем анализ:

Вот это поворот — перед нами драйвер. Смело переименовываем крякми в
crackme.sys. На сей раз в голову пришел вполне обоснованный вопрос: а где лоадер? Где гуй(graphical user interface, не подумайте ничего плохого)? Их нет. Буквально. Считаю это второй по значимости (хе-хе, до первой доберемся еще) нелогичностью крякми: так не бывает. Продолжаем анализ.Вот так выглядит в драйвере ImageBase:

А вот так и настоящий DriverEntry:

Здесь стоит запомнить имя девайса и обратить внимание на то, что наш драйвер любезно обрабатывает юзермодный
DeviceIoControl. Вот так обработчик выглядит до ручной корректировки:

А вот так после сопоставления с асм листингом:

Что здесь происходит? Функция получает на вход некий буфер (я кст так и не разобрался, как его передать средством
DeviceIoControl, пишите в комментарии) и некий контрольный код. Буфер, в зависимости от ControlCode, копируется в поле мейла или серийника (классная эмуляция гуя, че сказать). После заполнения этих полей мы в третий раз должны послать ControlCode и в результате запустится некая функция Validate, на основании которой выведется то или иное сообщение.Бывалый крякер пропатчил бы это дело и запустил в релиз, да только нам необходимо найти серийник к нашему мейлу. Готовимся к самому худшему и переходим к заветной функции
Validate:
Асм листинг ее самого интимного момента:

После валидации полученных параметров она высчитывает хеш от некой строки-константы, хеш от входного
buf1 (нашего мейла, это очевидно) и общий хеш от этих двух строк.Как выглядит функция
func1? Страшно и ужасно Стоит вспомнить, что в
func1 мы не передаем ничего, что было бы связано с buf2 (очевидно, это наш серийник). А что делает крякер, когда видит некую хеш функцию от мейла, в которую не передается ничего связанного с серийником, а прямо после этого прелестное сочетание:xor eax, eax repe cmpsb setz al ret
Конечно! Он
- Нам необходимо правильно инициализировать вызов функции
Validateчерез серию обращений к драйверу (ну или ручками вызвать + пропатчить память) - Обычный отладчик архетипа «Оля» для ring0 не подходит — необходимо использовать инструменты помощнее
Как бы я ни старался, но мой VirtualBox с накатанной сверху xp sp3 отказался принимать Syser/SoftICE/WinDbg. Появилась идея: почему бы не заставить драйвер любезно сообщать нам серийник? Как это можно сделать?
Для начала патчим проверки на валидность входящих данных внутри
Validate:
Просто затираем их nop`ами.
Затем необходимо вручную заполнить буфер с мылом (он выделяется динамически), делаем это, скажем, в самом начале функции
Validate. Было так:
Стало так:

Те был выпилен динамический подсчет длины мейла и все, что связано с
buf2. Теперь пропатчим самый конец функции и вместо исполнения
repe cmpsb впихнем вызов DbgPrint:
После патчинга необходимо пересчитать поле CheckSum драйвера — для этого используем утилиту PEChecksum. Затем загружаем драйвер с помощью KmdManager (для загрузки x32 драйвера вы обязаны иметь x32 систему, желательно, xp), открываем DebugView. Далее осталось написать небольшую программу для вызова драйвера:
char tmp[0x100]; HANDLE handle = CreateFile(L"\\\\.\\crackme", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); DeviceIoControl(handle, 0x222408, 0, 0, &tmp, 0x100, &tmp, 0); CloseHandle(handle);
Компилируем, запускаем:

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

