Kako sem razbil Trivia Crack

Trivia Crack je zelo priljubljena igra za spletne in mobilne platforme, ki je nekoliko oblikovana po Trivial Pursuit. To je zadnja norost v družabnih igrah, ki uporabnikom omogoča, da tekmujejo s prijatelji in neznanci pri odgovarjanju na vprašanja iz vrste kategorij. Čeprav me igranje nikoli ni preveč zanimalo, je moja žena nedavno postala velika oboževalka igre Trivia Crack. Ko sem nekaj časa opazoval njeno igro, sem se odločil, da jo prenesem in si podrobneje ogledam, kako se izvaja.

Začel sem s spremljanjem zahtev spletnega API-ja, izvedenih prek omrežja med uporabo aplikacije za Android. Zelo hitro sem med delovanjem igre opazil nekaj zanimivega. Zdelo se je, da aplikacija prejema kategorijo, vprašanje in odgovor s strežnikov Trivia Crack, še preden je uporabnik sploh začel vrteti kolesce »kategorije«.

Spodaj je primer odgovora, ki ga aplikacija pridobi, preden prikaže ta zaslon:

{ 

"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

}

}

Upoštevajte, da so kategorija, vprašanje, možnosti odgovora in ključi pravilnega odgovora vključeni v odgovor. To pomeni, da bi bilo enostavno prepoznati odgovor, ko bi ga v aplikaciji vprašali, naj goljufa v igri. Čeprav ni ravno etično ali pošteno za uporabo iger, sem mislil, da bo zanimiva raziskava.

Moj prvotni načrt je bil obratni inženiring aplikacije za Android in uporabniku zagotoviti Toast obvestilo o odgovoru. Začel sem z dekompiliranje aplikacije in pregled izvorne kode. Uporabil sem grep za iskanje nekaterih ključnih besed v viru, za katere sem upal, da mi bodo pomagale izslediti dejavnost vprašanj/odgovorov. Med iskanjem po nekaterih možnih rezultatih je mojo pozornost pritegnilo nekaj vrstic.

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

Za kodo je "ANSWERS_CHEAT" namigoval na skriti način goljufanja v igri. Namesto da bi ponovno odkril kolo, sem se odločil ugotoviti, kako deluje. Z uporabo grep sem našel vse sklice na "ANSWERS_CHEAT" vrvica in hitro odkriti sklicevanje na skriti meni na glavni dejavnosti nadzorne plošče.

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

}

}

Videti je bilo, da ta koda obravnava nastavitev možnosti goljufanja, vendar še vedno nisem mogel dostopati do samega menija. Znotraj iste dejavnosti sem pregledal spodnjo metodo 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);

}

}

Večina funkcionalnosti načina goljufanja, vključno s skritim menijem, je bila videti, kot da je odvisna od vrnjene vrednosti com.etermax.tools.f.a.a(). Koda za ta razred je spodaj:

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;

}

}

Zdelo se je, da je to točka odločitve, ki sem jo iskal. Spreminjanje naloge a = napačno; do prav moral bi omogočiti skriti meni. Odprl sem smali predstavitev razreda in našel dodelitev logičnega člana.

# 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

Spremenil sem vrstico 29 (izrezek vrstice #7 zgoraj) v const/4 v0, 1, ki nastavijo vrednost na true. Nato sem znova prevedel aplikacijo in jo namestil. Gumb menija je nato uspešno razkril spodnje skrite možnosti:

»Answer Cheat« se je zdaj zdel privzeto omogočen, zato sem zagnal novo igro za preizkus. Kot je bilo pričakovano, so igre zdaj za vprašanjem dodale številko, ki označuje indeks pravilnega odgovora na osnovi nič.

Prenesite popravljeni APK tukaj. Upoštevajte, da je to samo za raziskovalne namene; Ne odgovarjam za nemoralno igro!

UREDI:APK Mirror

To bi moralo služiti kot dober primer, da zasebnosti odjemalske aplikacije ni mogoče zagotoviti in da morajo razvijalci paziti, kaj je vključeno v njihove prevedene izdaje.