Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Скриптовый язык Ruby используется для написания плагинов во многих прикладных программах. Одна из них — 3D-редактор SketchUp. Сегодня мы изучим внутренности таких расширений, зашифрованных с использованием технологии RBE, и напишем свой конвертер из формата RBE в RB.
Продолжим нашу любимую тему разных новомодных скриптовых языков. Раз уж в позапрошлой статье мы вспомнили о языке Ruby, то в этот раз остановимся на другой его инкарнации.
Изначально многие скриптовые языки разрабатывались именно как языки для описания логики расширений популярных программ и служили для автоматизации несложных рутинных действий. Использовать их должны были простые пользователи, не слишком искушенные в программировании. Некоторые языки служат в этом качестве до сих пор (подобные случаи описаны в статьях «Безумный Max. Как ломают плагины для 3ds Max» и «Патчим JSXBIN. Как править бинарные скрипты Adobe без перекомпиляции»), что порождает спрос на защиту их открытого кода от исследования и модификации.
Ruby в этом плане не исключение: он активно используется для программирования расширений и плагинов. Сегодня мы рассмотрим его применение в программе SketchUp. SketchUp — это популярный пакет создания 3D-графики «для чайников», так сказать 3ds Max на минималках. За время своего существования он успел побывать в собственности у Google, а потом был продан по непонятным причинам.
Так уж повелось, что языковой основой скриптового API (описание интересующиеся могут найти на официальном сайте SketchUp) стал именно язык Ruby, на котором можно писать как простецкие макросы, хранящиеся в текстовых файлах со стандартным расширением .rb
, так и продвинутые кросс‑платформенные плагины с расширением .rbz
. При создании этого формата программисты SketchUp особо не заморачивались и пошли по самому простому проторенному пути — плагины являются, по сути, ZIP-архивами, в которых, помимо классов Ruby, может содержаться множество других файлов: тексты, изображения, даже нативные бинарники под разные платформы с расширениями .so
и .bundle
. Их можно сертифицировать (для авторизованных разработчиков), а можно забить на это и использовать так.
Разумеется, программисты продумали и встроили механизм защиты кода классов от исследования. Здесь авторы тоже поленились и вместо того, чтобы (как многие продвинутые разработчики) преобразовать Ruby-текст в шитый код виртуальной машины, не мудрствуя лукаво просто пошифровали его стандартным криптоалгоритмом. Первоначально для этого был придуман формат .rbs
(«scrambled»).
Несмотря на то что процесс шифрования выполнялся на удаленном сервере разработчиков, алгоритм достаточно быстро стал секретом Полишинеля. Более того, энтузиасты написали целый выводок «скрамблеров/анскрамблеров» (например, RbsUnscrambler), ведь шифрование текста проводилось c использованием банального симметричного алгоритма Blowfish, который допускает криптование в обе стороны.
В связи с этим лет семь назад был внедрен новый формат шифрования кода — RBE, информации о реверсе которого в широком доступе пока что не наблюдается. Постараемся исправить такое упущение и исследуем устойчивость этого формата к реверсу и патчингу.
Итак, заканчиваем с теорией и переходим к практике. Допустим, у нас имеется некий плагин к SketchUp в формате .rbz
. Распаковав его при помощи WinZip, видим множество файлов классов с расширением .rbe
. Бинарное содержимое таких файлов для исследований не подходит — как видишь, внутри высокоэнтропийный белый шум, отличающийся от .rbs
только версией сигнатуры RBS2.0.
Поскольку конвертеры из формата RB в RBE и обратно, как я уже говорил, в публичном доступе пока отсутствуют, попробуем отследить расшифровку такого кода при загрузке плагина в динамике. Путем несложных манипуляций с ProcMon определяем, что при запуске SketchUp он загружает распакованные классы и прочие библиотеки плагина из этого каталога:
C:Users...AppDataRoamingSketchUpSketchUp...SketchUpPlugins
Попробуем поймать эту загрузку при помощи нашего любимого отладчика x64dbg.
Обычно в подобных случаях мы ставим точки останова на системных функциях открытия и чтения файлов CreateFile
и ReadFile
, однако этот путь внезапно оказывается очень тернистым. SketchUp, как и 3ds Max, в определенной степени сражается с отладчиком — при долгой отладке, многократном срабатывании точек останова и даже аттаче к готовому запущенному процессу он так и норовит «замерзнуть», что откровенно вымораживает уже нас самих. Чтобы не тратить собственные нервные клетки, попробуем зайти с другой стороны.
Как я уже упоминал, 6-байтовые сигнатуры закриптованных файлов хорошо известны (RBS1.0 для .rbs
и RBS2.0 для .rbe
). Попробуем поискать строку RBS2.0 по всем загруженным модулям пакета SketchUp. Довольно быстро мы находим ее в главном модуле SketchUp.exe
по RVA=0x1D72F9C
. Открыв дизассемблированный код в IDA, мы убедимся, что алгоритм шифрования на этот раз RSA + AES.
Перейдя по цепочке ссылок на эту строку, обнаруживаем функцию, возвращающую тип шифрования Ruby-кода: sub_141347340
.
Как видим, возвращаемое значение 1
соответствует старому типу шифрования .rbs
, а 2 — новому .rbe
. Изучив ссылки на sub_141347340
, находим функцию, расшифровывающую этот самый тип 2, — sub_141347F20
.
Открыв реализацию этой функции, мы видим подтверждение наших предположений: для расшифровки кода SketchUp обращается к Microsoft CryptoAPI, вызывая криптопровайдер Microsoft Enhanced RSA and AES Cryptographic Provider, при помощи которого и расшифровывает содержимое файла стандартной библиотечной функцией CryptDecrypt
.
Источник: xakep.ru