Hvordan jeg knakk Trivia Crack

click fraud protection

Trivia Crack er et svært populært spill for både nett- og mobilplattformer som er litt modellert etter Trivial Pursuit. Det er den siste mani i sosial spilling, som lar brukere konkurrere mot venner og fremmede når de svarer på spørsmål fra en rekke kategorier. Selv om jeg aldri har vært veldig interessert i spill, har min kone nylig blitt en stor fan av Trivia Crack. Etter å ha sett henne spille en stund, bestemte jeg meg for å laste den ned og se nærmere på hvordan den ble implementert.

Jeg begynte med å overvåke web-API-forespørslene som ble gjort over nettverket mens jeg brukte Android-appen. Veldig raskt la jeg merke til noe interessant under spillets operasjon. Det så ut til at appen mottok kategorien, spørsmålet og svaret fra Trivia Crack-serverne før brukeren i det hele tatt begynte å snurre på "kategori"-hjulet.

Nedenfor er et eksempelsvar som appen henter før den viser denne skjermen:

{ 

"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

}

}

Merk at kategorien, spørsmålet, svaralternativene og riktige svartastene er inkludert i svaret. Dette betyr at det ville være enkelt å identifisere svaret når du blir bedt om å jukse spillet i appen. Selv om det ikke akkurat er etisk eller rettferdig for spillbruk, trodde jeg det ville være interessant forskning.

Min opprinnelige plan var å reversere Android-appen og gi brukeren en Skål melding om svaret. Jeg begynte med dekompilere appen og gjennomgå kildekoden. Jeg brukte grep for å søke i kilden etter noen nøkkelord som jeg håpet ville hjelpe meg med å spore opp spørsmål/svar-aktiviteten. Mens jeg søkte gjennom noen av de potensielle resultatene, fanget noen linjer oppmerksomheten min.

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

Etter koden hentydet "ANSWERS_CHEAT" til en skjult juksemodus i spillet. I stedet for å finne opp hjulet på nytt, bestemte jeg meg for å finne ut hvordan det fungerte. Ved å bruke grep fant jeg alle referanser til "ANSWERS_CHEAT" streng og raskt oppdaget en referanse til en skjult meny på hoveddashbordaktiviteten.

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

}

}

Denne koden så ut til å håndtere innstillingen av juksemodus-alternativet, men jeg fikk fortsatt ikke tilgang til selve menyen. Innenfor den samme aktiviteten gjennomgikk jeg OnCreateOptionsMenu-metoden nedenfor:

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

}

}

Det meste av juksemodusfunksjonaliteten, inkludert den skjulte menyen, så ut som den var avhengig av den returnerte verdien til com.etermax.tools.f.a.a(). Koden for den klassen er nedenfor:

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;

}

}

Dette så ut til å være beslutningspunktet jeg var ute etter. Endre oppdraget a = usann; til ekte burde ha aktivert den skjulte menyen. Jeg åpnet smali-representasjonen av klassen og fant oppgaven til det boolske medlemmet.

# 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

Jeg endret linje 29 (snuttlinje #7 ovenfor) til const/4 v0, 1, som satte verdien til sann. Jeg kompilerte deretter appen på nytt og installerte den. Menyknappen avslørte deretter de skjulte alternativene nedenfor:

"Answer Cheat" virket nå aktivert som standard, så jeg startet opp et nytt spill for å teste. Som forventet har spillene nå lagt til et tall etter spørsmålene, som indikerer den nullbaserte indeksen for det riktige svaret.

Last ned den oppdaterte APK her. Merk at dette kun er for forskningsformål; Jeg er ikke ansvarlig for noe umoralsk spilling!

REDIGERE:APK-speil

Dette bør tjene som et godt eksempel på at personvern for klientapplikasjoner ikke kan garanteres, og utviklere bør være forsiktige med hva som er inkludert i deres kompilerte utgivelser.