В этой статье мы раз­берем прак­тичес­кий при­мер работы с при­ложе­нием, защищен­ным кас­томной вер­сией ConfuserEx, которая лома­ет боль­шинс­тво извес­тных деоб­фуска­торов. Мы выяс­ним, почему авто­мати­чес­кие инс­тру­мен­ты не справ­ляют­ся, и пос­мотрим, как вме­шать­ся в работу деоб­фуска­тора, вытащить рас­шифро­ван­ный IL-код и под­готовить его к даль­нейше­му ана­лизу и пат­чу.

Те­ма обфуска­ции и деоб­фуска­ции прог­рамм на .NET воис­тину неис­черпа­ема: мы с тобой уже рас­смот­рели мно­жес­тво извес­тных и не очень обфуска­торов в стать­ях «Ан­гард! Ревер­сим при­ложе­ние, защищен­ное DNGuard», «Не­ядер­ный реак­тор. Взла­мыва­ем про­тек­тор .NET Reactor» и «Ре­вер­синг .NET. Как искать JIT-ком­пилятор в при­ложе­ниях», но воп­рос деоб­фуска­ции по‑преж­нему оста­ется откры­тым.

Ак­туаль­нос­ти ему добав­ляет и то, что даже широко извес­тные обфуска­торы пос­тоян­но совер­шенс­тву­ются (и, наде­юсь, мои статьи раз­работ­чикам в этом помога­ют). Более того, час­то это про­исхо­дит нас­толь­ко опе­ратив­но, что за пол­года в оче­ред­ную вер­сию уже разоб­ранно­го по вин­тикам обфуска­тора добав­ляют столь­ко нового и инте­рес­ного, что мож­но сме­ло раз­бирать его с самого начала. Темой сегод­няшне­го обсужде­ния я выб­рал широко рас­простра­нен­ный про­ект, нес­пра­вед­ливо обой­ден­ный вни­мани­ем в моих пре­дыду­щих обзо­рах, — Confuser.

Собс­твен­но, ранее я не касал­ся этой темы исклю­читель­но из‑за рас­простра­нен­ности обфуска­тора: он изна­чаль­но заяв­лен как open source, и, хотя сайт про­екта за дав­ностью лет уже не откры­вает­ся, сам обфуска­тор лег­ко гуг­лится. Нет­рудно най­ти гит­хабов­ский репози­торий Confuser (ныне, прав­да, тоже уже изрядно уста­рев­ший). С тех пор каж­дый ува­жающий себя .NET-раз­работ­чик, не жела­ющий тра­тить день­ги на готовое силь­ное решение типа DNGuard, счи­тает сво­им дол­гом взять сво­бод­ные исходни­ки Confuser и модифи­циро­вать их под себя, что­бы про­ект не деоб­фусци­ровал­ся стан­дар­тны­ми инс­тру­мен­тами, которых тоже написа­но великое мно­жес­тво.

Их реаль­но нас­толь­ко мно­го, что даже перечис­лять тут не буду. Деоб­фуска­торы для Confuser вынес­ли в от­дель­ный спи­сок на GitHub. Ста­тей по деоб­фуска­ции тоже хва­тает, хоть и не в рус­ско­языч­ном сег­менте (наде­юсь слег­ка испра­вить это упу­щение), — при­водить кон­крет­ные ссыл­ки не ста­ну, нагуг­лишь самос­тоятель­но. Есть и наг­лядные ману­алы. При всей моей нелюб­ви к юту­бов­ским виде­ооб­зорам лич­но мне пон­равилась ви­деоинс­трук­ция по сня­тию ConfuserEx. В ней под­робно опи­саны прин­ципы обфуска­ции ControlFlow, кон­тро­ля целос­тнос­ти, шиф­рования/дешиф­рования кода и исполь­зуемых ConfuserEx строк. В прин­ципе, из это­го ролика ты можешь получить гораз­до боль­ше полез­ной теоре­тичес­кой информа­ции, чем из сегод­няшней статьи. Поэто­му я, как обыч­но, не буду дуб­лировать теорию, а на прак­тичес­ком при­мере раз­беру порядок дей­ствий для слу­чая, ког­да стан­дар­тные под­ходы по какой‑то при­чине не при­носят резуль­тата.

Итак, усло­вие задачи: у нас есть при­ложе­ние на .NET, для которо­го необ­ходимо по воз­можнос­ти обой­ти механизм лицен­зирова­ния. Detect It Easy сра­зу пре­дуп­режда­ет, что это будет неп­росто, пос­коль­ку при­ложе­ние обфусци­рова­но при помощи одной из модифи­каций Confuser.

От­ладчик dnSpy, в котором мы откры­ваем это при­ложе­ние, сооб­щает нам две новос­ти — пло­хую и хорошую. Пло­хая новость зак­люча­ется в том, что подав­ляющая часть наиме­нова­ний методов обфусци­рова­на до нечита­бель­нос­ти, а код самих методов скрыт (мы стал­кивались с подоб­ным еще в самой пер­вой статье про обфуска­цию .NET — «Ре­вер­синг .NET. Как искать JIT-ком­пилятор в при­ложе­ниях»).

С дру­гой сто­роны, мы уже дос­таточ­но мно­го узна­ли про обфуска­цию .NET, что­бы не пугать­ся таких слож­ностей. При­чем в статье «Те­невые вызовы. Ана­лизи­руем хит­рую обфуска­цию в Quick License Manager» я при­водил при­мер, как тех­ничес­ки реали­зует­ся подоб­ное сок­рытие кода и его динами­чес­кая заг­рузка. Более того, в упо­мяну­том ролике при­водят­ся под­робнос­ти, где и как кон­крет­но это дела­ет изу­чаемый нами Confuser.

Хо­рошей новостью мож­но наз­вать то, что, вни­матель­но полис­тав спис­ки обфусци­рован­ных клас­сов и методов, мы с радостью обна­ружи­ваем, что наз­вания инте­ресу­ющих нас методов про­вер­ки лицен­зии не обфусци­рова­ны (похоже, потому, что эти самые методы объ­явле­ны как public для удобс­тва вызова).

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

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

К сожале­нию, как ты уже навер­няка догадал­ся, мы, похоже, име­ем дело с какой‑то необыч­ной кас­томной вер­сией ConfuserEx, которая вро­де как и рас­позна­ется деоб­фуска­тора­ми, но не деоб­фусци­рует­ся пол­ностью, выкиды­вая какую‑нибудь ошиб­ку. К при­меру, деоб­фуска­тор ConfuserEx-Unpacker By ElektroKill в самом кон­це деоб­фуска­ции выда­ет вот такое.

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

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

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

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

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

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

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

    Подписаться

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