Cómo descifré Trivia Crack

click fraud protection

Trivia Crack es un juego muy popular para plataformas web y móviles que sigue el modelo de Trivial Pursuit. Es la última moda en los juegos sociales, que permite a los usuarios competir contra amigos y extraños respondiendo preguntas de una variedad de categorías. Aunque nunca me han interesado mucho los juegos, mi esposa recientemente se ha convertido en una gran fanática de Trivia Crack. Después de verla jugar por un tiempo, decidí descargarlo y observar más de cerca cómo se implementó.

Comencé monitoreando las solicitudes de API web realizadas a través de la red mientras usaba la aplicación de Android. Muy rápidamente, noté algo interesante durante el funcionamiento del juego. Parecía que la aplicación estaba recibiendo la categoría, pregunta y respuesta de los servidores de Trivia Crack antes de que el usuario comenzara a girar la rueda de "categorías".

A continuación se muestra un ejemplo de respuesta que la aplicación obtiene antes de mostrar esta pantalla:

{ 

"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

}

}

Tenga en cuenta que la categoría, la pregunta, las opciones de respuesta y las claves de respuestas correctas están incluidas en la respuesta. Esto significa que sería sencillo identificar la respuesta cuando se le solicite dentro de la aplicación que haga trampa en el juego. Si bien no es exactamente ético o justo para el uso en juegos, pensé que sería una investigación interesante.

Mi plan inicial era realizar ingeniería inversa en la aplicación de Android y proporcionar al usuario una Tostada notificación de la respuesta. Empecé por descompilando la aplicación y revisando el código fuente. Utilicé grep para buscar en la fuente algunas palabras clave que esperaba que me ayudaran a rastrear la actividad de preguntas y respuestas. Mientras buscaba algunos de los posibles resultados, algunas líneas me llamaron la atención.

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

Siguiendo el código, "ANSWERS_CHEAT" aludía a un modo de trampa oculto en el juego. En lugar de reinventar la rueda, decidí descubrir cómo funcionaba. Usando grep, encontré todas las referencias a "ANSWERS_CHEAT" cadena y rápido descubierto referencia a un menú oculto en la actividad del panel principal.

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

}

}

Este código parecía manejar la configuración de la opción del modo trampa, pero todavía no pude acceder al menú en sí. Dentro de la misma actividad, revisé el método OnCreateOptionsMenu a continuación:

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

}

}

La mayor parte de la funcionalidad del modo trampa, incluido el menú oculto, parecía depender del valor devuelto de com.etermax.tools.f.a.a(). El código para esa clase está a continuación:

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;

}

}

Este parecía ser el punto de decisión que estaba buscando. Cambiando la tarea a = falso;verdadero Debería haber habilitado el menú oculto. Abrí la pequeña representación de la clase y encontré la asignación del miembro booleano.

# 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

Cambié la línea 29 (fragmento de línea n.° 7 arriba) a constante/4 v0, 1, que establece el valor en verdadero. Luego volví a compilar la aplicación y la instalé. Luego, el botón de menú expuso con éxito las opciones ocultas a continuación:

"Answer Cheat" ahora parecía habilitado de forma predeterminada, así que inicié un nuevo juego para probar. Como era de esperar, los juegos ahora añadían un número después de las preguntas, indicando el índice de base cero de la respuesta correcta.

Descargue el APK parcheado aquí. Tenga en cuenta que esto es sólo para fines de investigación; ¡No soy responsable de ningún juego inmoral!

EDITAR:Espejo APK

Esto debería servir como un buen ejemplo de que no se puede garantizar la privacidad de las aplicaciones cliente y que los desarrolladores deben tener cuidado con lo que se incluye en sus versiones compiladas.