A napokban történt meg velem egy érdekes eset, ami ismét bebizonyította számomra, hogy a jailbreak nagyon sokmindenre hasznos lehet, még akkor is, ha a hivatalos úton, az App Store-ba készítünk alkalmazásokat. Írtam is erről egy angol nyelvű cikket, amelynek a magyar változatát szeretném most veletek megosztani.
Ezen a nyáron egy infosec és telekommunikációs cégnél dolgozom gyakornokként. Az alkalmazásnak, amit fejlesztünk, szüksége van az iOS olyan funkcióinak elérésére is, amikhez a hozzáférés csak a felhasználó külön engedélye után lehetséges.
Az iOS-be beépített engedélykezelés az alkalmazás számára transzparensen kezeli az ilyen kéréseket – az alkalmazás megpróbálja használni a megfelelő funkciót, ekkor az iOS feldob egy “popup”-ot (illetve ezt maga az app is kezdeményezheti), amelyben a felhasználó választhat, hogy megadja vagy megtagadja a hozzáférést, például a mikrofonhoz vagy a kontaktlistához.
A probléma ezzel annyi, hogy az alkalmazás életében ez összesen egyszer történik meg – a rendszer megjegyzi a felhasználó választását, és – bár a Beállítások appon keresztül az később megváltoztatható – a popup soha többé nem nyílik meg. Mivel én az alkalmazásunk grafikus felületén dolgozom, ezért szükség lenne arra, hogy folyamatosan tesztelni tudjam ezt is.
Némi keresés után a Google ezt a Stack Overflow-kérdést és -választ dobta ki. Ez azonban nem segített sokat. Az egyik válasz egyszerűen teljesen irreleváns volt. A másik javasolt megoldás szerint a beállítások között a “Reset Location and Privacy” menüpontban az összes alkalmazás összes speciális engedélyét törölni lehet egyszerre. Ez viszont azért nem volt elég jó nekem, mert én tesztkészülékként a saját iPademet használom, tehát ha az app minden egyes futtatása után az összes alkalmazástól, amit használok, vissza kellene vonnom az összes engedélyt, az nagyon idegesítő és kényelmetlen lenne.
Éppen ezért úgy döntöttem, hogy kicsit utánajárok a problémának és megpróbálom az iOS-t kifaggatni arról, hogy hogyan is “emlékezik” az egyes alkalmazásoknak adott engedélyekre.
Szerencsére az iPadem jailbreakelt, ezért be tudtam rá SSH-zni, majd a grep parancs segítségével elkezdtem keresni az alkalmazás bundle ID-jára. A munkát a /var/mobile/Library/Preferences könyvtárban kezdtem – jailbreakes fejlesztői tapasztalatom szerint nagyon sok hozzáférésért, engedélyért a SpringBoard vagy a Preferences.app a felelős, és ezek szeretik itt tárolni egy-egy plist fájlban az adataikat. Az eközben talált bináris plist-eket a plutil segítségével tudtam olvasható formára hozni és a vim szövegszerkesztővel nyitottam meg.
Ám az első próbálkozásom nem járt szerencsével. Csak két fájlt találtam, amiben benne volt a keresett bundle ID, és egyikben sem találtam semmilyen releváns információt.
Ekkor arra gondoltam, átfésülöm mégegyszer az egész /var/mobile/Library könyvtárat. Ezzel sajnos kicsit átestem a ló túlsó oldalára: erre már hatalmas mennyiségű, több ezer sornyi kimenetet kaptam – ezt reménytelen egyenként átnézni. Persze ennek jó része szintén nem volt hasznos (például a rengeteg logfájl), de a maradék – “érdekesnek tűnő” – adat mennyisége is nagyon nagy volt. Már-már kezdtem feladni, amikor megláttam a legutolsó találatot, amit a grep kiadott:
Binary file ./TCC/TCC.db matches
Valami azt súgta, hogy erre a fájlra kellene vetni egy pillantást. Gyorsan rákerestem a “TCC iOS” kifejezésre, és találtam is az Apple Support Communities oldalán egy erre vonatkozó beszélgetést. A résztvevők közül többen azt állították, hogy a TCC szolgáltatásnak a kontaktok kezeléséhez van köze, de én gyanakodtam, hogy még sok másért is felelős lehet.
Megpiszkáltam tehát kicsit a TCC.db fájlt:
h2co3-ipad:/var/mobile/Library root# file TCC/TCC.db
TCC/TCC.db: SQLite 3.x database
h2co3-ipad:/var/mobile/Library root# sqlite3 TCC/TCC.db
SQLite version 3.8.5
Enter ".help" for instructions
sqlite>
Nagyszerű, tehát van egy érvényes adatbázisunk. Lássuk, mi van benne!
sqlite> .table
access access_overrides access_times admin
Hmm, ez az access tábla ígéretesnek hangzik! Nézzük csak a tartalmát:
sqlite> select * from sqlite_master where name = 'access';
table|access|access|4|CREATE TABLE access (service TEXT NOT NULL, client TEXT NOT NULL,
client_type INTEGER NOT NULL, allowed INTEGER NOT NULL, prompt_count INTEGER NOT NULL,
csreq BLOB, CONSTRAINT key PRIMARY KEY (service, client, client_type))
sqlite> select * from access;
kTCCServiceTwitter|com.atebits.Tweetie2|0|1|1|
kTCCServicePhotos|com.atebits.Tweetie2|0|1|0|
kTCCServiceUbiquity|com.apple.Preferences|0|1|1|
kTCCServiceMicrophone|foo.bar.MyAwesomeApp|0|1|0|
Telitalálat. Az utolsó sorban látszik a keresett alkalmazás bundle ID-ja, és a hozzá tartozó kTCCServiceMicrophone – ami éppen a mikrofon elérését jelző speciális szolgáltatás. Ki is töröltem tehát ezt a rekordot:
sqlite> DELETE FROM access WHERE client = 'foo.bar.MyAwesomeApp';
Végül kiléptem az SQLite klienséből, és bezártam, letöröltem, majd Xcode-ból újratelepítettem az alkalmazást. És láss csodát: a felugró ablak ismét megjelent, ahogy szerettem volna, anélkül, hogy bármely másik alkalmazásom engedélyei látták volna ennek kárát.
Egyszóval a jailbreak nem egy ördögien gonosz dolog. Sokszor jöhet jól, hogy hozzá tudunk férni a rendszer olyan részeihez is, amit egyébként nem láthatnánk. Hát nem nagyszerű? 😉
10 Comments
“(I wouldn’t ever use an iOS device without jailbreaking it)”
Ezt kihagytad lefordítani,pedig elég erős, szerintem. 🙂
Amúgy jó cikk mind a kettő. Köszönjük.
Mazlid volt
Sziasztok
Reg ota probalok valaszt talalni egy dologra, de nem megy. Fejlesztek egy appot, egyelore magamnak. Igy hat fent van a telefonomon, viszont amikor rajta van, az akkumlator idom jelentosen lecsokken. A standby es usage time azonossa valik. Nincs backgeound refresh, ertesites. Cloudkitet hasznalok es weblapot crawlrolok csak. Tenyleg, szamomra erdekes csak. Ez az akkus dolog normalis egy fejlesztes alatt allo programnal? Ha igen, hogy tudok magamnak fejleszteni app store nelkul? Koszi elore is, tudom kisse off tema.
“Scrolling through the virtually endless sea of text” – gyönyörű ????
@blevy: “Ha igen, hogy tudok magamnak fejleszteni app store nelkul?” – azt ugyan nem értem, hogy az akkuidő lecsökkenése hogyan függ össze azzal, hogy “App Store nélkül” (nemhivatalos úton, gondolom?) szeretnél fejleszteni, de ez utóbbit egyszerűen megteheted, ha jailbreakelt a készüléked: nincs más dolgod, mint úgyanúgy megírni az alkalmazást, mint egyébként, és a fordítás végéről kihagyni a codesigning lépést. Ezek után valahogyan el kell juttatni az app bundle-t a készülékre (pl. SCP-vel), esetleg ott ldid-vel egy hamis codesign-t adni neki, és már lehet is futtatni.
Egyébként nekem úgy tűnik, hogy neked amúgy van hivatalos fejlesztői előfizetésed; ebben az esetben minden további nélkül tudod telepíteni a saját készülékedre az alkalmazást, és ad-hoc distribution segítségével másoknak is lehetővé tudod ezt tenni (valahogy úgy, ahogyan azt a TestFlight csinálta anno).
Szia, hivatalos fejleszto vagyok es eddig ugy kompilaltam, hogy az eszkozt valasztom ki celnak, ez nem ok igy?
@blevy: de, az úgy teljesen jó. Csak akkor nem értem, mi a kérdés.
Hat az, hogy oriasi az akkufogyasztas ha fent a telon az app. A standby es a usage megyegyezik idoben.
@blevy: szerintem valami hiba van az appban, valamit nem megfelelően kezelsz benne, ami miatt nem engedi alvó módba a készüléket. az itt leírtakat nézd végig, és ellenőrizd az appod esetén, hogy adtál-e neki olyan tulajdonságokat, ami ehhez vezethet: http://szifon.com/2014/04/16/gyakori-kerdesek-akkuproblemak-megoldasa-8-lepesben/
Koszonom mindenkinek. Lehet az a baj, hogy debug modban van az app es valamit loggol a mukodesrol ami nekem kellene info legyen 🙂