Android Runtime Hooking

resur's blog·2023년 8월 25일
0

Frida

목록 보기
2/2

🌭 Intro


Frida의 Java API로 제공되는 java.choose()는 Java 힙에서 특정 클래스의 인스턴스를 열거하려는 경우 사용되는데, 이 API는 런타임에서 특정 클래스의 현재 인스턴스를 찾거나 분석하려는 경우 매우 유용합니다.
해당 API 사용 시 클래스 이름과 콜백 두 가지 파라메터가 필요한데, 주요 콜백은 onMatchonComplete 두 가지 함수가 포함되어 있습니다.

🍟 onMatch


사용 목적

onMatch 콜백은 java.choose()가 힙을 스캔하면서 해당 클래스의 각 인스턴스를 찾을 때마다 호출됩니다. 찾은 인스턴스에 대한 참조가 인자로 들어가며, 인스턴스를 분석하거나, 해당 인스턴스에 대한 작업을 수행하거나, 참조를 저장하는 등의 작업을 수행하기 위해 사용됩니다.

사용 예시

필드 값 접근

  • 객체 인스턴스의 공개된 필드 값을 직접 읽을 수 있습니다.
onMatch: function(instance) {
    console.log("Field value: " + instance.someField.value);
}

메서드 호출

  • 객체 인스턴스의 공개된 메서드를 호출할 수 있습니다.
onMatch: function(instance) {
    var result = instance.someMethod();
    console.log("Method result: " + result);
}

인스턴스의 문자열 표현

  • 객체 인스턴스의 toString() 메서드를 이용하여 문자열 표현을 얻을 수 있습니다. 만약 해당 클래스에 toString() 메서드가 오버라이드되어 있다면, 해당 메서드의 결과를 볼 수 있습니다.
onMatch: function(instance) {
    console.log("Instance: " + instance.toString());
}

Instance의 클래스 이름 확인

  • 객체의 클래스 이름을 확인할 수 있습니다.
onMatch: function(instance) {
    console.log("Class name: " + instance.class);
}

🍕 onComplete


모든 인스턴스가 onMatch를 통해 처리된 후에 실행되는 onComplete 콜백은 힙 스캔이 완료되면 호출됩니다. 이는 스캔 작업이 완료되었음을 알리거나, 후속 작업을 실행하기 위해 사용됩니다.

사용목적내용
특정 상태 확인특정 시점에서 특정 클래스의 인스턴스 상태를 확인하려는 경우
앱의 디버깅특정 앱의 특정 클래스 인스턴스가 얼마나 많이 생성되었는지, 혹은 특정 상태인지 확인하려는 경우
후킹 후의 상태 확인다른 메서드를 후킹하고 그 메서드의 호출 결과로 생성된 특정 객체의 상태를 확인하려는 경우

사용 예시

// 타겟 클래스 및 메서드 정의
var MyClass = Java.use('com.example.MyClass');

// 첫 번째 java.choose: 원래의 메서드 구현을 출력
Java.perform(function() {
    Java.choose('com.example.MyClass', {
        onMatch: function(instance) {
            console.log("Before change: " + instance.someMethod());
        },
        onComplete: function() {
            console.log("Finished enumerating instances (Before change)");
            
            // 메서드의 구현 변경
            MyClass.someMethod.implementation = function() {
                return "Changed Value";
            };

            // 두 번째 java.choose: 변경된 메서드의 구현을 출력
            Java.choose('com.example.MyClass', {
                onMatch: function(instance) {
                    console.log("After change: " + instance.someMethod());
                },
                onComplete: function() {
                    console.log("Finished enumerating instances (After change)");
                }
            });
        }
    });
});

이 예시는 java.choose를 사용하여 MyClass의 인스턴스를 먼저 열거하고 someMethod의 원래 값을 출력한 후, 해당 메서드의 구현을 변경하고 다시 java.choose를 사용하여 변경된 값을 출력합니다.

profile
Pentester

0개의 댓글