
Исследование защиты программы Expresso

Скриншот программы Expresso
Программа Expresso предназначена для создания и отладки регулярных выражений. Отличный инструмент как для новичков, так и для профессионалов. Автор поставил себе целью создать самый лучший инструмент для работы с регулярками, и, похоже, ему это почти удалось. По истечении триального срока отключается часть функционала, а программа начинает показывать сообщение о необходимости регистрации. К чести автора, регистрация абсолютно бесплатная, так что вы запросто можете получить регистрационный номер официально. Ну а если хотите немного подтянуть свои навыки в исследовании сборок .NET, то предлагаю вам эту статью.
Забираем с офсайта дистрибутив, устанавливаем, смотрим. До истечения пробного срока единственным проявлением триальности является надпись в заголовке окна. На попытку зарегистрировать программу левым серийником, она реагирует вот таким сообщением:

Сообщение о неправильной регистрации
Основной файл написан на дотнете, ничем не упакован и не защищен. Поэтому сразу же воспользуемся утилитой dnSpy для его декомпиляции.

Класс регистрации
Сразу же бросается в глаза объект "RegistrationForm", внутри которого обнаруживается не менее интересный класс "Registration", в котором, в свою очередь, находится метод "IsRegistered".

Функция проверки регистрации
Я бы очень удивился, если бы функция с таким названием занималась чем-нибудь другим, кроме проверки статуса зарегистрированности программы. Но на всякий случай откроем ее декомпилированный текст и убедимся в этом. Так и есть, из реестра читаются регистрационное имя и серийник, после чего они проверяются в методе "IsValid" и выносится вердикт о статусе программы.

Редактируем метод
Очевидно, что если изменить функцию проверки таким образом, чтобы она всегда возвращала TRUE, то программа при любых условиях должна будет считать себя зарегистрированной. Открываем метод на редактирование и вписываем вместо всех проверок сразу же возврат нужного значения. Компилируем изменения и сохраняем сборку под новым именем. Запускаем. Если все сделано правильно, то программа работает в зарегистрированном режиме даже без необходимости ввода каких-либо регистрационных данных.

Программа успешно "зарегистрирована"
В принципе, этого уже достаточно, чтобы сделать псевдо-портативную версию для запуска с флешки. Записи в реестре все равно остаются, но выполнять регистрацию на каждом новом компьютере уже не надо.

We need to go DEEPER
Для домашнего использования нормально, для публичного релиза недостаточно. Попробуем разобрать функцию проверки серийного номера.

Функция проверки серийного номера
По предыдущему коду мы знаем, что корректность серийного номера проверяется в методе "IsValid". Посмотрим его. В двух строчках считается хеш и сравнивается с серийным номером, из которого вырезаны пробелы. Чуть ниже видно, как считается этот хеш. И вот тут нам на помощь приходит вся мощь dnSpy. Это ведь не только декомпилятор, но и отладчик для дотнетовских сборок, и настало время его опробовать. Перемещаем курсор на строчку "return RegistrationCode.Replace(" ", "") == b" и нажатием кнопки F9 устанавливаем на ней точку останова. Должен появиться красный кружок рядом с номером строки. Запускаем программу на выполнение (F5) и повторяем регистрацию с каким-нибудь левым серийным номером.

Локальные переменные
Когда сработает точка останова, в списке локальных переменных появится регистрационное имя, введенный левый серийный номер и строка, с которой этот серийник сравнивается. А это ни что иное, как правильный серийник. Таким образом валидной парой будет регистрационное имя "ManHunter / PCL" и серийный номер "E58E8D10D118". Закрываем отладчик и пробуем зарегистрировать программу. Программа благодарит за регистрацию.

Сообщение об успешной регистрации
Для чистоты эксперимента перезапускаем программу, переводим время на пару месяцев вперед, регистрация не слетает. Цель достигнута.

Программа успешно зарегистрирована
Но и это еще не все. Можно ли сделать генератор ключей? Сперва надо точно определить, что за алгоритм хеширования в ней используется. Вернемся к методу "ComputeCode" и посмотрим на него повнимательнее, а точнее на метод "MyDES". Этот метод ссылается на системный криптографический класс MACTripleDES. Согласно документации, этот способ шифрования использует некий ключ, которого у нас пока нет. По ссылкам из функции инициализации, ключ обнаруживается прямо рядышком с описанием метода "MyDES".

Ключ шифрования
Поставив точку останова на вызов "ComputeCode", определяем значения "this.Prefix", "this.HashDigits" и "this.Suffix". Это будут, соответственно, символ "E", число 11 и пустая строка. Таким образом, правильный серийник будет состоять из символа "E" и 11 символов строки, полученной из регистрационного имени, зашифрованного по алгоритму Triple DES с известным ключом. Зашифрованная строка переводится в HEX-значение, так же как и ключ из текстовой строки переводится в двоичные данные. Для серийника используются последний 8-байтовый блок, полученный при шифровании.
Для разных языков программирования есть реализации Triple DES, но можно обойтись вообще без какого-либо программирования. Например, воспользовавшись замечательной утилитой SND Reverser Tool.

SND Reverser Tool
Выбираем функцию "DES Triple - Encrypt", в поле "Input" вводим регистрационное имя, в поле "Key" ключ шифрования из дотнетовской сборки. Осталось выставить правильные настройки: меню "Input + Output Options" - "Read Key as Hex" и "Display Output in Uppercase", а в меню "Encryption Mode" - "Cipher-Block Chaining (CBC)". В полученной строке отступаем 16 символов с конца и копируем 11 символов с этой позиции. Затем дописываем в начало букву "E" и получаем правильный серийный номер.
Огромное спасибо автору Expresso за замечательный инструмент, который еще не раз пригодится вам, если вы занимаетесь программированием. Ну а адепты Темной стороны Силы смогли на практике опробовать отладку .NET сборок.
Просмотров: 3641 | Комментариев: 6

Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье

nubuser
(06.03.2018 в 14:57):
В dnSpy можно искать русские буквы?
Скажем, пишет: "Неверный ключ".
У меня не получается.
Скажем, пишет: "Неверный ключ".
У меня не получается.

xussr
(04.03.2018 в 20:48):
Скорее классика от простого к сложному, флуд не уместен статья действительно учит !

Rustamer
(04.03.2018 в 11:04):
Статья то занятная(хотя бы нашлось применение SnD Revereser Tool), да и разбираемая программа лично у меня является главным инструментов (наряду с TextPipe) для работы с регулярками. Но ведь ее и лечить то не надо - сразу в OpenSource автору выкладывать, тк имхо классика. А ведь есть в мире дотнета более занятные экземпляры - софтины от fishcodelib, LinqPad и тп. Вот на их разбор посмотреть было бы весьма интересно имхо.

brute
(04.03.2018 в 07:10):
имхо, сменились поколения, молодёжи реверс не интересен, ибо нужны мозги и сложно его монетизировать. Вырос уровень защит, везде пакеры/крипторы/привязка к железу/онлайн проверка (для лечения которых нужен "приватный софт") или уже готовые ключи на торренте; программ "ничем не упакован и не защищен" с каждым днём всё меньше, наметился переход софта на андройд. Последние годы закрылась куча подобных сайтов (интересно, почему же ещё этот не прикрыли?:), вероятно, с конфискацией баз данных и прочими последствиями, кругом анальная слежка, поэтому предпочитают не светиться даже в комментариях..

Vnv
(03.03.2018 в 22:25):
И шо, никому статья не нравится? Никто не работает с дотнетом? Не, ну то шо я его недолюбливаю в счет не берется. Но ведь хорошая статейка, разбор генерации ключа, криптография (мать его), использование инструментов (СПС SND). СПАСИБО!!!

Добавить комментарий
Заполните форму для добавления комментария

ManHunter, если несложно, закинь мысль относительного сетевого стека в Windows. Если вариант перехватить его и контролировать на уровне ядра "телодвижения" сетевых сношений?
Зачем спрашиваю? Хочу дать миру бесплатный и ценный инструмент, чтобы одним — неповадно было, а другим — урок достойный о том, что мир меняется с тебя, а не с рассуждений на диване.
P.S. Rustamer, thanks for TextPipe.