Игривый Xamarin. Изучаем и взламываем мобильное приложение на С#

Содержание статьи

  • Выбираем инструмент
  • Разбираем APK
  • Патчим .Net
  • Собираем APK обратно
  • Выводы

Прог­рамми­ровать для Android мож­но не толь­ко на Java или Kotlin. Раз­работ­чики на С# име­ют воз­можность соз­давать мобиль­ные при­ложе­ния с помощью плат­формы Xamarin. Сегод­ня мы погово­рим о том, как иссле­довать такие при­ложе­ния и как при необ­ходимос­ти их мож­но взло­мать.

По­палось мне недав­но в руки мобиль­ное при­ложе­ние для Android, которое работа­ло не сов­сем так, как хотелось бы. Зна­чит, нуж­но хорошень­ко покопать­ся в его пот­рошках!

Ска­зано — сде­лано: берем све­жую вер­сию GDA, откры­ваем наш подопыт­ный APK и видим, что выг­лядит он как‑то уж слиш­ком подоз­ритель­но. Клас­сы всех activity содер­жат при­мер­но оди­нако­вый шаб­лонный код такого типа:

public class MainActivity extends BaseActivity{ private ArrayList refList; public static final String __md_methods; static { MainActivity.__md_methods = "n_onCreate:(Landroid/os/Bundle;)V:GetOnCreate_Landroid_os_Bundle_Handler ..... _ILandroid_os_Bundle_Handler:Android.Locations.ILocationListenerInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=nulln"; Runtime.register("Megaprogram.Activity.MainActivity, Megaprogram", MainActivity.class, MainActivity.__md_methods); } public void MainActivity(){ super(); if (this.getClass() == MainActivity.class) { Object[] objArray = new Object[0]; TypeManager.Activate("Megaprogram.Activity.MainActivity, Megaprogram", "", this, objArray); } return;

Это наводит на мыс­ли, что нам попал­ся неп­равиль­ный APK. Воз­можно, какой‑то фрей­мворк… Если поменять рас­ширение .apk на .zip, то в гла­за бро­сает­ся необыч­ная для обыч­ных мобиль­ных при­ложе­ний пап­ка assemblies, содер­жащая кучу DLL-биб­лиотек.

Пос­коль­ку мно­гие биб­лиоте­ки содер­жат в наз­вании сло­во Xamarin, ста­новит­ся понят­ным, отку­да взя­лось такое одно­обра­зие — основной код прог­раммы написан на С# и рас­полага­ется в биб­лиоте­ке DLL, а на Java написа­ны лишь шаб­лонные кус­ки кода, пред­назна­чен­ные для свя­зи меж­ду сре­дой выпол­нения Mono и вир­туаль­ной машиной сре­ды выпол­нения Android (ART).

Ну да лад­но, в сто­рону теорию, пора брать­ся за дело.

 

Выбираем инструмент

Для работы с .Net я исполь­зую три инс­тру­мен­та.

  • dotPeek от JetBrains. Поз­воля­ет деком­пилиро­вать и иссле­довать фай­лы .dll и .exe. У дан­ного про­дук­та самая, на мой взгляд, удоб­ная навига­ция по деком­пилиро­ван­ному коду, так что, если говорить толь­ко об иссле­дова­нии алго­рит­ма, этот инс­тру­мент самый удоб­ный.

    Глав­ное окно dotPeek

  • dnSpy — поз­воля­ет деком­пилиро­вать, редак­тировать, ком­пилиро­вать и отла­живать сбор­ки .Net. Сле­дует отме­тить, что все фун­кции, кро­ме деком­пиляции, работа­ют далеко не всег­да, мно­гое зависит от кон­крет­ной ситу­ации. В моем слу­чае ком­пиляция не зарабо­тала: соф­тина не смог­ла свя­зать прос­транс­тва имен Mono и Android.

    Глав­ное окно dnSpy

  • Simple-assembly-explorer — дос­таточ­но ста­рый, но от это­го не утра­тив­ший акту­аль­нос­ти софт. Поз­воля­ет деком­пилиро­вать .dll и .exe в код на С# или CIL (Common Intermediate Language — «высоко­уров­невый ассем­блер» вир­туаль­ной машины .NET. Про­межу­точ­ный язык, раз­работан­ный фир­мой Microsoft для плат­формы .NET Framework). Самая полез­ная воз­можность — этот инс­тру­мент уме­ет ком­пилиро­вать код на CIL, что поз­воля­ет без осо­бого тру­да вно­сить изме­нения в иссле­дуемые фай­лы.

    Глав­ное окно Simple assembly explorer

  • Для рас­паков­ки и запаков­ки APK я решил исполь­зовать 7z вмес­то стан­дар­тно­го для таких слу­чаев apktool. Ниже я объ­ясню почему.

     

    Разбираем APK

    Сна­чала я попытал­ся исполь­зовать для рас­паков­ки APK извес­тную прог­рамму apktool, но при запаков­ке воз­никла проб­лема из‑за того, что apktool «не зна­ет» такой тип фай­лов, как .dll, не счи­тает его стан­дар­тным для APK. Стан­дар­тны­ми счи­тают­ся толь­ко фай­лы с име­нами из сле­дующе­го мас­сива:

    private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] {"classes.dex", "AndroidManifest.xml", "resources.arsc", "res", "lib", "libs", "assets", "META-INF" };.

    При сбор­ке APK все неиз­вес­тные фай­лы сжи­мают­ся (тип сжа­тия DEFLATED), а Xamarin наде­ется уви­деть свои DLL нес­жатыми (STORED) и от разоча­рова­ния не может нор­маль­но про­читать их. Сна­чала воз­никла мысль испра­вить и пересоб­рать apktool, но потом я решил пос­тупить про­ще: рас­паковы­вать и запако­вывать фай­лы обыч­ным архи­вато­ром, без сжа­тия. Ведь декоди­рова­ние манифес­та или получе­ние smali-кода мне в дан­ной задаче не тре­бует­ся, а зачем тог­да усложнять себе жизнь без необ­ходимос­ти?

    Итак, рас­паковы­ваем:

    7z.exe x program.apk -oprogram_apk

    Пос­ле рас­паков­ки, помимо при­выч­ных для APK фай­лов, получа­ем каталог assemblies с кучей dll. Из них нас инте­ресу­ет одна биб­лиоте­ка, имя которой сов­пада­ет с име­нем при­ложе­ния. Ее‑то мы и будем пот­рошить.

     

    Патчим .Net

    Ана­лиз DLL и поиск мес­та для вне­сения пра­вок выходит за рам­ки сегод­няшней статьи, так как мыс­лям на эту тему будет тес­но даже в кни­ге. Оста­нов­люсь лишь на тех­ничес­ких момен­тах. Как я писал выше, dnSpy отка­зал­ся ком­пилиро­вать исправ­ленную биб­лиоте­ку, поэто­му приш­лось при­бег­нуть к помощи Simple-assembly-explorer (SAE).

    Источник: xakep.ru

    Ответить

    Ваш адрес email не будет опубликован. Обязательные поля помечены *