Как кракнах Trivia Crack

click fraud protection

Trivia Crack е изключително популярна игра както за уеб, така и за мобилни платформи, която донякъде е моделирана след Trivial Pursuit. Това е най-новата мания в социалните игри, позволяваща на потребителите да се състезават срещу своите приятели и непознати в отговорите на въпроси от набор от категории. Въпреки че никога не съм се интересувал особено от игри, жена ми наскоро стана голям фен на Trivia Crack. След като я гледах как играе известно време, реших да я изтегля и да разгледам по-отблизо как е изпълнена.

Започнах с наблюдение на заявките за уеб 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

}

}

Обърнете внимание, че категорията, въпросът, опциите за отговор и ключовете за правилен отговор са включени в отговора. Това означава, че би било лесно да се идентифицира отговорът, когато бъдете помолени в рамките на приложението да измамите играта. Въпреки че не е съвсем етично или справедливо за използване в игри, реших, че ще бъде интересно изследване.

Първоначалният ми план беше да направя обратно инженерство на приложението за Android и да предоставя на потребителя a Тост известие за отговора. Започнах от декомпилиране на приложението и преглед на изходния код. Използвах 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 представянето на класа и намерих присвояването на булевия член.

# 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

Това трябва да послужи като добър пример, че поверителността на клиентското приложение не може да бъде гарантирана и разработчиците трябва да внимават какво е включено в техните компилирани версии.