내가 Trivia Crack을 크랙한 방법

click fraud protection

Trivia Crack은 Trivial Pursuit를 어느 정도 모델로 한 웹 및 모바일 플랫폼 모두에서 매우 인기 있는 게임입니다. 이는 소셜 게임의 최신 열풍으로, 사용자는 다양한 카테고리의 질문에 답하면서 친구 및 낯선 사람과 경쟁할 수 있습니다. 나는 게임에 그다지 관심이 없었지만 최근 아내는 Trivia Crack의 열렬한 팬이 되었습니다. 한동안 그녀의 플레이를 지켜본 후, 나는 그것을 다운로드하여 그것이 어떻게 구현되었는지 자세히 살펴보기로 결정했습니다.

저는 안드로이드 앱을 사용하면서 네트워크를 통해 이루어진 웹 API 요청을 모니터링하는 것부터 시작했습니다. 아주 빨리, 저는 게임을 진행하는 동안 흥미로운 점을 발견했습니다. 사용자가 "카테고리" 휠을 돌리기 전에 앱이 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;

}

}

이것이 제가 찾던 결정 포인트인 것 같았습니다. 과제 변경 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"가 기본적으로 활성화된 것 같아서 테스트할 새 게임을 시작했습니다. 예상한 대로 이제 게임은 질문 뒤에 숫자를 추가하여 정답의 0부터 시작하는 인덱스를 나타냅니다.

패치된 APK를 다운로드하세요 여기. 이는 연구 목적으로만 사용됩니다. 나는 부도덕한 게임 플레이에 대해 책임을 지지 않습니다!

편집하다:APK 미러

이는 클라이언트 애플리케이션 개인 정보 보호가 보장될 수 없으며 개발자가 컴파일된 릴리스에 포함된 내용에 대해 주의해야 한다는 좋은 예가 될 것입니다.