[Unity][AOS] How to Dump Encrypted global-metadata.dat (2/2)

koo00·2022년 10월 4일
0

암호화 또는 난독화된 global-metadata.dat 파일 추출 방법 두번째 포스팅이다.

이번 포스팅에서는 global-metadata.dat 파일뿐만 아니라 libil2cpp.so 파일도 함께 암호화되어있을 때 복호화 및 덤프하는 방법에 대해 다룰 것이다.

참고로 첫번째 포스팅에서 다뤘던 보안 솔루션과는 다른 솔루션이며 프리다 탐지, 메모리 스캔 및 후킹 탐지를 우회해야 가능하다.


먼저 apk 파일의 lib 폴더에 있는 libil2cpp.so 파일을 열어보면 암호화되어있다.

그리고 assets/bin/Data/Managed/Metadata 폴더에 있는 global-metadata.dat 파일도 암호화되어 있다.

복호화 과정이 어떻게 되는지는 능력 부족으로 파악하지 못했으나 게임이 정상 실행되려면 무조건 원본 libil2cpp.so 파일과 global-metadata.dat 파일을 로드하는 과정이 필요하다.

따라서 원본 파일을 얻기 위해 게임이 정상 실행된 이후 덤프한다.

먼저 원본 IL2CPP 파일을 얻기 위해 아래의 스크립트는 Frida CLI 에서 실행시켰다.

var module = Process.findModuleByName('libil2cpp.so');
var il2cpp = module.base;
var offset = module.size;
// Memory.protect(il2cpp, offset, 'rwx');
var file = new File('/sdcard/Download/dec_libil2cpp.so', 'wb');
var buf = il2cpp.readByteArray(offset);
file.write(buf);
file.flush();
file.close();


스크립트 실행 전 hexdump 를 통해 덤프할 파일의 포맷이 ELF 인지 확인하고
Base Address 를 기억해두어야 한다. 내가 덤프한 IL2CPP 파일의 Base Address0x745e601000 이다.

덤프가 성공적으로 될 경우 단말기의 Download 폴더에서 dec_libil2cpp.so 파일을 얻을 수 있고 IDA 로 열면 복호화되어 있는 것을 알 수 있다.

이제 LoadMetaDataFile 함수를 찾아야 한다. 먼저 global-metadata.dat 문자열을 검색한다.

xrefs 를 통해 호출 시점을 따라갈 경우 서브 루틴 하나가 나온다. sub_1992C0 서브 루틴이 LoadMetaDataFile 함수라는 것을 알 수 있다.

빠르게 후킹을 걸자.

Interceptor.attach(Module.findExportByName(null, 'dlopen'), {
	onEnter: function(args) {
		this.path = args[0].readUtf8String();
	},
	onLeave: function(retval) {
		if(this.path.indexOf('libil2cpp.so') !== -1) {
			var il2cpp = Module.findBaseAddress('libil2cpp.so');
			console.error('[!] il2cpp : ' + il2cpp);
			var LoadMetaDataFile = il2cpp.add(0x1992C0);
			Interceptor.attach(LoadMetaDataFile, {
				onLeave: function(retval) {
					console.error('[!] LoadMetaDataFile retval : ' + retval);
				}
			});
		}
	}
});


스크립트를 다시 실행시켜 LoadMetaDataFile 함수의 리턴 값을 확인한다. 0x746f09d000global-metadata.dat 의 시작 주소 값이다.

hexdump 로 해당 주소 값을 확인할 경우 global-metadata.dat 파일의 매직 넘버를 확인할 수 있다.

global-metadata.dat 파일의 주소 값을 확인했으니 현재 메모리에서 덤프할 메모리를 확인해준다.

덤프할 크기는 0x163000 이다.

libil2cpp.so 파일 덤프했을 때와 마찬가지로 global-metadata.dat 파일을 덤프해준다.

var metadata = ptr(0x746f09d000);
var offset = 0x163000;

var file = new File('/sdcard/Download/dec_global-metadata.dat', 'wb');
var buf = metadata.readByteArray(offset);
file.write(buf);
file.flush();
file.close();


덤프가 성공적으로 되면 dec_global-metadata.dat 파일의 이름을 global-metadata.dat 파일로 변경시킨 뒤 IL2CPPDumper 를 실행한다.

원래라면 덤프가 되어야 하지만 Input il2cpp dump address or input 0 to force continue: 라는 메시지가 뜬다. 이때 IL2CPP 덤프할 때 기록한 Base Address 를 입력해준다.

0x745e601000 입력 시 덤프가 성공적으로 된다!


IDA 에서 스크립트 로드하면 꺼-억

profile
JFDI !

0개의 댓글