„Trivia Crack“ yra labai populiarus tiek žiniatinklio, tiek mobiliųjų platformų žaidimas, šiek tiek sukurtas pagal „Trivial Pursuit“. Tai naujausias socialinių žaidimų pamišimas, leidžiantis vartotojams konkuruoti su savo draugais ir nepažįstamais žmonėmis atsakant į įvairių kategorijų klausimus. Nors niekada nesidomėjau žaidimais, mano žmona neseniai tapo didžiule Trivia Crack gerbėja. Kurį laiką stebėjęs, kaip ji vaidina, nusprendžiau jį atsisiųsti ir atidžiau pažvelgti į tai, kaip tai įgyvendinta.
Pradėjau stebėdamas žiniatinklio API užklausas, pateiktas tinkle, naudodamas „Android“ programą. Labai greitai žaidimo metu pastebėjau kažką įdomaus. Atrodė, kad programa gavo kategoriją, klausimą ir atsakymą iš „Trivia Crack“ serverių, kol vartotojas net nepradėjo sukti „kategorijos“ rato.
Toliau pateikiamas atsakymo pavyzdys, kurį programa gauna prieš parodydama šį ekraną:
{"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
}
}
Atkreipkite dėmesį, kad kategorija, klausimas, atsakymų parinktys ir teisingo atsakymo klavišai yra įtraukti į atsakymą. Tai reiškia, kad būtų paprasta nustatyti atsakymą, kai programoje bus paprašyta apgauti žaidimą. Nors tai nėra visiškai etiška ar sąžininga žaidimų naudojimui, maniau, kad tai būtų įdomus tyrimas.
Mano pradinis planas buvo pakeisti „Android“ programą ir suteikti vartotojui a Skrudinta duona pranešimas apie atsakymą. Aš pradėjau nuo dekompiliuojant programą ir peržiūrėti šaltinio kodą. Naudojau grep ieškodamas šaltinio kai kurių raktinių žodžių, kurie, tikėjausi, padės atsekti klausimų / atsakymų veiklą. Ieškant kai kurių galimų rezultatų, mano dėmesį patraukė kelios eilutės.
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();
Po kodu „ANSWERS_CHEAT“ užsiminė apie paslėptą apgaulės režimą žaidime. Užuot išradęs dviratį iš naujo, nusprendžiau išsiaiškinti, kaip jis veikia. Naudodamas grep radau visas nuorodas į "ANSWERS_CHEAT" styga ir greitai atrado a nuoroda į paslėptą meniu pagrindinėje prietaisų skydelio veikloje.
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);
}
}
Atrodė, kad šis kodas tvarko apgaulės režimo parinkties nustatymą, bet vis tiek negalėjau pasiekti paties meniu. Toje pačioje veikloje peržiūrėjau toliau pateiktą OnCreateOptionsMenu metodą:
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);
}
}
Dauguma apgaulės režimo funkcijų, įskaitant paslėptą meniu, atrodė taip, lyg tai priklausytų nuo grąžintos vertės com.etermax.tools.f.a.a(). Šios klasės kodas yra žemiau:
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;
}
}
Atrodė, kad tai buvo sprendimo taškas, kurio aš ieškojau. Užduoties keitimas a = klaidinga; į tiesa turėjo įjungti paslėptą meniu. Atidariau klasės smali atvaizdą ir radau loginio nario užduotį.
# 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
Pakeičiau 29 eilutę (7 fragmento eilutė aukščiau) į const/4 v0, 1, kurie nustatė reikšmę į true. Tada iš naujo sukompiliavau programą ir ją įdiegiau. Tada meniu mygtukas sėkmingai atskleidė toliau pateiktas paslėptas parinktis:
„Atsakymų apgaulė“ dabar atrodė įjungta pagal numatytuosius nustatymus, todėl išbandžiau naują žaidimą. Kaip ir tikėtasi, dabar žaidimai po klausimų pridėjo skaičių, nurodantį teisingo atsakymo indeksą, pagrįstą nuliu.
Atsisiųskite pataisytą APK čia. Atminkite, kad tai tik tyrimo tikslais; Nesu atsakingas už jokį amoralų žaidimą!
REDAGUOTI:APK veidrodis
Tai turėtų būti geras pavyzdys, kad kliento programų privatumas negali būti garantuotas, o kūrėjai turėtų būti atsargūs dėl to, kas įtraukta į jų sudarytus leidimus.