Сейчас на форуме: Magister Yoda, vasilevradislav (+5 невидимых) |
eXeL@B —› Крэки, обсуждения —› Исследование защиты Xamarin Mono/Android |
. 1 . 2 . >> |
Посл.ответ | Сообщение |
|
Создано: 07 мая 2013 16:23 · Поправил: andrique · Личное сообщение · #1 В связи с планируемой покупкой смартфона решил научиться писать под Андроид. Давно пишу на C#; хотя до этого еще больше писал на C++, возвращаться к нему неохота, не говоря уже про жабу. Поэтому порадовался, когда нашел Я, в общем-то, не противник покупки софта за разумную цену. Купил N-е количество средств разработки, например .NET Reflector -- посчитал сотню долл. приемлемой ценой. Но мандроид стоит немног-немал USD1899 (в топовой конфигурации; за Visual Studio минимум над косарь зеленых отдать)! Жесть... данный заоблачный прайс породил просто-таки компульсивное желание исследовать защиту и узнать, чёш там таког! Забегая вперед, скажу, что защиту сделали интересно. На этом форуме был На данный момент техническая часть работы выполнена процентов на 65-70, а принципиально - защита изучена. Данный пост [надеюсь, его можно будет редактировать] представляет собой отчет об этом процессе. Не только что было найдено/поменяно, но и как найдено, какие шаги предприняты для этого. Так сказать, некий кейс-стади для новичков. И кстати, хорошо, что нашелся русскоязычный сайт (этот). Писать отчет на английском не хотца - т.к., очевидно, такой отчет могут прочесть и разработчики, и защитить защиту от исследования . А это нежелательно для нас . Введение (не смеяться!) Весь продукт состоит из двух частей: Xamarin Android и Xamarin Studio. Первая - это SDK для разработки на C# под Android. Представляет собой плагин для студий (как вижуалки, так и своей, см. ниже). Плагин добавляет несколько новых типов проекта на C# - Андроид. Там несколько вариантов приложений можно создать. Собственно этот плагин и является платным. То есть существует и бесплатная версия, но она очень урезанная. Более полную инфу по редакциям смотрим Вторая часть - это полноценная .NET IDE, хотя и не такая навороченная. Надо сказать, это некоторое подслащение горькой пилюли на 2K USD: работает она даже в бесплатном режиме, и может создавать нормальные проекты на C#. Ваш покорный слуга, чтоп проверить это утверждение, тольк чт создал проект консольного приложения, добавил ссылку на один из своих студийных проектов, дернул службу - прога работает, запускается, все ОК. По файлам проекта она совместима с вижуалкой, то есть проект создал в одной, открываешь в другой и наоборот. Иными словами, отличная альтернатива V-студии, когда над на коленке что-нить слабать, а ставится за 5 минут, в отличие от вижуалки. Лицензирование Оба варианта студии привязываются на сайте Xamarin к учетке, которую над создать. Как именно происходит привязка, я не выяснял, возможно, по айпишнику. Но может и нет, для наших целей это несущественно. Пока вы работаете в Xamarin студии, или пока Вы не запустите явно активацию, плагин работает в бесплатном режиме (Starter). Как только будет открыт проект Андроид в вижуалке, плагин начнет пытаться активироваться, обратившись к веб-службе на сайте. Для активации используются следующие данные: имя, телефон, эл. почта, название компании. Активироваться можно либо в триальном режиме, либо в платном. Триал дает все возможности на месяц, а платный - навсегда, но в рамках оплаченной редакции. После истечения триального месяца, можно либо оплатить и активировать платную лицензию, либо вернуться к бесплатной редакции Starter. Что где лежит Файла продукта лежат в следующих местах: C:\Program Files (x86)\Xamarin Studio\ - ксамарийная студия C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Xamarin\ - плагин для вижуалки C:\Program Files (x86)\MSBuild\Xamarin\Android\ - мсбилдные таски для сборки андроид-проектов C:\ProgramData\Mono for Android\License\ - лицуха! Также продукту нужны следующие зависимости: Android SDK JDK GTK# которые могут лежать в своих собственных местах. Общее устройство защиты Во первых, большая часть сборок не подписана. Хотя подписывание сборок не является препятствием, оно отнимает N-е количество времени на снятие. Не подписали, и на том спасибо. Основная сборка вижуального плагина (а начал я с него) - Mono.Android.VisualStudio.dll. Быстрая пробежка по рефлекторному коду показала, что при решении вопроса о состоянии активации эта сборка обращается к программе mandroid.exe, которая оказалась... ой! ой!!! -- НЕУПРАВЛЯЕМАЯ! Блин, это нечестно! - я очень расстроился... В парадигму защиты Xamarin входит: продукт (MonoAndroid), редакция (XamarinEdition) - которая бывает Starter, Indie, Business и Priority, она же Enterprise. Также еще отдельная редакция называется Trial. В последнем случае у нее есть срок действия (expiration). Итак, сборки просят мандроид дать им нечто под названием Entitlements, то есть "права" - что пользователю положено. Entitlements представляет собой строчку следующего вида: 04e5fd6b801c5914be8d1bb302a4738b28039656 MonoAndroid Priority 2050-01-01T00:00:00 Четыре строки, разделенные "\n". Первая строка - это хеш, вторая - название продукта, третья - редакция, четвертая - expriation. Формируются эти строчки следующим кодом: Code:
Так вот. Получив от мандроида эти самые строчки, компоненты студии их проверяют. В проверку входит много чего, начиная от хеша и кончая проверкой даты файла, в котором хранятся Entitlements. Если проверка проходит, компоненты приступают к работе. Если нет - они просят мандроид произвести повторную активацию. До активации мы еще дойдем. Дальше пошла Собственно работа Первой моей идеей было: внести изменения в сборки, чтобы .NET-часть просто не спрашивала неуправляемую прогу ни о чем. На тот момент я еще не знал точно, что это за прога и какая у нее роль. Изначальный подход был такой. Получить исходники сборок при помощи рефлектора, внести нужные изменения, и снова собрать. Но не тут-то было. Дело в том, что рефлектор выдает код "как есть", то есть не компилящийся на C#. Данная мысль требует пояснения. Когда мы пишем на C#, допустим, анонимные делегаты или лямбда-выражения, компилятор создает анонимный класс, у него делает метод, и этот метод подставляет туда, где мы используем эту самую лямбду. Все это оттого, что анонимные делегаты и лямбды - это в парадигме C#, а не CLR. Рантайм про это знать не знает. Идем дальше. Всем известно, что такие символы как '<' '>' '-' и проч. в идентификаторах использовать нельзя. Угу, в идентификаторах C#... Но на ассемблере (IL) - можно. Каковым фактом компилятор радостно и пользуется. Чесн говоря, я не знаю, чем руководствовались разработчики C#, но сделал они так. Допустим, вы пишите такой код: Code:
В этом случае компилятор создаст вот такой метод - статический член класса Program: Code:
Вполне понятно, что C# такое не скомпилит. К сожалению, .NET Reflector вместе со своим плагином FileDisassembler именно такой код и создает. На эту тему я собираюсь создать отдельный топик, т.к. это не дело. Отсутствие надежного инструмента - тревожная ситуация. Ну, а в сборке размером пол-гигабайта таких мест, понятно, выше крыши. Что же делать? Вариант 1: запастись терпением на пару месяцев, и строчка за строчкой исправлять все каки. Вариант, на самом деле, плохой, т.к. за два месяца они выпустят новую версию и все над будет начинать сначала. Вариант второй: дизассемблировать сборку через ILDASM, и вносить изменения в код на IL. Отличный вариант, в управляемом мире ILDASM генерирует отличный код, который собирается без ошибок, одно только "но": кто у нас свободно пишет на IL? Ха ха. В результате был выбран вариант промежуточный: сборка разбирается ILDASM'ом, затем на C# пишется код-заглушка, которую надо вставить в сборку. Затем этот код компилится, разбирается ILDASM'ом, и нужный кусок на IL вставляется в код исходной сборки. Таким образом, мы получаем нужное нам изменение (патч), при этом процесс разборки-сборки проходит вполне надежно. Таким образом, мною были внесены изменения в следующие сборки: Mono.Android.VisualStudio Mono.VisualStudio.Extension2 Mono.VisualStudio.Shell Xamarin.Components.Ide Xamarin.Android.Build.Tasks Видимо, мое сообщение превысило какой-то размер, т.к. то, что я пишу дальше, не сохраняется. Продолжение будет в ответных постах. | Сообщение посчитали полезным: lsreg, Abraham, 4kusNick |
|
Создано: 07 мая 2013 16:32 · Личное сообщение · #2 |
Ранг: 419.0 (мудрец), 647thx Активность: 0.46↗0.51 Статус: Участник "Тибериумный реверсинг" |
Создано: 07 мая 2013 16:33 · Личное сообщение · #3 |
|
Создано: 07 мая 2013 18:04 · Личное сообщение · #4 |
|
Создано: 07 мая 2013 18:13 · Поправил: SaNX · Личное сообщение · #5 жаба+НДК или просто жаба. Дабы убедиться в тормознутости сего чуда предлагаю поставить http://4pda.ru/forum/showtopic=335952 на мобилу. Я его юзал недельку. Запуск идет секунд 15, во время работы наблюдаются тормоза. Перешел на чисто жабовскую anMoney - запуск секунда, причем в анмани бОльший функционал. Как то я ставил себе моно для пробы. Написал хелло ворлд. Запускалось секунд 5, размер апк был весьма огромным. Снес нахер, пишу на жабе. ----- SaNX |
|
Создано: 07 мая 2013 18:32 · Поправил: andrique · Личное сообщение · #6 Ммм... я пока реально не кодил на мандроиде, за исключением Hello World для целей лома защиты. Но вот Эх, пока сам не протестишь, не поймёшь... Сам по себе эмулятор из Android SDK работает ПИИПЕЕЦ как медленно!!! Дней через 10 возьму себе Galaxy Note 2, вот тогда и сделаю выводы... В жабу не верю. Структур, говорят, даже нет! А кстати, где написано, что CoinKeeper написан на мандроиде? |
|
Создано: 07 мая 2013 19:20 · Поправил: SaNX · Личное сообщение · #7 |
|
Создано: 10 мая 2013 17:41 · Поправил: andrique · Личное сообщение · #8 Сделав это, я уже радостно плясал и праздновал победу, пока не увидел в выводе отлаживаемой программы слова о том, что Xamarin/Mandroid работает в триальном режиме. Тут я здорово взбесился. Думаю, коллегам чувства мои будут понятны. Было очень жалко, что сделанная работа прошла впустую. На самом деле, если публика захочет, я могу выложить пропатченные исходники на IL, но пока у меня нет уверенности, что они вообще понадобятся в окончательном варианте. Перехват мандроида На следующем этапе я решил разобраться, что то собственно, за зверь mandroid.exe. Т.к. это неуправляемая прога, исходного кода от него нет и получить не получается . Тогда я пошел таким путем. Я сделал программу-перехватчик. Переименовал mandroid.exe в mandroid-xamarin.exe, сделал программу под названием mandroid.exe и положил ее в папку C:\Program Files (x86)\MSBuild\Xamarin\Android. Таким образом, компоненты студии звали мою программу, а она вызывала сам мандроид, по пути записывая в лог-файл весь обмен данными. Подробно описывать здесь все это я не буду, т.к. выкладываю Собственно, как компоненты студии вызывают мандроид. Примерно так: Code:
Данный код - это мой, но он сделан по подобию оригинального. Итак, компоненты студии запускают мандроид, перехватывают стандартный ввод, вывод и поток ошибок, пихают в stdin команды и читают stdout и stderr. Моя мысль была в том, чтобы вмешаться в этот процесс, отдавать студии мои собственные Entitlements, команды на активацию игнорировать и говорить, что все хорошо - то есть возвращать код 0. Так я и сделал. Опять студия была счастлива, НО! при сборке моего проекта mandroid-xamarin пожаловался на фатальную ошибку. Я понял, что родной mandroid.exe в процессе сборки проверяет, сука, лицензию. И никак это не обойдешь, пока не взломаешь собственно мандроид. |
|
Создано: 10 мая 2013 18:00 · Поправил: SaNX · Личное сообщение · #9 |
|
Создано: 10 мая 2013 18:04 · Личное сообщение · #10 Пришлось так и сделать. Взлом mandroid.exe Т.к. эта сволочь неуправляемая, я стал думать, что бы такое предпринять. Начал с ИДЫ, но она сделала мне файл на ассемблере в миллион (!) строк. Ясно, что с этим разбираться не надо даже пытаться... Дальше я начал тусить на форумах, и вскоре обнаружил, что мандроид запускает некую еще программу mandroid-win.exe, которая, дескать, все и делает. И что она - УПРАВЛЯЕМАЯ!!! Мой энтузиазм увеличился, и я начал разбираться. Я задумался. Процесс монитор ничего такого не показывал, отсюда вывод: он запускает сборки прямо из памяти. Запускает рантайм, создает домен приложения, грузит туда сборки, и вперед. Дальше моя мысль была следующая. Если неуправляемая программа запускает управляемую, налицо желание разработчиков писать все на .NET. Можно сделать вывод, что роль mandroid.exe и состоит в том, чтобы скрытно запустить управляемую прогу. То есть он, козел такой, есть простой запускатор. Значит, если получится вытащить управляемую часть, можно таким образом добраться до самого сердца защиты. ОК, в теле mandroid.exe ничего похожего на сборки не видно. Ага, дальше я выяснил, что программа-то запакована!!! Попробовал искать распаковщики, но ничего не нашел. Все они сообщали, что прога запакована не ими. В конце концов интуитивно я нашел выход. Я нашел отладчик OllyDbg. Очень здоровская штука. Когда я запустил мандроид под этим отладчиком, он отработал, но Олли не выключила все, как это делает студия, а просто остановилась где-то в недрах системы. Выглядело это так: |
|
Создано: 10 мая 2013 18:10 · Поправил: andrique · Личное сообщение · #11 Дальше я нашел окно Memory. Оно, ни много ни мало, показывает всё виртуальное пространство процесса. Все сегменты памяти, все загруженные системные DLL. И я стал рыться в этой памяти. На мое - нет, наше! счастье разработчики не додумались очищать память перед завершением процесса. Очевидно, они не предположили, что кто-то зайдет так далеко. Ребята, это наш большой секрет. Надо, чтобы они и не узнали. НЕ БОЛТАЙТЕ!!! Итак, я начал искать в памяти сигнатуры EXE и DLL файлов - знаменитые MZ. И нашел, представьте мою радость!!! Что я сделал дальше? Я сохранил на диск все сегменты памяти, в которых находились эти сигнатуры. Олли позволяет это делать, и выглядит это вот так: То есть, ясное дело, каким бы упаковщиком не был запакован мандроид, при запуске он распаковывается в памяти, и все становится доступным и беззащитным. Дальше, я написал прогу, которая вытаскивает из дампов сегментов памяти находящиеся там исполняемые образы. Опять, много писать здесь не буду, т.к. выкладываю В этих дампов памяти очень много чего нашлось, в том числе 76 (!) системных DLL типа user32, kernel32 и проч проч проч! Они, кстати, 64-битные, и ни чем не открываются. Найденные DLL я сохранял на диск, и проверял, не управляемые ли они. Проверял так: создавал домен приложения, и пытался грузить туда сборки. Заметьте: грузил "для отражения", это режим позволяет загрузить сборку и не учитывать зависимости. Иначе не загрузились бы. Код в студию : Code:
И что же? Если сборка загрузилась в домен как управляемая, значит, мне доступно ее имя. Ура, с таким именем я ее и сохраняю, как видно из кода. Да, для каждого сегмента (файл с расширением .MEM) я создавал отдельную папку, и складывал туда найденные сборки. И вот, в одной из папок нашлись такие сборки: I18N.dll I18N.West.dll Ionic.Zip.dll mandroid-win.exe Mono.Cecil.dll Mono.Cecil.Mdb.dll Mono.Data.Sqlite.dll Mono.Data.Tds.dll Mono.Posix.dll Mono.Security.dll Mono.Touch.Client.dll Mono.Touch.Common.dll Mono.Web.dll То есть, сцкнх, вся президентская рать! |
|
Создано: 10 мая 2013 18:34 · Личное сообщение · #12 |
|
Создано: 10 мая 2013 18:41 · Личное сообщение · #13 |
|
Создано: 10 мая 2013 18:50 · Личное сообщение · #14 |
|
Создано: 10 мая 2013 19:09 · Личное сообщение · #15 |
|
Создано: 10 мая 2013 19:37 · Личное сообщение · #16 Ну поехали дальше. Моё предположение было в том, что если mandroid.exe запускает mandroid-win.exe, то mandroid-win.exe использует такие же команды, что и mandroid-win.exe, и общается с ним так же, через stdin, stdout, stderr. Надо сказать, что мое предположение подтвердилось. Я скопировал его в папку C:\Program Files (x86)\MSBuild\Xamarin\Android\, переименовал в mandroid-xamarin.exe, и положил свой прокси-проект, чтобы мониторить обмен командами. Получилось, при сборке, вот что: 10.05.2013 19:09:15 mandroid.exe is being called with command line: "-d" 10.05.2013 19:09:15 mandroid-xamarin.exe has started 10.05.2013 19:09:15 stdout: 'OK Ready' 10.05.2013 19:09:15 stdin: 'edition' 10.05.2013 19:09:15 stderr: 'monodroid: error XA9999: Invalid license. Please reactivate Xamarin.Android' 10.05.2013 19:09:15 stdout: 'OK Completed' 10.05.2013 19:09:15 stdin: 'edition' 10.05.2013 19:09:15 stderr: 'monodroid: error XA9999: Invalid license. Please reactivate Xamarin.Android' 10.05.2013 19:09:15 stdout: 'OK Completed' Вот сейчас я нахожусь на этом этапе. Для желающих поиграть со сборочками |
|
Создано: 10 мая 2013 19:46 · Поправил: andrique · Личное сообщение · #17 Дальнейшие действия. В mandroid-win.exe есть класс Xamarin.Licensing.PlatformActivation, который, видимо, все и делает. Для начала я намереваюсь внести в ассемблерный (IL) код изменения - все модификаторы доступа заменить на public! Ха ха!. Напишу прогу, добавлю ссылку на сборку mandroid-win.exe, и буду вызывать метода этого класса, смотреть что он делает, придется отлаживать ассемблерный код, ну ничего, разберусь. Превратить его в код на C# не получится, по указанным выше причинам . Для студии есть приблуда, чтобы смотреть содержимое стека, и проч, проч. У меня она есть, но не помню как называется. Если кто вспомнит, напишите, а то у меня куча софта и искать заипёшьсё. Дальше - написать класс, эмулирующий Xamarin.Licensing.PlatformActivation, с заглушками вместо реального кода. Типа, активация прошла, все свои. Вторая идея заключается в том, чтобы, используя методы Xamarin.Licensing.PlatformActivation, сгенерить правильную лицуху и Entitlements, чтобы даже честный мандроид считал чт все ОК, и работал, работал... То есть, сделать, по типу, кейген. Приглашаю всех поучаствовать в этом мероприятии. Артифакты буду выкладывать, чтобы все могли поиграть. В конце концов, если не получится, то всегда есть патч - Итак, план - сделать кейген. Это будет достойный ответ на сволочную цену в две тысячи баков. ВПЕРЕД! |
|
Создано: 10 мая 2013 21:32 · Личное сообщение · #18 |
|
Создано: 10 мая 2013 23:48 · Личное сообщение · #19 |
|
Создано: 11 мая 2013 00:07 · Поправил: SaNX · Личное сообщение · #20 Ну, кейгена не выйдет, там RSA, паблик грузится из сертификата (ищи где-то в дистрибе) и проверяется подпись+хеши для Code:
Code:
Code:
Хотя, если подменить сертификат, можно генерить ключи юзердата пошифровано Rijndael. ----- SaNX |
|
Создано: 11 мая 2013 01:00 · Личное сообщение · #21 Я пока рассказываю свой прогресс. Итак, я дизассемблировал mandroid-win.exe, получил код на IL. Теперь мне надо было сделать свою версию класса PlatformActivation. Для этого я сделал отдельный проект, назвал его mandroid-win-emulation. И перетащил в него этот самый класс, и все остальное, что для него нужно. Соответственно все неймспейсы там были такие же, и результирующий код на IL можно было радостно вставлять в большой ассемблерный файл вместо изначального класса. Вот, собсн, артефакты: Все файлы для сборки ломаной версии оригинального mandroid-win.exe лежит И вот что получается в результате: я выложил На этом на сегодня мой мозг отказывается работать... целый день сижу с этой херней. Тлять! Почти все сделано. Да, кстати, когда я запускаю мандроид-вин без прокси-программы, ничего не меняется то есть дело не в ней. Ребята, может кто глянет? Где-то что-то я упустил. Еще выкладываю проект mandroid-win, это версия, которая была получена рефлектором, и немного причесана, чтобы компилилась. Запускать ее я не советую, ничего хорошего не выйдет. Она просто для информации. Рекомендую посмотреть отличия класса PlatformActivation в моем эмуляторе и в ней. Вот Ну, надеюсь на вас, коллеги. А нет - ну опять придется самому. Мне не привыкать |
|
Создано: 11 мая 2013 01:37 · Личное сообщение · #22 Ура, тля!!! Разобрался в чем причина зависания!!! Мой mandroid-win.exe, переменованый в mandroid-xamarin.exe, ПРОСТО, ТУПО! ЭЛЕМЕНТАРНО - ПААДААЕТ!!! ха ха ха ха Я сотрю - бл, процесса-то нет! И процесс монитор показывает выход процесса, и в системном журнале написано, что приложение упало. Теперь поставлю обработчик необработанных исключений, и найду причину!!! |
|
Создано: 11 мая 2013 02:07 · Личное сообщение · #23 Народ, произошло что-то странное!!! Я добавил такой код: Code:
и такой: Code:
предполагалось, что он сообщит об исключении, запишет то есть в лог, и упадет как обычно. Но нет! Он просто начал работать!! На команду create-package ответил ОК, построил и запустил прогу на эмуляторе. При этом никаких вопросов о лицензии!!! УРА !! ПОЛУЧИЛОСЬ!! ПРАВДА ПОКА НЕ ЗНАЮ КАК!!! Завтра разберусь!!! Поздравьте меня, что ли!!! | Сообщение посчитали полезным: daFix |
|
Создано: 11 мая 2013 12:17 · Поправил: 4kusNick · Личное сообщение · #24 Поздравляю! Всегда приятно видеть когда человек решается нырнуть в пучину неизведанного и сам во всем разбирается. Сразу молодость вспоминается Гы гы... молодость?? А мне междупроч 45 лет какбэ Ну да, моя же молодость вспоминается, а не ваша ----- Флэш, ява, дотнет - на завтрак, обед и ужин. Unity3D на закуску. |
|
Создано: 11 мая 2013 21:11 · Личное сообщение · #25 |
|
Создано: 12 мая 2013 00:43 · Личное сообщение · #26 |
|
Создано: 12 мая 2013 00:45 · Личное сообщение · #27 |
|
Создано: 12 мая 2013 00:55 · Личное сообщение · #28 SaNX пишет: А не проще сделать поиск по сигнатурам и патчить, как патчили на хабре (ну или где там)? Я, когда заморочился, быстро нашел нужные места и пропатчил. Не пояснишь мысль? Чт ткъ "поиск по сигнатурам"? Ну то есть что такое поиск, понятно А по каким сигнатурам? То есть я совершенно не понял, что за процесс ты описал в этих трех словах? |
|
Создано: 12 мая 2013 01:21 · Личное сообщение · #29 ELF_7719116 пишет: Запасаемся попкорном. Ну чт, попкорн-то весь слопали? Хочется услышать единомышленников. Особенно на тему все-таки кейгена. Я так понимаю, что блоб лицензии на стороне клиента нигде не генерируется, и нет кода, чтобы этот алгоритм воспроизвести? Спрашиваю потому, что сам еще не разбирался. |
|
Создано: 12 мая 2013 01:48 · Личное сообщение · #30 Так, коллеги. К вопросу о кейгене. Рассмотрим следующий код: Code:
Данный код выдает правильную лицензию, которая была мне и выдана Xamarin'ом. Все это наводит на мысль, что раз у нас есть сертификаты - клиентский, и серверный, можно попробовать эту самую лицензию новую сделать и зашифровать и будет счастье. |
. 1 . 2 . >> |
eXeL@B —› Крэки, обсуждения —› Исследование защиты Xamarin Mono/Android |