Ako som prelomil Trivia Crack

Trivia Crack je veľmi populárna hra pre webové aj mobilné platformy, ktorá je trochu po vzore Trivial Pursuit. Ide o najnovší výstrelok v oblasti sociálnych hier, ktorý používateľom umožňuje súťažiť so svojimi priateľmi a neznámymi ľuďmi v odpovediach na otázky z rôznych kategórií. Hoci som sa o hry nikdy veľmi nezaujímal, moja žena sa nedávno stala veľkým fanúšikom hry Trivia Crack. Po chvíli sledovania jej hry som sa rozhodol stiahnuť si ju a pozrieť sa bližšie na to, ako bola implementovaná.

Začal som sledovaním požiadaviek webového rozhrania API cez sieť pri používaní aplikácie pre Android. Veľmi rýchlo som si počas fungovania hry všimol niečo zaujímavé. Zdalo sa, že aplikácia prijímala kategóriu, otázku a odpoveď zo serverov Trivia Crack ešte predtým, ako používateľ začal točiť kolieskom „kategórie“.

Nižšie je uvedený príklad odpovede, ktorú aplikácia načíta pred zobrazením tejto obrazovky:

{ 

"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

}

}

Všimnite si, že v odpovedi sú zahrnuté kategórie, otázky, možnosti odpovede a kľúče správnej odpovede. To znamená, že by bolo jednoduché identifikovať odpoveď, keď sa v aplikácii spýta na podvádzanie hry. Aj keď to nie je úplne etické alebo spravodlivé pre herné použitie, myslel som si, že by to bol zaujímavý výskum.

Môj pôvodný plán bol spätne analyzovať aplikáciu pre Android a poskytnúť používateľovi a Toast oznámenie o odpovedi. Začal som tým dekompilácia aplikácie a kontrolu zdrojového kódu. Použil som grep na vyhľadávanie niektorých kľúčových slov, o ktorých som dúfal, že mi pomôžu vystopovať aktivitu otázok/odpovedí. Pri prehľadávaní niektorých potenciálnych výsledkov ma upútalo niekoľko riadkov.

 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();

Po kóde "ANSWERS_CHEAT" narážal na skrytý cheat mód v hre. Namiesto toho, aby som znovu objavil koleso, rozhodol som sa zistiť, ako to funguje. Pomocou grep som našiel všetky odkazy na "ANSWERS_CHEAT" reťazec a rýchlo objavil odkaz na skrytú ponuku na hlavnej aktivite dashboardu.

 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);

}

}

Zdá sa, že tento kód zvláda nastavenie možnosti cheat módu, ale stále som nemal prístup k samotnej ponuke. V rámci tej istej aktivity som skontroloval metódu OnCreateOptionsMenu nižšie:

 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);

}

}

Väčšina funkcií cheatového režimu, vrátane skrytej ponuky, vyzerala, že závisí od vrátenej hodnoty com.etermax.tools.f.a.a(). Kód pre túto triedu je uvedený nižšie:

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;

}

}

Zdalo sa, že toto je bod rozhodnutia, ktorý som hľadal. Zmena zadania a = nepravda; do pravda mal povoliť skryté menu. Otvoril som malú reprezentáciu triedy a našiel priradenie booleovského člena.

# 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

Zmenil som riadok 29 (úryvok riadku #7 vyššie) na const/4 v0, 1, ktorý nastavil hodnotu na true. Potom som aplikáciu prekompiloval a nainštaloval. Tlačidlo ponuky potom úspešne odhalilo skryté možnosti nižšie:

"Answer Cheat" sa teraz zdal byť v predvolenom nastavení povolený, takže som spustil novú hru na testovanie. Ako sa očakávalo, hry teraz za otázky pripojili číslo, ktoré označuje index správnej odpovede založený na nule.

Stiahnite si opravený súbor APK tu. Upozorňujeme, že toto slúži len na výskumné účely; Nie som zodpovedný za žiadnu nemorálnu hru!

UPRAVIŤ:APK Mirror

To by malo slúžiť ako dobrý príklad toho, že nie je možné zaručiť súkromie klientskych aplikácií a vývojári by si mali dávať pozor na to, čo je súčasťou ich kompilovaných vydaní.