[Mobile]Frida 사용법&FridaLab1

김민주·2026년 1월 6일

security

목록 보기
6/13
post-thumbnail

FridaLab을 풀려고 하기 Frida 사용법을 몰라 어려웠다. 그래서 Frida 사용법을 정리하고 1번 문제 풀이를 적어보고자 한다.

1. Frida 사용법

https://learn.dreamhack.io/221
드림핵의 Tools: Frida 강의를 참고하여 작성하였다.

Frida의 주요 기능

1. Injection
임의 코드를 애플리케이션에 주입할 수 있다.

2. Interception
특정 함수를 후킹하여 함수의 매개 변수나 반환 값을 수정할 수 있다.

3. Tracing
애플리케이션에서 명령어 레벨의 코드를 추적할 수 있다.

Frida tools

1. frida
앱을 실행하여 frida와 애플리케이션을 연결하고 스크립트를 로드한다.
2. frida-ps
프로세스 목록을 출력한다.
3. frida-trace
함수 호출을 추적한다.
4. frida-ls-devices
연결된 기기 목록을 출력한다.
5. frida-kill
동작중인 프로세스를 종료한다.

Frida options

1-1. frida : Attach

  • -F : 현재 기기의 포그라운드 프로세스에 Frida를 연결한다.
  • -n {PACKAGE NAME}: 앱의 패키지 이름을 통해 연결할 앱에 부착시킨다.
  • -p {PID}: 앱의 프로세스 id를 통해 앱에 부착한다.

1-2. frida : Spawn

  • -f {PACKAGE NAME}: 앱을 일행하고 Frida와 연결한다.

1-3. frida : Load Script

  • -l {SCRIPT}: Frida 스크립트를 로드한다.

2-1. frida-trace : include/exclude

  • -I {MODULE} : 모듈의 모든 함수를 추적한다.
  • -X {MODULE} : 모듈의 모든 함수를 추적에서 제외한다
  • -i {MODULE!FUNCTION} : glob pattern을 이용하여 함수를 추적한다.
  • -x {MODULE!FUNCTION} : glob pattern을 이용하여 함수를 추적에서 제외한다.
  • -a {FUNCTION!offset} : offset을 기반으로 함수를 추적한다.

2-2. frida-trace : logging

  • -d. --decorate : 추적할 함수가 속한 모듈 이름을 함께 기록한다.

2-3. frida-trace : others

  • -O {TEXT FILE} : 명령줄을 텍스트 파일로 입력한다.

3. frida-ls-devices : list

  • 현재 frida를 연결할 수 있는 기기 목록을 출력한다.

4. frida-kill

  • -D {DEVICE-ID} {PID} : 프로세스를 종료한다.

2. 1번 풀이

문제는 다음과 같다.
Change class challenge_01's variable 'chall01' to : 1

우선은 jadx-gui를 이용해서 fridalab.apk 파일을 디컴파일해보자.

다음과 같이 chall01과 관련된 클래스를 발견할 수 있다.
여기서 chall01이라는 변수를 1로 바꿔만 주면 된다.

처음에는 파이썬을 이용해서 코드를 작성하려고 했다.

하지만 인터넷에 있는 코드들을 참고해서 작성한 하단의 코드가 frida 17 이상의 버전에서는 브릿지(?) 라는 걸 사용하지 않으면 작동하지 않는다는 것이다.

https://simnple.tistory.com/14
상단의 블로그에서 확인할 수 있었다.

#1. change class challenge_01's variable 'chall01' to: 1

import frida, sys

#PACKAGE_NAME = "uk.rossmarks.fridalab"
PACKAGE_NAME = "FridaLab"

jscode='''
Java.perform(function (){
    var challenge_01 = Java.use("uk.rossmarks.fridalab.challenge_01");
    challenge_01.chall01.value = 1;
    console.log("chall01 variable changed to 1");
    
})
'''

#메시지 핸들러 함수
def on_message(message, data):
    if message['type'] == 'send':
        print("[*] Message from script:", message['payload'])
    elif message['type'] == 'error':
        print("[!] Error in script:", message['stack'])

try:
    #USB 장치에 연결
    print("[*] Connecting to device...")
    device = frida.get_usb_device(timeout=5)

    #실행중인 프로세스 ID 가져오기
    print(f"[*] Finding process ID for package: {PACKAGE_NAME}")
    processes = device.enumerate_processes()
    pid = next((p.pid for p in processes if p.name == PACKAGE_NAME), None)

    #실행 중인 프로세스가 없다면 종료
    if pid is None:
        print(f"[!] Could not find process with package name: {PACKAGE_NAME}")
        sys.exit(1)

    print(f"[*] Found process ID: {pid}")

    #프로세스에 세션 연결
    print("[*] Attaching to process...")
    session = device.attach(pid)

    #JS 코드 로드
    print("[*] Creating and loading script...")
    script  = session.create_script(jscode)
    script.on('message', on_message) #메시지 핸들러 설정
    script.load()

    print("[*] Hook is running. Press Enter to exit.")
    input()  #사용자 입력 대기

except Exception as e:
    print(f"[!] An error occurred: {e}")

그래서 그냥 쉘에서 바로 시도하였다.
javascript 코드를 작성하여 frida 명령어를 이용하여 실행해줬다.

Java.perform(function (){
    var challenge_01 = Java.use("uk.rossmarks.fridalab.challenge_01");
    challenge_01.chall01.value = 1;
    console.log("chall01 variable changed to 1");
})

그리고 UI로 확인해보니 1단계가 클리어 된 것을 확인할 수 있다.

0개의 댓글