Trivia Crack هي لعبة شائعة جدًا لكل من منصات الويب والهواتف المحمولة والتي تم تصميمها إلى حد ما على غرار Trivial Pursuit. إنها أحدث جنون في الألعاب الاجتماعية، مما يسمح للمستخدمين بالتنافس ضد أصدقائهم والغرباء في الإجابة على الأسئلة من مجموعة من الفئات. على الرغم من أنني لم أكن أبدًا مهتمًا جدًا بالألعاب، إلا أن زوجتي أصبحت مؤخرًا من أشد المعجبين بـ Trivia Crack. بعد مشاهدتها وهي تلعب لفترة من الوقت، قررت تنزيله وإلقاء نظرة فاحصة على كيفية تنفيذه.
لقد بدأت بمراقبة طلبات واجهة برمجة تطبيقات الويب التي يتم إجراؤها عبر الشبكة أثناء استخدام تطبيق 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 وتزويد المستخدم بـ خبز محمص إشعار الجواب. لقد بدأت بها فك التطبيق ومراجعة الكود المصدري. لقد استخدمت 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 أعلاه) إلى ثابت/4 v0, 1، الذي قام بتعيين القيمة إلى true. ثم قمت بإعادة ترجمة التطبيق وتثبيته. نجح زر القائمة في الكشف عن الخيارات المخفية أدناه:
يبدو الآن أن "الإجابة على الغش" ممكنة افتراضيًا، لذلك بدأت لعبة جديدة للاختبار. وكما هو متوقع، قامت الألعاب الآن بإلحاق رقم بعد الأسئلة، يشير إلى المؤشر الصفري للإجابة الصحيحة.
قم بتنزيل APK المصحح هنا. لاحظ أن هذا لأغراض البحث فقط؛ أنا لست مسؤولاً عن أي لعبة غير أخلاقية!
يحرر:مرآة APK
يجب أن يكون هذا بمثابة مثال جيد على أنه لا يمكن ضمان خصوصية تطبيق العميل ويجب على المطورين توخي الحذر بشأن ما تم تضمينه في إصداراتهم المجمعة.