Trivia Crack on väga populaarne mäng nii veebi- kui ka mobiiliplatvormidel, mis on mõnevõrra kujundatud Trivial Pursuiti järgi. See on sotsiaalmängude uusim hullus, mis võimaldab kasutajatel võistelda oma sõprade ja võõrastega, vastates paljude kategooriate küsimustele. Kuigi ma pole kunagi mängust väga huvitatud olnud, on mu naisest hiljuti saanud suur Trivia Cracki fänn. Olles mõnda aega tema mängu jälginud, otsustasin selle alla laadida ja lähemalt uurida, kuidas seda rakendati.
Alustasin Androidi rakenduse kasutamise ajal võrgu kaudu tehtud veebi API päringute jälgimisest. Väga kiiresti märkasin mängu ajal midagi huvitavat. Tundus, et rakendus sai Trivia Cracki serveritelt kategooria, küsimuse ja vastuse juba enne, kui kasutaja hakkas "kategooria" ratast keerutama.
Allpool on näide, mille rakendus tõmbab enne selle ekraani kuvamist.
{"id": 2747994099,
"opponent": {
"id": 0,
"alerts_count": 0,
"username": "smartplay(tm)"
},
"game_status": "PENDING_APPROVAL",
"language": "EN",
"created": "03/23/2015 08:58:29 EST",
"last_turn": "03/23/2015 08:58:29 EST",
"type": "NORMAL",
"expiration_date": "03/26/2015 08:58:29 EST",
"my_turn": true,
"statistics": {
"player_one_statistics": {
"category_questions": [
{
"category": "GEOGRAPHY",
"correct": 1,
"incorrect": 0,
"worst": false
}
],
"correct_answers": 1,
"incorrect_answers": 0,
"challenges_won": 0,
"questions_answered": 1,
"crowns_won": 0
},
"player_two_statistics": {
"correct_answers": 0,
"incorrect_answers": 0,
"challenges_won": 0,
"questions_answered": 0,
"crowns_won": 0
}
},
"duelGameType": false,
"normalType": true,
"spins_data": {
"spins": [
{
"type": "NORMAL",
"questions": [
{
"question": {
"id": 14996887,
"category": "SPORTS",
"text": "Who was the first woman gymnast to score a perfect ten at the Olympics?",
"answers": [
"Nadia Comaneci",
"Mo Huilan",
"Tatiana Gutsu",
"Agnes Keleti"
],
"author": {
"id": 71534267,
"name": "Florentina Ionela Gagliano",
"username": "florentina.gagliano",
"facebook_id": "100000030456122",
"facebook_name": "Florentina Ionela Gagliano",
"fb_show_picture": true,
"fb_show_name": true
},
"correct_answer": 0,
"media_type": "NORMAL"
},
"powerup_question": {
"id": 8534934,
"category": "SPORTS",
"text": "In basketball, what does it mean to \"kiss it off the glass\"?",
"answers": [
"Make both free throws",
"Pass off someone's back",
"Dribble past two people",
"Hit a shot off the backboard"
],
"author": {
"id": 41439403,
"name": "tsan.819",
"username": "tsan.819",
"fb_show_picture": false,
"fb_show_name": false
},
"correct_answer": 3,
"media_type": "NORMAL"
}
}
]
}
]
},
"available_crowns": [
"SCIENCE",
"ARTS",
"HISTORY",
"ENTERTAINMENT",
"SPORTS",
"GEOGRAPHY"
],
"my_player_number": 1,
"available_extra_shots": 1,
"player_one": {
"charges": 1
},
"player_two": {
"charges": 0
},
"round_number": 1,
"sub_status": "P1_PLAYING_FIRST_TURN",
"previous_sub_status": "P1_WAITING_FIRST_TURN",
"is_random": true,
"unread_messages": 0,
"status_version": 1,
"new_achievements": false,
"my_level_data": {
"level": 1,
"points": 1,
"progress": 33,
"goal_points": 3,
"level_up": false
}
}
Pange tähele, et vastuses sisalduvad kategooria, küsimus, vastusevalikud ja õige vastuse võtmed. See tähendab, et vastuse leidmine oleks lihtne, kui rakenduses palutakse mängu petta. Kuigi see ei ole mängude jaoks just eetiline ega õiglane, arvasin, et see oleks huvitav uurimus.
Minu esialgne plaan oli Androidi rakendus pöördprojekteerida ja pakkuda kasutajale a Röstsai vastusest teatamine. Alustasin sellest rakenduse dekompileerimine ja lähtekoodi ülevaatamine. Kasutasin grep'i, et otsida allikast mõned märksõnad, mis lootsin aitaksid mul küsimuste/vastuste tegevusele jälile saada. Mõnda potentsiaalset tulemust otsides tõmbasid mu tähelepanu mõned read.
v.setText(p);String s1 = "";
if (com.etermax.tools.f.a.a() && h.a("ANSWERS_CHEAT", true))
{
s1 = (new StringBuilder()).append(" (").append(r.getCorrectAnswer()).append(")").toString();
}
B.setText((new StringBuilder()).append(r.getText()).append(s1).toString());
A.setContentDescription(r.getText());
a(B);
u.setVisibility(0);
C.startAnimation(com.etermax.preguntados.ui.a.c.b());
x.setImageResource(com.etermax.preguntados.ui.game.duelmode.h.a(m).a(g, r.getCategory()));
LayoutInflater layoutinflater;
List list;
if (l != null && l == GameType.DUEL_GAME)
{
y.setVisibility(0);
y.setText(c(c.x().h()));
} else
{
y.setVisibility(8);
}
H.setEnabled(false);
layoutinflater = getLayoutInflater(getArguments());
d.a(e.d);
list = r.getAnswers();
Koodi järel viitas "ANSWERS_CHEAT" mängus peidetud peturežiimile. Selle asemel, et ratast uuesti leiutada, otsustasin uurida, kuidas see töötab. Kasutades grep, leidsin kõik viited "ANSWERS_CHEAT" string ja kiiresti avastatud a viide peidetud menüüle armatuurlaua põhitegevuses.
public boolean onOptionsItemSelected(MenuItem menuitem){
if (com.etermax.tools.f.a.a() && menuitem.getItemId() == com.etermax.i.cheat)
{
if (j.a("ANSWERS_CHEAT", true))
{
j.b("ANSWERS_CHEAT", false);
menuitem.setTitle("Enable Answer Cheat");
return true;
} else
{
j.b("ANSWERS_CHEAT", true);
menuitem.setTitle("Disable Answer Cheat");
return true;
}
} else
{
return super.onOptionsItemSelected(menuitem);
}
}
Tundub, et see kood käsitleb peturežiimi valiku seadistamist, kuid ma ei pääsenud ikkagi menüüsse. Sama tegevuse raames vaatasin läbi alloleva meetodi OnCreateOptionsMenu:
public boolean onCreateOptionsMenu(Menu menu){
if (com.etermax.tools.f.a.a())
{
getMenuInflater().inflate(com.etermax.l.preguntados_debug_menu, menu);
return true;
} else
{
return super.onCreateOptionsMenu(menu);
}
}
Enamik peturežiimi funktsioone, sealhulgas peidetud menüü, tundus olevat sõltuv tagastatud väärtusest com.etermax.tools.f.a.a(). Selle klassi kood on allpool:
public class a.{
private static boolean a;
private static String b;
public static void a(ApplicationInfo applicationinfo)
{
a = false;
}
public static void a(String s)
{
b = s;
}
public static boolean a()
{
return a;
}
public static String b()
{
return b;
}
public static boolean c()
{
return b != null;
}
}
See tundus olevat otsustuspunkt, mida ma otsisin. Ülesande muutmine a = vale; juurde tõsi oleks pidanud lubama peidetud menüü. Avasin klassi smali esituse ja leidsin tõeväärtusliku liikme ülesande.
# direct methods..method public static a(Landroid/content/pm/ApplicationInfo;)V
.locals 1
.prologue
.line 29
const/4 v0, 0x0
sput-boolean v0, Lcom/etermax/tools/f/a;->a: Z
.line 30
return-void
.end method
Muutsin rea 29 (lõigu rida nr 7 ülal) vastu const/4 v0, 1, mis määras väärtuse tõeseks. Seejärel kompileerisin rakenduse uuesti ja installisin selle. Seejärel paljastas menüünupp edukalt allolevad peidetud valikud:
"Answer Cheat" tundus nüüd vaikimisi lubatud, nii et käivitasin testimiseks uue mängu. Ootuspäraselt lisasid mängud nüüd küsimuste järele numbri, mis näitab õige vastuse nullipõhist indeksit.
Laadige alla paigatud APK siin. Pange tähele, et see on ainult uurimise eesmärgil; Ma ei vastuta ebamoraalse mänguviisi eest!
EDIT:APK peegel
See peaks olema hea näide sellest, et kliendirakenduste privaatsust ei saa garanteerida ja arendajad peaksid olema nende koostatud väljaannetes sisalduva suhtes ettevaatlikud.