Mobile/Android

Unity기반(il2) 게임 App 분석

pyozzi 2019. 11. 24. 05:52

요즘 재밌고 인기있는 게임들은 대부분 Unity Engine으로 개발되고 있다.

대표적으로 포켓몬Go, 궁수의전설, 거지키우기 등 이 있다.

 

Unity기반의 게임들은 JVM이 아닌 Native에서 코드가 구현되어 실행된다.

JVM단에서는 Native라이브러리를 로드만 해주고, 실질적인 게임기능들은 Native단에 로드된 라이브러리에서 처리된다.

해당 라이브러리들은 '/lib'에 위치하고 있다.

 

Unity게임 개발자들은 컴파일 방식을 'mono'와 'il2cpp' 두 가지 방식 중 선택해서 빌드가 가능한데,

예전에는 대부분 게임들이 Interpreter처리방식으로 속도가 빠른 'mono'를 선호했다.

하지만, 안정성 이슈와 보안적인 부분이 미흡하여 'il2cpp'로 많이 개발되는 추세이다.

 

따라서, 이번 글에서는 il2cpp 방식으로 빌드된 게임 App을 대상으로 기술하려고 한다.

 

[그림1] il2cpp방식 /lib 파일

il2cpp로 빌드된 App은 위 3개의 라이브러리를 포함하고 있다.

JVM에서 libmain.so를 먼저 로드시킨 뒤, libmain.so에서 나머지 라이브러리들을 로드하는 방식으로 진행된다.

 

게임의 실질적인 기능들은 'libil2cpp.so'에 포함되어 있다. 그래서 용량이 크다. (22MB...)

IDA로 열어보면 모든 함수들의 심볼정보가 삭제되어 있는데, 이것이 Unity의 소스코드 난독화 솔루션이다.

 

mono방식이나 il2cpp방식 둘 다 난독화가 적용되지만, il2cpp방식이 Symbol정보를 가져오는 것이 아주 조금 번거롭다.

 


1. il2dumper

역시 세상은 넓고 갓갓은 많다.

 

https://github.com/Perfare/Il2CppDumper/releases

위 링크로 들어가서 파일을 다운받고, 압축을 풀어준다.

 

[그림 2] il2dumper

우리는 il2CppDumper.exe를 사용하면 된다.

usage: il2CppDumper.exe [libil2cpp.so 경로] [global-metadata.dat 경로]

 

global-metadata.dat 파일은 "assets\bin\Data\Managed\Metadata"에 위치해 있다. 

 

[그림 3] Unity Version

그럼 Unity Version을 입력구문이 나온다.

해당 App의 Unity Version은 "assets\bin\Data"에 위치한 파일들에서 얻을 수 있다.

 

[그림 4] Data 파일

위 파일들 아무거나 HxD로 열면 Unity Version정보를 얻을 수 있다.

 

[그림 5] Unity Version

해당 App의 Unity Version 정보는 '2018.4'이다.

 

[그림 6] Mode Select

그 다음은 Mode를 선택해주면 되는데, 3번이 개발자가 권장하는 메뉴이다. 3번 선택하자.

 

[그림 7] Dump File

그럼 'DummyDll'폴더와 'dump.cs'파일이 생성되는데, dump.cs에서 모든 함수의 심볼정보를 확인할 수 있다.

[그림 8] dump.cs - Function Symbol

libil2cpp.so에 난독화된 함수들의 Symbol 정보들을 확인할 수 있으며, 각 함수마다의 RVA정보도 확인 가능하다.

Frida에서는 libil2cpp.so의 Base주소 + Target함수의 RVA로 후킹 포인트를 잡을 수 있다.

 

[그림 9] DummyDll

DummyDll폴더에는 이것저것 DLL파일들이 많은데, Symbol에 대한 정보는 'Assembly-CSharp.dll'에 존재한다.

 

dnSpy툴을 이용하면 보기 편하다. ( https://github.com/0xd4d/dnSpy )

 

[그림 10] dnSpy_Assmbly-CSharp.dll

Assembly-CSharp.dll에서는 dump.cs보다 좀 더 분석적인 확인이 가능하다.

 

이제 위 정보들을 활용하여서 후킹할 메소드를 찾아서 포인트를 잡으면 된다.

 

Ref. https://blog.naver.com/PostView.nhn?blogId=linears_&logNo=221395979775&parentCategoryNo=&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView