APP 진단/Android 2

8. 프리다 연습 - FridaLab (2) 문제 풀이 (1-5번)

takudaddy 2022. 12. 11. 00:34

 

 

 

 

[목차]

 

 

1. Change class challenge_01's variable 'chall01' to 1

2. Run chall02()

3. Make chall03() return true

4. Send "frida" to chall04()

5. Always send "frida" to chall05()

 

 


 

 

1. Change class challenge_01's variable 'chall01' to 1

> 클래스 challenge_01의 변수 chall01을 1로 변경하기

 

 

(1) challenge_01 클래스 소스 확인

 

 

클래스 내

chall01라는 변수를 1로 변경하면

getChall01Int라는 메서드가 실행되면서

chall01이라는 값이 1로 리턴되는 구조!

 

문제 해결을 위해 간단히

getChall01Int 함수(메서드)의

리턴 값을 변경해도 문제는 풀리는데

 

문제의 의도는 challenge_01 클래스의

변숫값을 변경하는 것이기 때문에

정석대로 풀어본다.

 

 

 

(2) 변조할 변수가 포함되어 있는 클래스 명 확인

 

> uk.rossmarks.fridalab.challenge_01

 

 

 

(3) 코드 작성

setImmediate(function(){
	Java.perform(function(){
		var chall_01 = Java.use("uk.rossmarks.fridalab.challenge_01"); // static 메서드를 찾을때는 Java.use API
		chall_01.chall01.value = 1;  // value라는 property(속성 : 자바스크립트에서 객체 내부의 속성을 뜻함)를 사용해 변수값을 변경해준다.
		console.log("[+] Challenge_01 변수 값이 1로 변경되었습니다!");
	})
})
 

 

 

 

> 돌려주면

 

해결 완료!

 

 


 

 

2. Run chall02()

> Chall02() 메서드 실행하기

 

해당 메서드는

다른 곳에서는 사용되지 않는 메서드이며

프리다를 통해서만 실행할 수 있다.

 

 

 

(1) jadx로 문자 검색

네비게이션 > 텍스트 검색 (Ctrl + Shift + f)

 

chall02() 메서드는

​MainActiviry라는 클래스 내 있음

 

 

 

소스를 살펴보면

 

chall02라는 메서드를 호출 하면서

첫 번째 배열 값(배열이니 실제는 두 번째)이

1로 세팅이 되면 해당 문제가 풀린다.

 

 

 

 

(2) 메서드 형식 확인 (중요!)

호출할 chall02라는 메서드는

static method가 아닌

instance method이다.

 

static 메서드는 선언을 해줄 때

static을 붙여주는데 없기 때문에

instance method로 볼 수 있고

 

instance 메서드를 호출하기 위해서는

instance화 된 객체를 찾아 사용해야 한다.

 

instance화 된 객체를 찾을때는

Java.choose 라는 API 함수를 사용한다.

(static 메서드는 Java.use - 1번 문제)

 

 

 

 

(3) 코드 작성

setImmediate(function(){
	Java.perform(function(){
		var chall_02 = Java.choose("uk.rossmarks.fridalab.MainActivity",{
			"onMatch" : function(chall_02){  // onMatch 따옴표로 안 묶어도 됨! MainActivity에 대한 인스턴스를 chall_02(이름은 상관없음)으로 받아
				chall_02.chall02();          // 매칭이 되면 chall_02(MainActivity에 대한 instance)의 chall02 함수를 호출하겠다!
			},
			"onComplete" : function() {  // onComplete 따옴표로 안 묶어도 됨!
				console.log("\n[+] 2번 문제 해결 완료!");
			}			
		})
	})
})
 

 

> 돌려보면

 

해결 완료!

 

 

 

 

 

​[+] 참고로

instance 메서드를 Java.use로 호출하면

setImmediate(function(){
	Java.perform(function(){
		var instance_call_test = Java.use("uk.rossmarks.fridalab.MainActivity")
			instance_call_test.chall02();
	})
})
 
 

 

instance 메서드를 불러올 수 없다며

에러가 발생한다!

 

static / instance

메서드를 잘 구분해서 사용하자!

 

 

 


 

 

 

3. Make chall03() return true

> chall03() 메서드가 true 반환하게 만들기

: 함수에서 반환 값을 수정(implementation)하는 문제!

 

 

(1) 메서드 검색 후 소스 분석

 

 

MainActivity 클래스 내 chall03 메서드

리턴 값을 true로 바꾸면 됨!

 

 

 

[+] 메서드 관련!

본 문제는 chall03() 메서드를

호출하는 것이 아닌

반환 값만 변경하는 문제이며

 

호출은 MainActivity에서 하기 때문에

static 명시가 없어도 Java.use API

사용이 가능하다!

 

문제 풀이와 관계없이 chall03() 메서드를

직접 호출하고 싶을때는 해당 메서드가

static으로 선언된 메서드가 아니기 때문에

Java.choose를 사용해야 한다.

 

 

 

 

(2) 코드 작성

setImmediate(function(){
	Java.perform(function(){
		var chall_03 = Java.use("uk.rossmarks.fridalab.MainActivity");
		chall_03.chall03.implementation = function(){
			console.log("\n[+] 3번 문제 해결!");
			return true;
		}
	})
})
 

돌린 후 앱에서 CHECK 버튼을 눌러 실행시키면

 

해결 완료!

 

 

 

 

 

4. Send "frida" to chall04()

> chall04() 메서드에 frida 문자열 전송하기

: 함수에 전달되는 인수 값 수정 후 전송 (일회성)

 

(1) 메서드 검색 후 분석

 

 

 

인자 값으로 string을 받는데

입력된 값이 frida 면 문제가 해결!

 

chall04라는 메서드를 호출할때

인자값으로 frida라는 문자열을

넣어주면 된다!

 

해당 함수는 static이라는 명시가 없기 때문에

Java.choose API를 사용한다.

 

 

 

 

(2) 코드 작성

setImmediate(function(){
	Java.perform(function(){
		Java.choose("uk.rossmarks.fridalab.MainActivity", {
			onMatch : function(chall_04){  // 인수 값 명 chall_04는 자유롭게 작성! MainActivity instance가 chall_04에 들어간다!
				console.log("\n[+] frida string을 보냅니다!")
				chall_04.chall04("frida"); // 넘겨줄 인자값이 없으면 (), 지금은 있기 때문에 지정을 해줬다
			},
			onComplete : function() {
				console.log("\n[+] 4번 문제 해결!!");
			}
		})
	})
})
 

 

해결 완료!

 

 

 

 

 

5. Always send "frida" to chall05()

> chall05() 메서드에 frida 문자열 항상 전송하기

 

: 4번 문제는 frida라는 문자열을

한 번이라도 전송하면 문제가 해결되었지만

해당 문제는 항상 전송이 되어야 한다!

 

​​

 

 

(1) 소스 확인

 

4번과 로직은 동일한데

else 문이 추가되면서

한 번이라도 전송이 안되면

다시 0(빨간색)으로 돌아온다!

 

MainActivity 클래스의 객체를 받아와

chall05 메서드를 재작성 해주면 되는데

 

this.chall05() API를 사용하여

기존의 chall05 메서드가 가진 행위를

하게 하면서 해당 인자 값에

우리가 원하는 문자열을 넣어준다.

 

한 마디로 내부 로직은 기존에 짜여진 대로

정상적으로 타게 하면서 chall05 메서드가

실행될때마다 우리가 임의로 넣어준

인자 값 frida가 들어가도록 세팅!

 

 

인스턴스를 사용하는 것이 아닌

기존의 메서드(함수)를 재작성 하는

것이기 때문에 Java.use를 사용한다!

 

 

 

 

(2) 코드 작성

 

[+] overload() 함수 사용 설명

우선 자바 오버로딩 개념을 이해해야 한다.

 

"자바 오버로딩"이란

클래스 내에 같은 이름을 가진 메서드가 여럿 존재하고

각 메서드마다 서로 다른 매개변수를 가지고 있는

메서드를 정의하는 것으로

 

만약

A라는 클래스 내에 B라는 이름을 가진 메서드

3개가 아래와 같이 존재한다고 가정하면

 

1>> B(String str)

2>> B(String str, int num)

3>> B(int num1, int num2)

 

이름이 같은 3개의 메서드를

각각 호출하기 위해선 매개변수로

구분하여 호출이 가능하다.

 

이번에 사용하는 overload() 함수의 경우

overload("java.lang.String")로 지정하면

첫 번째 메서드가 호출이 되고

overload("java.lang.String", "int")로 지정하면

두 번째 메서드가 호출되는데

 

본 문제에서 chall05 메서드는

MainActivity 클래스 내에 한 개만 존재하므로

위에서 다룬 방법으로 호출하지 않더라도 가능하지만

 

단순히 overload()를 사용해 보기 위해

연습용으로 넣어본다.

 

정리하면

chall05 이름을 가진 메서드는

MainActivity 클래스 내에 한 개만 존재하므로

chall_05.chall05().overload("java.lang.String").implementation = function(arg) {}

또는

chall_05.chall05().implementation = function(arg) {}

로 작성 가능하다.

 

setImmediate(function(){
	Java.perform(function(){
		var chall_05 = Java.use("uk.rossmarks.fridalab.MainActivity");
		chall_05.chall05.overload("java.lang.String").implementation = function(arg){  // overload 개념 사용 + 인자 값 받는 것이 있으니 arg 사용!
			this.chall05("frida");
			console.log("\n[+] 05번 문제 해결!")
		}
	})
})
 

 

 

 

CHECK 버튼 누를 때마다

해결 완료!

 

728x90