Приветствую всех, продолжаю цикл статей реверс-инжиниринг для начинающих и сегодня представляю 5 - часть. Эта статья по своему будет интересной, в ней мы рассмотрим не только варианты патчинга программ а и посмотрим на способ написания KeyGena (Генератора ключей для программ). Но это еще не все, как обычно, сказано просто а нюансов много. Надеюсь статья Вам понравится, по крайней мере я так думаю а Вы уже оцените по факту.
Сегодняшнее меню у нас состоит из 5 программ.
HelpCreator (Программа для создания различных справок Windows в формате CHM)
FormMaker (Программа для создания онлайн форм)
OrderForm (Программа для создания HTML-форм для продажи ваших товаров в Интернете)
HtAccess (Программа для создания файлов конфигурации .htaccess для веб-серверов Apache)
MarkdownEditor (Редактор Markdown для Windows)
HelpCreator (Программа для создания различных справок Windows в формате CHM)
FormMaker (Программа для создания онлайн форм)
OrderForm (Программа для создания HTML-форм для продажи ваших товаров в Интернете)
HtAccess (Программа для создания файлов конфигурации .htaccess для веб-серверов Apache)
MarkdownEditor (Редактор Markdown для Windows)
Начнем наш обзор с программного обеспечения под названием HelpCreator. Официальный сайт программы https://helpcreator.net/en/. Если сказать в двух словах то это программа для создания различных справок Windows в формате CHM, с возможностью конвертации их в exe файлы.
Стразу хочу отметить что программы были отобраны не просто так. Моя цель показать и рассмотреть как можно больше зависимостей, конструкций защиты. И постепенно будем переходить к защитам различной сложности, всему свое время. Для начала, как обычно, давайте же запустим программу и визуально посмотрим на принцип активации программы. С самого начала становится понятно что для активации программа требует данные - имя пользователя и ключ активации.
Разрядность: В данном случае утилита коректно не смогла определить разрядность приложения. Но так как программа по стандарту установлена в папку Program Files (x86) значит это 32 разрядное (32-битное) приложение Windows .
Язык программирования и есть ли упаковка (сжатие), защита на программе: Язык программирования С# \ а вот защиты нет, упаковки или обфускации кода.
Ну и последний пункт: Тут идут всегда рекомендации по использованию отладчика. А как по мне так DnSpy, в нашем, случае будет поудобней. Ну каждому свое, я не навязываю.
Ну и теперь давайте посмотрим внутренности программы через отладчик. Закидываем исполняемый файл программы в DnSpy, нажимаем по нем правой кнопкой мышки и переходим сразу же в точку входа программы. То есть туда где происходит запуск программы, загрузка компонентов, стилей и так далее.
Далее мы видим что вот тут Application.Run(new MainForm()); происходит запуск главной формы программы. Давайте туда перейдем и посмотрим что у нас там запускается и как все взаимосвязано между собой.
Нажимаем левой кнопкой мышки по MainForm и заходим в внутрь функции. И видим там очень интересный вызов функции ...КeyLogic. Уже само название за себя говорит и можно предположить что это что то связано с регистрацией. Нам никто не мешает перейти и посмотреть, кликаем левой кнопкой мышки по КeyLogic.
Вот как это дело выглядит в нашем случае.
Gif картинка не поместилась в тему, ОБЯЗАТЕЛЬНО скачать и посмотреть:
mega.nz
И так, на Gif анимации показано: ввод в поле User Name текстовых данных xss.pro-EXE- и неверного ключа активации 000000000. А в финале, функция регистрации отобразила нам правильный ключ регистрации. То есть 922790-850355088-6479946.Gif картинка не поместилась в тему, ОБЯЗАТЕЛЬНО скачать и посмотреть:
Скрытый контент для зарегистрированных пользователей.
2.71 MB file on MEGA
Давайте введем данные активации в программу и проверим так ли это. Запускаем программу и вводим данные активации:
User Name: xss.pro-EXE-
Activation Key: 922790-850355088-6479946
И смотрим что все отлично, программа благодарит за активацию. Но это еще не все, идем далее.
Сейчас покажу разбор (перевод на более понятный язык) функции генерации ключа, можно сказать пальцах. Первое выделяется сразу же так это то что ключ регистрации состоит из трех частей, разделенных между собой символом -.
- Первая часть кода, вычисления и значения: КeyBase у нас это числовое значение и оно равно 0x000132E2. И переводится из шестнадцатеричной системы счисления в десятичную. То есть 132E2 в десятичной системе счисления КeyBase будет равен = 78562. После чего КeyBase умножить на длину строки User Name (то есть имени пользователя) + альт-код первой буква из строки User Name (то есть имени пользователя) умножить на альт-код символа "ʚ" (что равен 666).
- Вторая часть кода, вычисления и значения: КeyBase умножить на альт-код первой буквы из строки User Name и умножить на 123
- Третья часть кода, вычисления и значения: КeyBase + длина строки User Name (то есть имени пользователя) * альт-код первой буквы User Name * 6613
В результате, если имя пользователя мы ввели xss.pro-EXE- у нас получается вот такое уравнение:
- Первая часть ключа активации состоит из такого уравнения: 78562 * 11 + 88 * 666 = 922790
- Вторая часть ключа активации состоит из такого уравнения: 78562 * 88 * 123 = 850355088
- Третья часть ключа активации состоит из такого уравнения: 78562 + 11 * 88 * 6613 = 6479946
Разобрав алгоритм генерации ключа мы можем написать свой KeyGen (генератор ключей активации программы). На каком языке написать генератор ключей ?, тут уже выбор за Вами. Я же, к примеру, напишу его на Delphi. Все на самом деле не сложно и Вы сейчас сами в этом убедитесь.
Код генератора ключей:
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
// Первая часть кода
Key1.Text := IntToStr((78562 * Length(UserName.Text)) +
(ord(UserName.Text[1]) * 666));
// Вторая часть кода
Key2.Text := IntToStr(78562 * ord(UserName.Text[1]) * 123);
// Третья часть кода
Key3.Text := IntToStr(78562 + Length(UserName.Text) *
ord(UserName.Text[1]) * 6613);
//Финальный ключ состоит из трех частей разделенных символом -
FinalKey.Text := Key1.Text + '-' + Key2.Text + '-' + Key3.Text;
end;
Давайте приступим. В предоставленном генераторе ключей, пояснения к коду:
- Ord - это функция что преобразовывает символы, перечисления в их числовые эквиваленты.
- IntToStr - используется для преобразования целого числа Integer или Int64 в строку.
- ord(UserName.Text[1]) - Берем первый символ из имени пользователя и преобразовываем его в числовой эквивалент.
- Length(UserName.Text) - длина строки имени пользователя, то есть подсчет введенных букв в текстовое поле UserName.Text.
- Key1.Text - Текстовое поле для генерации и отображения Первой части кода
- Key2.Text - Текстовое поле для генерации и отображения Второй части кода
- Key3.Text - Текстовое поле для генерации и отображения Третьей части кода
- FinalKey.Text - Текстовое поле для вывода финального ключа что состоит из трех частей.
- Знак * - Умножения.
- Знак + - Сложение.
Ну и теперь прокомментирую что у нас тут получилось на практике. В текстовом поле Вы вводите желаемое имя для регистрации программы и получаете рабочий регистрационный ключ. Генератор ключей я специально разделил на три части с выводом каждой - что бы, новичкам, понятней был принцип его работы. Как видите ничего сложно в написании подобных вещей нет. Исходники и сам генератор ключей я обязательно прикрепил к этой статье, сможете открыть и посмотреть.
И это еще не все, теперь давайте сгенерируем ключ активации на имя пользователя USER-xss.pro-EXE- и активировать программу. Как видим программа успешно зарегистрировалась и в окне с информацией о лицензии красуется надпись на кого зарегистрирована программа.
А теперь давайте рассмотрим вариант патчинга этой программы, без использования KeyGen. Вернемся назад к нашей функции проверки логики ключа активации. Кликаем по функции IsRegistered левой кнопкой мышки и смотрим что происходит внутри.
А тут все просто, проверка файла с данными лицензии на существования и проверка ключа активации через функцию CheckSerial.
Если посмотреть код функции CheckSerial то обратите внимание на число 78562 тут у нас уже в десятичной системы счисления переведен КeyBase (Я про это говорил выше). Это так для информации и понимания взаимозависимости между функциями.
Нам никто не мешает сделать так чтобы функция IsRegistered всегда возвращала успех, то есть заменить весь код функции на одну строку return true; То если есть ключ или его нет все равно программа будет активирована. Также обращаю ваше внимание и на то что функция IsRegistered вызывается из InformationManagerLogic.dll, то есть динамической библиотеки и по факту мы делаем изменения в ней а не в исполняемом файле программы. То есть код функции будет выглядеть вот так после изменения.
А теперь давайте сохраним результат, запустим программу и посмотрим активировалась у нас программа или все же нет ?. Запускаем, форма активации исчезла, никаких регистрационных данных программа не просит, что следовало было ожидать. Но тут есть интересный нюанс, если перейти в меню программы info - About, что бы посмотреть на информацию о лицензии то программа нам покажет окно с ошибкой (исключением). После закрытия этого окна - закроется и программа. На работу софта это не влияет, но смотрится некрасиво. Такие нюансы нужно всегда исправлять, особенно если пропатченную программу вы публикуете для широкой публики.
Что касается программ (этого разработчика) у которых один тип лицензии, то :
В программе MarkdownEditor (https://da-software.net/en/software/da-markdowneditor/)
Что касается генерации ключа:
Тут, также как и в первой нашей программе, принцип генерации ключа такой же. Но КeyBase будет равен = 29383. А функция генерации ключа вызывается из
MarkdownEditLogic.dll - файла динамической библиотеки (Также, только название этого файла другое, как Вы сами можете заметить на рисунке).
Для генерации ключа вам нужно просто в исходном коде KeyGen заменить 78562 на 29383.
И после скомпилировать, запустить и сгенерировать ключ. После чего программа также успешно активируется.
В программе HtAccess (https://da-software.net/en/software/da-htaccess/)
Что касается генерации ключа: То и тут ничего особенного, принцип генерации ключа тот же но вот КeyBase будет равен = (Перевод из шестнадцатеричной системы счисления в десятичную 14E82) = 85634. А функция генерации ключа вызывается с файла динамической библиотеки DALogic.dll (Такой же принцип как в предыдущем софте, только название этого файла (dll) другое).
Для генерации ключа вам нужно просто в исходном коде KeyGen заменить 78562 на 85634.
Ну и тут также скомпилировать, запустить и сгенерировать ключ. После чего программа успешно активируется.
Что касается патчинга (Если не использовать генератор лицензий): Также как и в первой программе, убираем все лишнее с IsRegistered , а оставляем return true;
И что бы корректно отображалось имя пользователя, на кого зарегистрирована программа, как я показывал в первом примере. Просто прописываем понравившееся нам имя пользователя.
Сохраняем результат и смотрим что все прекрасно активировалось и мы добились успеха в очередной раз.
Ну а теперь перейдем к более сложнее задачам. А именно к остальным, двум, программам у которых принцип активации немного другой.
Давайте первую рассмотри OrderForm (https://da-software.net/en/software/da-orderform/). Тут уже разработчик предлагает купить или full версию лицензии или
Professional Edition. И между ними имеются, естественно, ограничения по функционалу.
Давайте посмотрим как поведет себя программа при вводе неверного регистрационного имени и ключа. И отследим и посмотрим стучится софт в интернет для проверки лицензии или нет. Для этого запускаем HTTP Analyzer что служит нам для мониторинга http и https трафика в режиме реального времени. Запустили, нажали на кнопку Start. А после запустим нашу программу и введем любые данные для регистрации. Что мы наблюдаем ?, действительно программа проверяет корректность введенных данных через свой сайт (сервер). В данном случае KeyGen нам не поможет (особо), тут уже логичней попробовать пропатчить саму проверку. Ну что, давайте же приступим и проанализируем логику защиты программы изнутри.
Откроем программу в отладчике и посмотрим на логику активации. Сейчас покажу еще один хитрый способ как можно искать уязвимые места в программах, выходя из логики защиты что мы проанализировали выше. Принцип таков что защитные функции программы вызываются из динамической библиотеки dll схожей с названием самого исполняемого файла. Так вот давайте, к примеру, поищем сразу же что нибудь связанное с типами лицензии в самом dll файле. Выходя из логики это OrderFormLogic.dll, к примеру слово License. И посмотрим где оно используется, в результате попадаем на такую конструкцию кода.
А мы что должны ответить в таком случае ? Правильно, True (Успех). То есть при любом раскладе, даже если данных активации нет или не соблюдены какие условия то все равно разрешить (True). Изменяем логику кода на противоположенное значение.
Сохраняем изменения в нашем файле, DALicencing.dll и запускаем программу. Программа запустилась, активировалась, но есть одно но!. А именно у нас активировалась Стандартная лицензия. А хочеться конечно же Профессиональную, где больще функций доступно и все такое.
AppType.DABestell; на AppType.DABestellPro; И сохраняем результат в этот раз это в файл OrderFormLogic.dll, так как из него идет переключение типа лицензий.
Запускаем программу и видим что у нас без проблем активировалась максимальная лицензия (Профессиональная). То есть в этот раз мы: также, просто достигли своей цели.
Забегая немного наперед скажу что: Эта программа защищена по такой же логике как и предыдущая. Отличие всего лишь одно, а именно в том что функция проверки типа лицензии вызывается из файла FormMakerLogic.dll. То есть файла по названию идентичному исполняемому, только что формат отличается.
Тоже самое ищем License в файле FormMakerLogic.dll. Что бы получить Максимальную лицензию (то есть Профессиональную) - нужно AppType.DAFormStandard; заменить на AppType.DAFormPro;. То есть при любом раскладе активации у Вас будет Pro лицензия.
А что бы активировалась эта лицензия то переходим (кликаем левой кнопкой мышки) в IsFreeUpdateTimeSpan и меняем Флаг условия IsActivationValid c False на True. Вот так:
Сохраняем результат. Поскольку мы сделали изменения в двух dll файлах, поэтому, нажимаем сохранить все. После этого запускаем программу и радуемся полученному результату.
Подведем итоги :
В этой статье Вы увидели разные типы защиты одного разработчика. Но у каждой из них были свои особенности. С своей стороны я пытался и буду стараться пояснять все максимально просто. Бываю конечно же нюансы что Вам могут быть не понятны. Я это все понимаю и если возникнут вопросы то всегда рад Выслушать как в теме так и в личных сообщениях.
Кстати: Не думайте что не читал ваши сообщения и пожелания в предыдущих статьях. В этой статье, как Вы просили, сделал минимум цветного текста и смайликов.
Всем Хорошего настроения, надеюсь статья зашла! ?
Продолжение следует......
Наши пациенты / virustotal:
FormMaker / virustotal: https://www.virustotal.com/gui/file/3a24be0cf5d160deb8df8b2a3b995305d01617e9eb391dbff01d50c8f0b19161
HelpCreator / virustotal: https://www.virustotal.com/gui/file/e0e3c562194671034bae54b4c1d24046d7e0e531ab3a58bdb6b83f80a79dc8f2
OrderForm / virustotal: https://www.virustotal.com/gui/file/f569908d13b8a61941f949618aef636d69bb31c4eefcbbef6d1204dbdcb66988
HtAccess / virustotal: https://www.virustotal.com/gui/file/ffde2946310127b930297b49c3c8328cc8af252e694bfa89f63c1e91b2782830
MarkdownEditor / virustotal: https://www.virustotal.com/gui/file/5879cb7d85f8e6c0ea7b2043662a6609bb44a701c179a5b28b5ee43434aea302
Инструменты для анализа:
HttpAnalyzer / virustotal: https://www.virustotal.com/gui/file/f25541dee8f859b62c642d2e6e835c247900b5bc94a00cdbc4d894bab83796dd
dnSpy x32 / virustotal: https://www.virustotal.com/gui/file/7ce05f1aafaaa87d046bbad1b07801777e724251b084bc7f70cef71c98b08105
dnSpy x64 / virustotal: https://www.virustotal.com/gui/file/cc15f3f7836f5c976e058aabdd55af8635b484a6b9a5e94a2cb048856965f9e2
ExeinfoPe / virustotal: https://www.virustotal.com/gui/file/32e6df44a529d3bd543aae01365852990c0e7f3b4f84b5a7f9d7dfc18d6a46fd
Исходный код, на Delphi, KeyGen и исполняемый файл:
Project1.exe / virustotal: https://www.virustotal.com/gui/file...5c8ec79e085401c0dc23aa14de68c2f5171?nocache=1
Файлы к статье:
Скрытый контент для зарегистрированных пользователей.