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

warning

Статья име­ет озна­коми­тель­ный харак­тер и написа­на в обра­зова­тель­ных целях. Автор и редак­ция не несут ответс­твен­ности за любой вред, при­чинен­ный с при­мене­нием изло­жен­ной информа­ции.

Мы уже рас­смат­ривали в пре­дыду­щих стать­ях стан­дар­тные крип­тоал­горит­мы или их модифи­кации, одна­ко быва­ют слу­чаи, ког­да и самопис­ный алго­ритм ста­новит­ся хорошей раз­минкой для моз­гов, даже если он реали­зован на зауряд­ном дот­нетов­ском бей­сике. В сво­ей статье «Зо­лотой клю­чик. Раз­бира­ем на при­мере прин­цип соз­дания кей­генов» я уже рас­ска­зывал, как раз­работ­чики защища­ют прог­раммы при помощи генера­ции лицен­зион­ных клю­чей, а так­же о том, как самому соз­давать подоб­ные генера­торы.

Мы изу­чали и сов­сем прос­той слу­чай, и вари­ант не осо­бо про­думан­ной мо­дифи­кации стан­дар­тно­го крип­тоал­горит­ма. Одна­ко недав­но я стол­кнул­ся с хит­рой реали­заци­ей про­вер­ки кода про­дук­та вооб­ще без исполь­зования стан­дар­тных алго­рит­мов.

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

Прог­рамма впол­не зауряд­ная, написа­на на VB.NET, не исполь­зует никаких серь­езных про­тек­торов, весь код на виду, хотя control flow слег­ка обфусци­рован, веро­ятно каким‑то прос­тым самопис­ным обфуска­тором:

PE32
Operation system: Windows(95)[I386, 32-bit, GUI]
Linker: Microsoft Linker
Compiler: VB.NET
Language: VB.NET
Library: .NET Framework(CLR 4.0.30319)
Tool: Microsoft Visual Studio
(Heur)Protection: Anti analysis[Anti-debug]
(Heur)Debug data: Contains[Absolute PDB path]
_debug_data.5.sg: PE/_debug_data.5.sg: 10: TypeError: Result of expression 'PE.getNumberOfDebugDataRecords' [undefined] is not a function.

По­это­му на пер­вых шагах все прос­то: прог­рамма лег­ко заг­ружа­ется в отладчик dnSpy и поз­воля­ет себя отла­живать, бла­года­ря чему мы быс­тро находим мес­то валида­ции product code по име­ни поль­зовате­ля.

Ко­неч­но, было бы прос­то замеча­тель­но, если бы на мес­те выделен­ного выраже­ния ока­залось равенс­тво типа f(Name)==ProductKey. Тог­да бы мы прос­то ревер­сирова­ли фун­кцию и получи­ли готовый алго­ритм пре­обра­зова­ния име­ни в ключ. Но не тут‑то было: если вни­матель­но всмот­реть­ся в код, то мы получа­ем хит­рое крип­тоурав­нение упро­щен­ного вида:

Lenstr("Unregistered7777766666","11111-22222-33333-44444-55555") == Cval("11111-22222-33333-44444-55555")

Как видишь, основная беда зак­люча­ется в том, что пер­вые пять групп ProductCode вхо­дят в обе час­ти урав­нения, а зна­чит, его при­дет­ся решать. Еще силь­нее нагоня­ет жути, что резуль­таты фун­кций спра­ва и сле­ва — это длин­нющие стро­ки из десятич­ных цифр, вдо­бавок раз­ные по дли­не. Код этих фун­кций под обфуска­цией выг­лядит страш­новато, осо­бен­но фун­кция Lenstr, в которой при бли­жай­шем рас­смот­рении каким‑то обра­зом учас­тву­ет еще и текущее вре­мя.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии