How I Cracked Trivia Crack

Το Trivia Crack είναι ένα εξαιρετικά δημοφιλές παιχνίδι τόσο για πλατφόρμες ιστού όσο και για κινητές συσκευές, το οποίο είναι κάπως διαμορφωμένο σύμφωνα με το Trivial Pursuit. Είναι η πιο πρόσφατη τρέλα στα κοινωνικά παιχνίδια, που επιτρέπει στους χρήστες να ανταγωνίζονται τους φίλους και τους αγνώστους τους απαντώντας σε ερωτήσεις από μια σειρά από κατηγορίες. Αν και ποτέ δεν με ενδιέφερε πολύ το gaming, η σύζυγός μου έγινε πρόσφατα μεγάλη θαυμάστρια του Trivia Crack. Αφού την είδα να παίζει για λίγο, αποφάσισα να το κατεβάσω και να ρίξω μια πιο προσεκτική ματιά στον τρόπο εφαρμογής του.

Ξεκίνησα παρακολουθώντας τα αιτήματα web API που έγιναν μέσω του δικτύου κατά τη χρήση της εφαρμογής Android. Πολύ γρήγορα, παρατήρησα κάτι ενδιαφέρον κατά τη λειτουργία του παιχνιδιού. Φαινόταν ότι η εφαρμογή λάμβανε την κατηγορία, την ερώτηση και την απάντηση από τους διακομιστές του Trivia Crack πριν ακόμη ο χρήστης αρχίσει να περιστρέφει τον τροχό της "κατηγορίας".

Ακολουθεί ένα παράδειγμα απάντησης που ανακτά η εφαρμογή πριν από την εμφάνιση αυτής της οθόνης:

{ 

"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

}

}

Σημειώστε ότι η κατηγορία, η ερώτηση, οι επιλογές απάντησης και τα κλειδιά σωστής απάντησης περιλαμβάνονται στην απάντηση. Αυτό σημαίνει ότι θα ήταν εύκολο να προσδιορίσετε την απάντηση όταν ζητηθεί από την εφαρμογή να εξαπατήσει το παιχνίδι. Αν και δεν είναι ακριβώς ηθικό ή δίκαιο για χρήση gaming, σκέφτηκα ότι θα ήταν ενδιαφέρουσα έρευνα.

Το αρχικό μου σχέδιο ήταν να αναθεωρήσω την εφαρμογή Android και να παρέχω στον χρήστη ένα Τοστ κοινοποίηση της απάντησης. ξεκίνησα από αποσυμπίληση της εφαρμογής και έλεγχος του πηγαίου κώδικα. Χρησιμοποίησα το grep για να αναζητήσω την πηγή για ορισμένες λέξεις-κλειδιά που ήλπιζα ότι θα με βοηθούσαν να εντοπίσω τη δραστηριότητα ερωτήσεων/απαντήσεων. Κατά την αναζήτηση ορισμένων από τα πιθανά αποτελέσματα, μερικές γραμμές τράβηξαν την προσοχή μου.

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

Ακολουθώντας τον κωδικό, το "ANSWERS_CHEAT" παρέπεμπε σε μια κρυφή λειτουργία εξαπάτησης στο παιχνίδι. Αντί να ανακαλύψω ξανά τον τροχό, αποφάσισα να μάθω πώς λειτουργούσε. Χρησιμοποιώντας το grep, βρήκα όλες τις αναφορές στο "ANSWERS_CHEAT" σειρά και γρήγορα ανακαλύφθηκε ένα αναφορά σε ένα κρυφό μενού στην κύρια δραστηριότητα του πίνακα εργαλείων.

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

}

}

Αυτός ο κωδικός φαινόταν να χειρίζεται τη ρύθμιση της επιλογής λειτουργίας εξαπάτησης, αλλά και πάλι δεν μπορούσα να έχω πρόσβαση στο ίδιο το μενού. Μέσα στην ίδια δραστηριότητα, εξέτασα τη μέθοδο 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);

}

}

Οι περισσότερες λειτουργίες της λειτουργίας εξαπάτησης, συμπεριλαμβανομένου του κρυφού μενού, έμοιαζαν σαν να εξαρτώνται από την επιστρεφόμενη τιμή του com.etermax.tools.f.a.a(). Ο κωδικός αυτής της τάξης είναι ο παρακάτω:

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;

}

}

Αυτό φαινόταν να είναι το σημείο απόφασης που έψαχνα. Αλλαγή της ανάθεσης α = ψευδής; προς την αληθής θα έπρεπε να είχε ενεργοποιήσει το κρυφό μενού. Άνοιξα την παράσταση smali της τάξης και βρήκα την ανάθεση του μέλους boolean.

# 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

Άλλαξα τη γραμμή 29 (απόσπασμα γραμμής #7 παραπάνω) σε const/4 v0, 1, το οποίο ορίζει την τιμή σε true. Στη συνέχεια έκανα εκ νέου μεταγλώττιση της εφαρμογής και την εγκατέστησα. Στη συνέχεια, το κουμπί μενού αποκάλυψε με επιτυχία τις παρακάτω κρυφές επιλογές:

Το "Answer Cheat" φαινόταν τώρα ενεργοποιημένο από προεπιλογή, οπότε ξεκίνησα ένα νέο παιχνίδι για δοκιμή. Όπως ήταν αναμενόμενο, τα παιχνίδια προσάρτησαν τώρα έναν αριθμό μετά τις ερωτήσεις, υποδεικνύοντας τον μηδενικό δείκτη της σωστής απάντησης.

Κατεβάστε το επιδιορθωμένο APK εδώ. Σημειώστε ότι αυτό είναι μόνο για ερευνητικούς σκοπούς. Δεν είμαι υπεύθυνος για οποιοδήποτε ανήθικο παιχνίδι!

ΕΠΕΞΕΡΓΑΣΙΑ:APK Mirror

Αυτό θα πρέπει να χρησιμεύσει ως καλό παράδειγμα ότι το απόρρητο της εφαρμογής πελάτη δεν μπορεί να είναι εγγυημένο και οι προγραμματιστές θα πρέπει να είναι προσεκτικοί σχετικά με το τι περιλαμβάνεται στις μεταγλωττισμένες εκδόσεις τους.