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
}
}
გაითვალისწინეთ კატეგორია, კითხვა, პასუხის ვარიანტები და სწორი პასუხის ღილაკები ყველა შედის პასუხში. ეს ნიშნავს, რომ მარტივი იქნება პასუხის იდენტიფიცირება, როდესაც აპში მოეთხოვებათ თამაშის მოტყუება. მიუხედავად იმისა, რომ არ არის ზუსტად ეთიკური ან სამართლიანი სათამაშო გამოყენებისთვის, ვფიქრობდი, რომ ეს იქნებოდა საინტერესო კვლევა.
ჩემი თავდაპირველი გეგმა იყო ანდროიდის აპის შებრუნებული ინჟინერია და მომხმარებლისთვის მიწოდება სადღეგრძელო პასუხის შეტყობინება. მე დავიწყე აპლიკაციის დეკომპილირება და გადახედეთ წყაროს კოდს. მე გამოვიყენე 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;
}
}
როგორც ჩანს, ეს იყო გადაწყვეტილების წერტილი, რომელსაც ვეძებდი. დავალების შეცვლა a = ყალბი; რომ მართალია უნდა ჩართულიყო ფარული მენიუ. გავხსენი კლასის 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
ეს უნდა იყოს კარგი მაგალითი იმისა, რომ კლიენტის აპლიკაციის კონფიდენციალურობის გარანტია შეუძლებელია და დეველოპერები ფრთხილად უნდა იყვნენ იმის შესახებ, თუ რა შედის მათ შედგენილ რელიზებში.