Study/Android

frida 라이브러리 덤프

sh711 2025. 3. 12. 01:25

1. 개요

보통 일반적인 안드로이드 어플은 네이티브 라이브러리를 사용한다.

CMake 및 ndk-module을 통해 어플 런타임 중 호출되어 C/C++ 모듈을 사용할 수 있다.

Kotlin에서의 생성자를 통한 라이브러리 호출

//	MainActivity Class

val calculator = Calculator()
//	Calculator Class

companion object {
        init {
            System.loadLibrary("calculator-lib")
        }
    }

 

2. 라이브러리 호출

frida를 통한 로드된 모듈 및 베이스 주소 확인

var modules = Process.enumerateModules();

modules.forEach(module => {
    console.log(module.name + " at " + module.base);
})

 

근데 계산 라이브러리 모듈이 나오지 않는다

 

이유는 libcalculator.so는 코틀린 코드 내 System.loadLibrary에 의해 동적으로 호출되기 때문에 프로세스 시작 지점에서 로드되는 모듈들 사이에서는 로드되지 않는다.

따라서, linker64 모듈에서 호출되는 안드로이드의 dl_open 함수인 android_dlopen_ext 함수에 후킹을 걸어주고 인자(라이브러리 명)가 libcalculator-lib.so 일 경우 hook 함수를 호출하겠다

Interceptor.attach(Module.getExportByName(null, "android_dlopen_ext"), {
    onEnter(args) {
        this.path = Memory.readUtf8String(args[0])
    },
    onLeave(retval) {
        if(/libcalculator-lib.so/i.test(this.path)) {
            const target = this.path.split("/").pop()
            hook(target)
        }
    }
})

function hook(lib) {
    var base = Module.findBaseAddress(lib);
    console.warn(base);
}

libcalculator-lib 라이브러리가 호출되고 베이스 주소가 나왔다

 

3. frida 라이브러리 덤프

일반적인 분석을 할땐 보통 패키지 파일 내 라이브러리가 존재하여 해당 파일만 분석을 진행하면 된다.

 

일반적이지 않은 경우(난독화, 패킹 등)에는 해당 파일만으로 정적 분석을 한다는 것은 불가능에 가깝다.

따라서, 라이브러리가 로드된 시점(어느정도 복호화 및 언패킹이 된 시점)에 frida를 통해 덤프를 수행한 파일을 분석 시 전자보다는 수월한 분석이 가능하다.

//	JavaScript API를 통한 파일 쓰기

function hook(lib) {
    var base = Module.findBaseAddress(lib);
    console.warn(base);

    var memory = Memory.readByteArray(base, 8264);	// 라이브러리 파일 크기 만큼 읽기
    // Memory.protect(base, 8264, "rwx")    //	메모리 보호 권한 변경 필요 시 
    var file = new File("/data/data/[패키지명]/files/dump.so", "wb");	// 권한 부여된 디렉터리
    file.write(memory);
    file.flush();
    file.close();
}

로드 시점에 덤프된 라이브러리 파일 확인 가능 

 

해당 덤프 파일 로컬로 가져온 후 아이다에서 분석