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();
}
로드 시점에 덤프된 라이브러리 파일 확인 가능

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