처음에는 프리다 CLI를 통해 자바스크립트 코드를 앱 프로세스에 인젝션했지만, 이는 코드를 재활용하기 불편하여 자바스크립트 파일을 생성해서 이를 로드하여 인젝션하는 방법을 사용해보았다. 이번에는 파이썬 코드에 자바스크립트 코드를 삽입하여 프리다로 앱에 접근한 뒤 자바스크립트를 인젝션하는 과정까지를 자동화 해보자. 파이썬 실행으로 아래와 같은 기능을 할 수 있다.
# frida, sys 모듈 임포트
import frida, sys
# 삽입할 자바스크립트 코드 넣기
jscode = """payload_code"""
# frida를 시작하고 USB 장치에서 com.your.package.name 프로세스 연결
session = frida.get_usb_device().attach("com.your.package.name")
# jscode에 있는 스크립트 코드를 frida에서 사용할 수 있도록 생성
script = session.create_script(jscode)
# 생성한 script를 로드
script.load()
# script가 동작하기 전에 종료되는 문제 방지
sys.stdin.read()
# frida, sys 모듈 임포트
import frida, sys
# 삽입할 자바스크립트 코드 넣기
jscode = """payload_code"""
# frida를 시작하고 USB 장치에 연결
device = frida.get_usb_device()
# 연결된 USB 장치에서 com.your.package.name 프로세스 생성
pid = device.spawn(["com.your.package.name"])
# com.your.package.name 프로세스 연결
session = device.attach(pid)
# jscode에 있는 스크립트 코드를 frida에서 사용할 수 있도록 생성
script = session.create_script(jscode)
# 생성한 script를 로드
script.load()
# com.your.package.name 프로세스 메인 스레드 실행
device.resume(pid)
# script가 동작하기 전에 종료되는 문제 방지
sys.stdin.read()
이전에 android.app.Activity 클래스의 onResume 함수를 덮어쓰는 인젝션 코드를 파이썬 바인딩 파일로 만들어보자.
# onresume.py
import frida, sys
jscode = """
console.log("[*] Starting onResume script");
Java.perform(function() {
var Activity = Java.use("android.app.Activity");
Activity.onResume.implementation = function() {
console.log("[*] onResume() got called!");
this.onResume();
};
})
"""
session = frida.get_usb_device().attach("com.android.chrome") # 크롬 앱 프로세스에 연결
script = session.create_script(jscode) # 삽입할 자바스크립트 코드 생성
script.load() # 생성한 스크립트 로드
sys.stdin.read() # 스크립트 삽입 전 종료되는 문제 방지
지금까지 console.log
를 사용하여 로그를 출력했는데, 자바스크립트 객체 message를 전송하여 콜백 함수를 통해 원하는 메세지만 출력할 수 있도록 설정할 수 있다.
send(message [,data])
프리다 기반 애플리케이션에 자바스크립트 객체 message 전송script.on('message', on_message)
프리다 스크립트에서 보낸 메세지를 처리할 콜백 함수(on_message)를 설정on_message(message, data)
script.on('message', on_message)에서 등록한 콜백 함수에 대한 정의
# onresume.py
import frida, sys
def on_message(message, data):
print(message)
jscode = """
console.log("[*] Starting onResume script");
Java.perform(function() {
var Activity = Java.use("android.app.Activity");
Activity.onResume.implementation = function() {
send("[*] onResume() got called!"); // console.log 대신 send 함수 사용
this.onResume();
};
})
"""
session = frida.get_usb_device().attach("com.android.chrome")
script = session.create_script(jscode)
script.on('message', on_message) # 스크립트에서 보낸 메세지를 처리할 콜백 함수 설정
script.load()
sys.stdin.read()
onResume()
가 호출되면 json 객체에 payload
키에 해당하는 값에 send
함수를 통해 보낸 메세지가 저장되고, type
키 값에는 send
라는 값이 저장되어 있다. 이 json 객체를 이용하여 type
키 값이 send
인 메세지만 출력할 수 있도록 처리할 수 있다.
# onresume.py
import frida, sys
def on_message(message, data):
if message['type'] == 'send':
print(message['payload'])
else:
print(message)
jscode = """
console.log("[*] Starting onResume script");
Java.perform(function() {
var Activity = Java.use("android.app.Activity");
Activity.onResume.implementation = function() {
send("[*] onResume() got called!"); // console.log 대신 send 함수 사용
this.onResume();
};
})
"""