• Ei tuloksia

Android-järjestelmän arkkitehtuuri (Google 2019a)

Uusi ajoaikaympäristö ART kääntää sovelluksen.dex-tiedoston tavukoodin natiivikoodiksi ja muodostaa.oat-tiedoston, joka sisältää sekä käännetyn Dalvik-tavukoodin sekä sovel-luksessa käytetyn natiivikoodin. Tämä tiedosto sisältää oatdata-osion ja osion käännetylle koodille. Data-osio sisältää tiedot kaikista käännetyistä luokista ja luokan koodin sijainti koodiosiossa ilmoitetaan erityisellä oatexec-symbolilla. Kun sovellus käynnistetään, ART par-sii.oat-tiedoston ja luo jokaista luokkaa kohden C++-olion sekä jokaista metodia kohden C++-ArtMethod-luokan. Myös Android-kehys käännetään samaan tapaan ja ladataan muistiin tietylle muistialueelle sovellusten käytettäväksi (Xue ym. 2017).

Sovellukset voivat käsitellä natiivikirjastoja Java-koodissaan hyödyntäen NDK:ta (Native Development Kit), joka käyttää JNI:tä eli Java Native Interfacea. Tätä koodia kutsutaan .dex-tavukoodissa ja se suoritetaan virtuaalikoneen ulkopuolella tuoden lisää suorituskykyä

(Spreitzenbarth ym. 2013). Natiivimetodit kirjoitetaan käyttämällä joko C:tä tai C++:aa. (Enck ym. 2014). Sovellukset voivat suorittaa koodia järjestelmätasolla lataamalla käyttöjärjestelmän tarjoamia natiivikirjastoja JNI:n kautta. Käyttö ei kuitenkaan ole rajoittunut käyttöjärjestelmän kirjastoihin, vaan sovelluskehittäjä voi liittää sovellukseensa itse tekemiänsä kirjastoja ja suorittaa koodia näiden kautta (Lindorfer ym. 2014).

Käyttöjärjestelmän käynnistymisen jälkeenzygote-niminen prosessi alustaa Dalvik-virtuaalikoneen lataamalla tärkeimmät kirjastot. Tämän jälkeen se jää tarkkailemaan sokettia ladatakseen

uusia prosesseja.Zygotemyös pyrkii nopeuttamaan ohjelmia lataamalla muistiin ohjelmille yhteisiä kirjastoja (Faruki ym. 2015).

Parannuksia, joita käyttöjärjestelmään on tehty, on muun muassa ylivuotojen korjaukset, il-moitus jos sovellukset lähettävät tekstiviestejä, useamman käyttäjän tuki sekä oikeuksien valvonnan siirtäminen resursseilta järjestelmälle (Faruki ym. 2015). Lisäksi uudemmissa käyttöjärjestelmäversioissa parannuksia ovat muun muassa alkuperäisen kontrollivuon muut-tamisen estäminen, tiedostojärjestelmän salaus sekä oikeuksien vaatiminen ajonaikaisesti asennuksessa myöntämisen sijaan (Google 2019c).

Faruki ym. (2015) toteavat, että Android-puhelimille ongelmia aiheuttaa myös käyttöjärjes-telmäversioiden hajaantuminen. Vaikka Google julkaisee runsaasti korjauksia ja päivityksiä, niiden jakaminen käyttäjille on valmistajien vastuulla, jonka vuoksi päivitykset voivat tulla asennettaviksi puhelimiin kuukausien viiveellä. Voi myös olla, että päivityksiä ei julkaista puhelimille lainkaan, mikä jättää puhelimiin hyödynnettäväksi heikkouksia, jotka voi olla jo uudemmissa käyttöjärjestelmissä paikattu.

2.2 Järjestelmän turvatoimet

Android-käyttöjärjestelmässä sovellus- ja tietosuoja on toteutettu kahdella eri tasolla, järjes-telmätasolla sekä ICC-tasolla. ICC-tason toteutus määrittelee turvallisuuskehyksen ytimen, mutta se perustuu alla olevan Linux-järjestelmän toimintalupauksiin. Yleisellä tasolla jo-kainen Android-sovellus ajetaan uniikilla käyttäjätunnisteella. Tämän ansiosta sovelluksista löydettyjä turvallisuusaukkoja ei voi käyttää muita sovelluksia tai järjestelmää vastaan. ICC:tä ei kuitenkaan rajoita käyttäjille tai prosesseille asetetut rajat eikä Linux-järjestelmä pysty

sitä hallitsemaan, jonka vuoksi ICC:n hallintaa tulee tehdä varoen. Android-väliohjelmisto hallitsee ICC-järjestelmää tarkkailemalla sovelluksille ja komponenteille asetettuja nimiöitä.

Pääsynhallintaa sovelluksille hallinnoi oikeuksienvalvoja (Anderson 1972).

Oikeuksienvalvojan valvoo pääsylupia järjestelmän subjektien ja objektien välillä. Yksi tämän toteutus on oikeuksienvalvontamekanismi, joka tarkistaa käyttäjäsovelluksen sille antaman viitteen tietyn tiedon tai sovelluksen käyttöön kyseiselle käyttäjälle sallittujen viittausten listasta. Oikeuksienvalvojan vaatimukset ovat seuraavat:

1. Oikeuksienvalvontamekanismin on oltava immuuni peukaloinnille.

2. Oikeuksienvalvontamekanismia tulee kutsua jokaisella kerralla.

3. Oikeuksienvalvontamekanismin on oltava riittävän yksinkertainen täydelliseen analyy-siin ja testaukseen mekanismin toimivuuden varmentamiseksi.

Android-käyttöjärjestelmän tapauksessa oikeuksienvalvojan tehtävänä on yksinkertaisimmil-laan tarkastaa pääsylupanimiöitä, jotka ovat merkkijonoja. Kehittäjät asettavat sovelluksille lupanimiöitä, ja kun komponentti kutsuu ICC:tä, oikeuksienvalvoja vertaa sovelluksen ja sitä kutsuvan komponentin oikeuksia toisiinsa. Jos oikeudet eivät täsmää, pyyntö hylätään vaikka se tulisi samasta sovelluksesta. Oikeudet määritelläänAndroidManifest.xml -tiedostossa. Oikeudet asetetaan sovelluksen asennuksen aikana, eikä niitä pysty muuttamaan ilman uudelleenasennusta (W. Enck, M. Ongtang ja P. McDaniel 2009).

Google on myös tehnyt parannuksia pohjalla olevalle turvallisuusmallille uudemmissa käyttö-järjestelmäversioissa (W. Enck, M. Ongtang ja P. McDaniel 2009). Näitä ovat muun muassa:

• Yksityiset komponentit, joilla voidaan helposti estää muiden pääsy arkaluontoisiin sovelluskomponentteihin.

• Implisiittisesti avoimet komponentit, joita pystyy käyttämään ilman aikeiden ilmoitta-mia toimintoja. Tämä kuitenkin mahdollistaa viestien väärentämisen.

• Aikeiden oikeudet. Aikeille voidaan määrittää oikeuksia niin, että ainoastaan oikeuden omaavat sovellukset pääsevät käsiksi aie-objekteihin.

• Sisällöntarjoajan oikeuksilla voidaan rajoittaa kirjoitus- sekä lukuoikeuksia tietokan-taan.

• Palvelunsieppaus, jolla voidaan tarkentaa palvelunkäytön oikeuksia. Ilman niitä

palve-lun tarkistukseen on vain yksi oikeus, mikä mahdollistaa palvepalve-lun kaiken toiminnalli-suuden käytön, jos sovelluksella on vain oikeus esimerkiksi käynnistää palvelu.

• Suojatut API:t, joiden käyttöä varten manifesti-tiedostossa tulee vaatia niiden käyttöoi-keuksia. Näin sovellukset eivät pääse vaikuttamaan järjestelmään ilman ennakkotietoa.

• Oikeustasot. Oikeudet on jaettu neljään eri tasoon. Normaalit oikeudet, vaaralliset oikeudet, allekirjoitetut oikeudet ohjelmistokehyksen kehittäjille sekä järjestelmäyh-teensopivuuden vuoksi allekirjoitetut tai järjestelmäoikeudet.

• Tulossa olevat aikeet, jotka jäävät odottamaan toiminnoin suoritusta. Tämän tapahtuessa aikeen puuttuvia kenttiä voidaan täydentää vastaanottajan toimesta.

• URI-oikeudet, joilla voidaan aikeissa antaa lukuoikeudet tietokanta-alkioihin, jos aie avaisi URI:n tiedon eri sovelluksessa, kuin millä on oikeudet käyttää kyseistä sisällön-tarjoajaa.

W. Enck, M. Ongtang ja P. McDaniel (2009) mainitsevat kuitenkin, että osa näistä paran-nuksista piilottaa oikeuksien toimintaa kooditasolle, delegoi toimintaa ja erkaannuttaa pää-synhallinnan toimintaa alkuperäisestä ideasta sekä mallista. Lisäksi muutokset vaikuttavat vaikuttavat lupa-analyysin joustavuuteen.

Android-ydin toteuttaa DAC:n (Linux Discretionary Access Control), jossa jokaiselle sovel-lusprosesille määritellään uniikki tunniste. Tämä estää sovellusten vaikuttamisen toisiinsa.

Android toteuttaa myösParanoid Network Security-ominaisuuden, joka asettaa verkkore-sursseja, kuten langattoman verkon käyttöoikeuksia vaativille sovelluksille ryhmätunnisteen.

Sovelluksen tulee sisältää kehittäjän yksityisellä avaimella allekirjoitettu julkinen avain, jolla varmistetaan Googlen toimesta kehittäjän luotettavuus. Allekirjoituksen perusteella määrätään sovelluksen tunniste, joka johtaa kuitenkin siihen, että kaksi saman allekirjoituksen omaa-vaa sovellusta asetetaan samaan hiekkalaatikkoon. Tätä toiminnallisuutta onkin mahdollista hyödyntää haittaohjelmien kehittäjien toimesta (Faruki ym. 2015).

Android-käyttöjärjestelmän järjestelmäosio sisältää käyttöjärjestelmän ytimen, järjestelmä-kirjastot, ohjelmistokehyksen, ajonaikaisen ympäristön sekä sovellukset. Se on asetettu lu-kutilaan väärinkäytösten välttämiseksi (Google 2019d). Myös sovellusten käteismuisti ja muistikortit ovat suojattu oikeuksilla niiden käytön estämiseksi, kun puhelin on liitetty tie-tokoneeseen USB-kaapelilla. Sovelluksia Android-puhelimeen voi asentaa Googlen omasta

Play-kaupasta tai kolmannen osapuolen kauppapaikoista, joiden käyttöä Google ei kuiten-kaan turvallisuussyistä suosittele. Play-kauppa nimittäin sisältää Bouncer-ohjelmiston, joka analysoi dynaamisesti Play-kauppaan lähetettyjä sovelluksia haittaohjelmien varalta (Faruki ym. 2015).

2.3 Oikeusjärjestelmä

Tärkeänä Android-käyttöjärjestelmän turvallisuuden osana toimii sovellusten asennukses-sa kysyttävät, sovellukselle myönnettävät oikeudet käyttää tiettyjen järjestelmän resurssien API-kutsuja. Jokaisen sovelluksen suoritus tapahtuu vähäiset käyttöoikeudet omaavan käyt-täjätunnisteen prosessissa ja oletuksena sovelluksilla on pääsy vain omiin tiedostoihinsa.

Androidin versio 2.2 sisältää kolmentasoisia oikeuksia yhteensä 134 kappaletta. Ensimmäisen tason tavalliset oikeudet eivät aiheuta käyttäjälle hyväksyttäessä suurta haittaa. Toisen tason oikeudet mahdollistavat vaaralliset API-kutsut, esimerkiksi käyttäjän kontaktien tarkkailun.

Viimeisellä tasolla on järjestelmäoikeudet, joita myönnetään vain puhelinvalmistajan serti-fikaatin omaaville tai tiettyyn järjestelmäkansioon asennetuille ohjelmille. Tämä rajoittaa viimeisen tason oikeudet käytännössä valmiiksi asennettuihin ohjelmiin. Ohjelmien on myös mahdollista määritellä itsensä suojaamisen kannalta omia oikeuksiaan (Felt ym. 2011).

Käyttäjä myöntää sovellukselle asennusvaiheessa oikeuksia liittyen yksityisyyteen ja tur-vallisuuteen. Asennusvaiheen oikeuksien kysyminen antaa käyttäjälle hallintaa laitteensa toiminnasta, mutta se menettää tehoaan, jos kehittäjät pyytävät käyttäjältä laajempia oikeuk-sia, kuin sovellus todellisuudessa tarvitsee. Sovellukset saattavatkin pyytää asennuksen aikana tarpeettoman suurta määrää oikeuksia. Felt ym. (2011) havaitsivat, että Androidin versiolla 2.2 kolmasosa Android Marketista ladatuista sovelluksista pyysi asennettaessa enemmän oikeuksia, kuin olisi ollut tarpeen. He havaitsivat kuitenkin, että ylimääräisiä oikeuksia ei pyydetty valtavasti: yli puolet tutkituista sovelluksista pyysi vain yhtä ylimääräistä oikeutta ja vain 6% ohjelmista pyysi yli neljää ylimääräistä oikeutta. Liiallisten oikeuksien pyytämi-nen vaikutti tutkimuksen perusteella johtuvan sekavasta oikeusjärjestelmästä. Oikeuksien dokumentaatio oli rajattu ja lisäksi dokumentaatiossa oli selkeitä virheitä.

Oikeuksia tarvitaan järjestelmä-API:n, tietokantojen ja viestinvälitysjärjestelmän kanssa

toimi-miseen. Sisällöntarjoajat hoitavat tiedonvälityksen ohjelmille ja aikeet (intent) ilmoittavat ohjelmille tapahtumista. Myös järjestelmäaikeiden kaltaisten aikeiden lähettämiseen tarvit-see oikeuksia. Linux-oikeudet hallinnoivat sokettien ja tiedostojen avaamista. Natiivikoodi ei pysty suoraan kommunikoimaan järjestelmä-API:n kanssa, vaan ohjelman täytyy luoda Java-metodeita kutsumaan API:a (Felt ym. 2011).

Sisällöntarjoajat ovat suojattu dynaamisilla sekä staattisilla oikeustarkistuksilla. Staattisten tarkastusten tapauksessa sisällöntarjoajille asetetaan erilliset luku- sekä kirjoitusoikeudet.

Oletuksena kaikille sisällöntarjoajan resursseille pätevät nämä oikeudet, mutta oikeuksia voidaan myös muokata resurssipolun mukaan. Sisällöntarjoajan kyselyitä hallinnoiva koodi voi myös dynaamisesti vaatia järjestelmän oikeustarkastusmekanismilta tiettyjä oikeuksia mahdollistaen kehittäjälle oikeusvaatimusten asettamisen eri tiedoille tietokannassa (Felt ym. 2011).

Androidin viestinvälitysjärjestelmää käytetään sovellusten keskinäiseen viestinvälitykseen.

Järjestelmäviestien lähettämisen estämiseksi käyttöjärjestelmä asettaa rajoja tiettyjen viestien lähettämiselle. Rajoitukset toteutetaan kahdella tavalla. Joitain viestejä sovellukset voivat lähettää vain, jos ne omaavat tarvittavat lähetysoikeudet. Järjestelmäviestien lähetysoikeudet on rajattu vain prosesseille, joilla on järjestelmäprosessien käyttäjätunniste. Järjestelmävies-tien lähettäminen ei ole käytännössä mahdollista sovelluksille, koska niiden tunniste ei voi vastata järjestelmätunnistetta. Sovellukset tarvitsevat myös oikeuden vastaanottaa viestejä.

Käyttöjärjestelmä säätelee vastaanottajia samalla tavalla, kuin muutkin ohjelmat asettamalla vastaanottajille oikeuksia vastaanottaa tiettyjä lähetettyjä viestejä (Felt ym. 2011).

Sovelluksia asentaessa käyttäjä ohjataan kahden ikkunan kautta. Ensimmäisessä ikkunassa esi-tetään tietoa ohjelmasta. Toisessa ikkunassa kerrotaan, mitä oikeuksia sovellus on pyytämässä sekä tietoa siitä, mitä kyseisillä oikeuksilla on mahdollista puhelimessa tehdä. Asennuksen aikana kuitenkin ilmoitetaan oikeuksista niin, että myös hyödyllisistä sovelluksista saa kuvan vaarallisia oikeuksia pyytävinä. Tämä ehdollistaa käyttäjät myöntämään kaikille sovelluksil-le oikeudet miettimättä, koska sama varoitus näytetään aina jokaisen sovelluksen kohdalla, vaikka sille ei välttämättä olisikaan tarvetta (Sarma ym. 2012).

2.4 Android-API

Androidin API-ohjelmistokehys koostuu kahdesta osasta: jokaisen ohjelman omassa vir-tuaalikoneessaan sijaitsevasta kirjastosta sekä järjestelmäprosessissa suoritettavasta API-toteutuksesta. Virtuaalikoneessa sijaitsevalla kirjastolla on samat oikeudet kuin suoritettavalla sovelluksella, mutta järjestelmässä sijaitsevalla API:lla ei vastaavia rajoituksia ole. Puhelimen tilaa muuttavat API-kutsut ohjataan virtuaalikoneen kirjaston toimesta järjestelmäprosessille.

Sovelluksen API:n kutsuminen tapahtuu kolmessa vaiheessa. Ensimmäisessä vaiheessa sovel-lus kutsuu kirjastossaan sijaitsevaa API:a. Tämän jälkeen kirjaston API kutsuu siinä sijaitsevaa rajapintaa. Lopuksi rajapinta lähettää järjestelmäprosessille RPC-kutsun kyseisen toiminnon suorittamisesta. Normaalisti kaikki kirjaston toiminnot eivät ole sovelluksen käytettävissä, mutta reflektion avulla piilotettuja toimintoja on mahdollista hyödyntää sovelluksessa. Piilo-tettujen toimintojen alkuperäinen käyttötarkoitus on kuitenkin ollut niiden hyödyntäminen Googlen kehittämissä sovelluksissa tai sovelluskehyksen itsensä käytössä (Felt ym. 2011).

Oikeuksien noudattamista valvovat useat järjestelmän osat. Näitä ovat järjestelmäprosessi sekä APIiin ripotellut mekanismit. Oikeuksien tarkastamiseen ei kuitenkaan ole yleistä linjaa.

Oikeuksien tarkastus tapahtuu järjestelmäprosessin toteutuksessa. Virtuaalikoneen API-kirjasto pystyy myös tarkistamaan oikeuksia, mutta ohjelmat pystyvät kiertämään tämän tarkastuksen kommunikoimalla suoraan RPC-tynkien kanssa (Felt ym. 2011).

2.5 Android-sovellusten rakenne

Androidille kehitettävät sovellukset rakentuvat komponenteista. Nämä voivat sisältää neljää erilaista komponenttityyppiä. Komponenttityypit ovatActivity,Broadcast Receiver, Content ProviderjaService (W. Enck, M. Ongtang ja P. McDaniel 2009). Nämä toteutetaan johtamalla ennalta määrätyistä järjestelmäluokista uusi luokka, rekisteröimällä tämäAndroidManifest.xml-tiedostossa ja toteuttamalla uudelle luokalle elinkaarimeto-dit, kutenonCreate()jaonStop()(Arzt ym. 2014). Android-sovellusten analysoinnin ongelmana on, että ne eivät sisällä varsinaista päämetodia, josta suoritus lähtee liikkeelle, vaan sovelluksen koodiin voidaan tulla useammassa tilanteessa (Arzt ym. 2014).

• komponentti määrittelee ohjelman käyttöliittymän. Vain yhdellä Activity-komponentilla kerrallaan voi olla puhelimen fokus ja niitä on yleensä yksi jokaista sovelluksen ikkunaa kohden.

• Broadcast Receiverottaa vastaan viestejä muilta sovelluksilta. Yleensä sovelluk-set lähettävät viestejä johonkin tiettyyn osoitteeseen, jota muut sovelluksovelluk-set kuuntelevat, mutta viestejä on mahdollista lähettää myös suoraan muille vastaanottajille.

• Content Providertallentaa ja luovuttaa tietoja SQLite-relaatiotietokannasta. Jo-kaisella Content Providerilla on niin kutsuttu "auktoriteetti", joka määrittelee kompo-nentin sisältämän tiedon. SQL-kutsut tiedon saamiseksi komponentilta tehdään auktori-teetin nimen perusteella.

• Servicetoimii taustaprosessina. Jos ohjelman tarvitsee suorittaa toimintoja silloin, kun käyttöliittymä ei ole näkyvissä, ohjelma käynnistää sille palvelun. Service myös määrittelee rajapintoja RPC-kutsuille muiden järjestelmäkomponenttien kanssa vuoro-vaikutusta varten.

Ohjelmistokehittäjä määrittelee sovelluksenAndroidManifest.xml-tiedostossa sovel-luksen käyttämät komponentit. Erityyppisten komponenttien määrälle ei ole rajoituksia, mutta tapana on nimetä yksi komponentti, yleensä Activity, samannimiseksi kuin itse sovellus. Täl-lä tavoin ilmoitetaan myös sovelluksen pääasiallinen Activity, joka käynnistää sovelluksen käyttöliittymän (W. Enck, M. Ongtang ja P. McDaniel 2009).

Komponenttien vuorovaikutus tapahtuu pääasiassa aikeilla, jotka ovat määränpään sekä datan sisältäviä viestiobjekteja. Android-API määrittelee aikeiden vastaanottofunktiot ja käynnistää niiden avulla aktiviteettejä tai palveluita ja lähettää viestejä. Funktiokutsut ovat startActivity(Intent)-kaltaisia. Nämä funktiokutsut ilmoittavat ohjelmistokehyk-selle, että kohdesovelluksessa tulee suorittaa koodia. Tätä komponenttien välistä viestintää kutsutaan tapahtumaksi (action) (W. Enck, M. Ongtang ja P. McDaniel 2009).

Aie-objekti siis määrittelee aikeen suorittaa jokin tapahtuma. Kohdekomponentti voi olla jokin tietty komponentti, mutta kehittäjä voi myös määritellä kohteelle implisiittisen nimen.

Tätä kutsutaan tapahtumamerkkijonoksi (action string). Jos esimerkiksi kuvaan viittaavas-sa aikeesviittaavas-sa kutsutaan VIEW-tapahtumamerkkijonoa, järjestelmä ohjaa aikeen oletuksena käytössä olevalle kuvankatselusovellukselle. Komponenttien välistä kommunikaatiota

kut-sutaan ICC:ksi (inter-component communication) ja se vastaa Unix-järjestelmän IPC:tä (inter-process communication). ICC toimii samalla tavalla riippumatta siitä, onko kohde sama tai eri sovellus, kuin kutsun tekijä. Käytössä olevat ICC-tapahtumat riippuvat kom-ponentin tyypistä. Aktiviteetit ilmestyvät ruudulle. Palvelut tukevat aloitus-, lopetus- se-kä sitomistapahtumia, jotka mahdollistavat palvelun tarjoamien RPC-kutsujen se-käytön. Lä-hetyksen vastaanottajalle lähetetty viesti tapahtuu aikeena joko tietylle sovellukselle tai tapahtumamerkkijonon mukaan. Sisällöntarjoajia kutsutaan aikeiden sijaan erikois-URIn content://<authority>/<table>/[<id>]avulla, joka suorittaa palveluntarjoa-jalla SQL-kyselyn. <table> on palveluntarjoajalla oleva SQL-taulu ja vapaaehtoisena annettava<id>jokin tietty tietue taulussa (W. Enck, M. Ongtang ja P. McDaniel 2009).

Androidille kehitettävät sovellukset kirjoitetaan Java-ohjelmointikielellä, mutta myös natiivi-koodia on mahdollista hyödyntää. Kaikki sovellukset suoritetaan myös omassa virtuaaliko-neessaan (Felt ym. 2011).

Android-sovellus pakataan.apk-pakettiin,.zip-paketin kaltaiseen tiedostomuotoon, joka sisältää tarvittavat tiedot ohjelman suorittamiseen. Paketin tärkeintä sisältöä on

AndroidManifest.xml-tiedosto, joka sisältää muun muassa sovelluksen vaatimat oikeu-det, tuetut käyttöjärjestelmäversiot sekä sen suorituksessa tarvitut kirjastot. Lisäksi

classes.dex-tiedosto sisältää virtuaalikoneessa suoritettavan tavukoodin ja Meta-INF-kansio sisältää ohjelman kehittäjän allekirjoitetun sertifikaatin (Faruki ym. 2015). Paketin sisältämät kansiot ja tiedostot ovat tarkemmin seuraavat (Tam ym. 2017):

• META-INF-kansio sisältää manifesti-tiedoston, salaustiedostoja ja listan käytetyistä resursseista.

• Assets-kansio sisältää AssetManagerilla haettavissa olevat tiedostot.

• Lib-kansio sisältää prosessorin ohjelmistotason mukaan lajitellut käännetyt koodit.

• Res-kansio sisältää resurssit, joita ei ole käännetty valmiiksi.

• AndroidManifest.xml sisältää tietoa sovelluksesta, sen kirjastoista, oikeuksista, kompo-nenteista ja versiosta.

• classes.dex tai classes.odex (AOT-kääntäjällä) sisältää sovelluksen tavukoodin.

• resources.arsc sisältää valmiiksi käännetyt resurssit.

Kuviossa 2 on esitetty.apk-paketin sisältö.