Итак, представим себе такую гипотетическую задачу: у нас имеется некое приложение с онлайн‑проверкой лицензии при загрузке. Его анализ при помощи DIE детектит наличие платформы .NET. Загрузив программу в отладчик dnSpy, обнаруживаем сразу две вещи: плохую и хорошую. Начну с плохой: приложение жестоко обфусцировано, часть методов переименована в бессмысленный набор символов, а главное, вместо их кода повсюду пустые заглушки.
Для очистки совести пробуем сдампить приложение способами, описанным в моей предыдущей статье, — это частенько помогает восстановить скрытый код методов. Увы, не в нашем случае: сдампленные модули работоспособны, но несильно отличаются от исходных. Обфускация никуда не делась, тела методов все равно пустые.
Возвращаемся в отладчик dnSpy и пробуем потрассировать работающую программу. А вот и хорошая новость: в приложении нет антиотладчика, приложение прекрасно запускается и трассируется, причем при трассировке «пустых» методов во вкладке Call Stack видно, что счетчик команд перемещается по невидимому коду и проваливается в вызовы. Погуляв вслепую по коду, мы обнаруживаем еще одну хорошую новость: не все методы переименованы, некоторые названия вполне осмысленны, и можно даже нащупать процедуру проверки валидности (на скриншоте выше — isValid
). Тело данного метода скрыто, но название и индекс известны, и это уже что‑то.
Попробуем подойти к деобфускации по стандартной схеме: для начала натравливаем на приложение de4dot. К сожалению, в нашем случае этот метод не работает, de4dot ничего не деобфусцирует. Более старые версии сразу валятся с ошибкой:
de4dot v3.1.41592.3405 Copyright (C) 2011-2015 de4dot@gmail.com
Latest version and source code: https://github.com/0xd4d/de4dot
Detected .NET Reactor 4.8
Необработанное исключение: System.Security.Cryptography.CryptographicException: Недопустимая длина данных для дешифрования.
в System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
в de4dot.code.deobfuscators.DeobUtils.AesDecrypt(Byte[] data, Byte[] key, Byte[] iv) в D:\a\de4dot-cex\de4dot-cex\de4dot.code\deobfuscators\DeobUtils.cs:строка 87
в de4dot.code.deobfuscators.dotNET_Reactor.v4.EncryptedResource.DecrypterV1.Decrypt(EmbeddedResource resource) в D:\a\de4dot-cex\de4dot-cex\de4dot.code\deobfuscators\dotNET_Reactor\v4\EncryptedResource.cs:строка 225
в de4dot.code.deobfuscators.dotNET_Reactor.v4.EncryptedResource.Decrypt()
...
Версии посвежее формулируют ошибку лаконичнее:
Latest version and source code: http://www.de4dot.com/
21 deobfuscator modules loaded!
Detected .NET Reactor 4.8
ERROR:
ERROR:
ERROR:
ERROR: Hmmmm... something didn’t work. Try the latest version.
Ну теперь мы хотя бы знаем, с чем имеем дело, — это .NET Reactor версии предположительно 4.8. Версия довольно старая, однако с ней не справляется даже специально обученный под .NET Reactor de4dot. Ошибка та же, и нам снова предлагают поискать версию посвежее.
Трудности нас не останавливают: в конце концов, мы уже научились разбирать более крутые обфускаторы типа Agile буквально изнутри на самом низком уровне. Загружаем нашу злополучную программу в отладчик x32dbg и вспоминаем все то, о чем я писал в предыдущей статье. Дабы не тратить время на повторение, опускаю длинное описание теоретической части процесса. Вкратце: загружаем библиотеку cljit.dll, отладочные символы к ней и ставим точку останова на вход JIT-компилятора CILJit::
.
Указанный способ работает, то есть при каждом вызове компилятора в поле ILCode
структуры CORINFO_METHOD_INFO
мы видим расшифрованный IL-код каждого метода. В принципе, можно анализировать код и даже патчить на лету, но это долго и утомительно, вдобавок нас ждет еще одна ложка дегтя. Напомню, что в предыдущей статье я описывал слегка жульнический способ определить индекс компилированной процедуры. Суть его состоит в том, что хендл ftn
(первое двойное слово в структуре CORINFO_METHOD_INFO
), если его использовать как указатель, указывает на одинарное слово — индекс метода в .NET метадате EXE-модуля.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»