안드로이드 게임 해킹 - 게임 코드 변조 上

'보안 솔루션이 적용된 유니티 기반의 안드로이드 게임에서의 게임 코드 변조'를 다루기 전에 먼저, '보안 솔루션이 적용되지 않은 유니티 기반의 안드로이드 게임에서의 게임 코드 변조'를 먼저 다루고자 한다. 우선 그림 1을 보면서 유니티 기반의 안드로이드 게임이 어떻게 만들어지고, 배포되고, 실행되는지부터 알아보도록 하자.

(본 장에서는 Mono 기반의 유니티 만을 다룹니다. IL2CPP 기반의 유니티는 다루지 않습니다)


유니티 기반의 안드로이드 게임이 만들어지고, 배포되고, 실행되는 방식



그림 1. 유니티 기반의 안드로이드 게임이 만들어지고, 배포되고, 실행되는 방식


① 유니티 기반의 게임은 C# 언어로 작성된다.


② 작성된 C# 파일들은 하나의 DLL 파일로 컴파일된 후, 배포된다.


작성된 C# 파일들은 '하나'의 플랫폼 독립적인 DLL 파일로 컴파일된 후, 모든 유저에게 배포된다. 다시 말해, 각 유저의 실행 환경에 맞게 여러 버전의 DLL 파일들을 만들어서 배포하는 것이 아닌, 단 '하나'의 플랫폼 독립적인 DLL 파일을 만들어서 배포한다. 이를 위해 DLL 파일은 우리가 일반적으로 알고 있는 DLL 파일들처럼 x86 instruction 이나 ARM instruction 으로 구성되는 게 아닌, CIL(Common Intermediate Language) 로 구성되어 실행 환경에 관계없이 모든 플랫폼에서 동작하게 된다. 즉, 배포되는 DLL 파일은 네이티브 언어가 아닌 중간 언어로 구성되어있기 때문에 c나 c++로 작성된 파일들보다 디컴파일이 쉬운 편이다. 이렇게 배포되는 DLL 파일을 Managed DLL(또는 .NET DLL) 이라고 부르기도 한다. 좀 더 자세한 내용을 알고 싶다면 이를 키워드로 검색해보거나 아래 링크를 참조바란다.

https://support.microsoft.com/en-us/help/815065/what-is-a-dll

https://msdn.microsoft.com/ko-kr/library/windows/desktop/bb318664(v=vs.85).aspx


③ 배포된 DLL 파일은 유니티 엔진 위에서 실행된다.


만약 위 과정들이 잘 이해가 가지 않는다면, 자바에서 코드가 컴파일되고, 실행되는 과정을 생각해보라. 자바 또한 C#과 비슷하게 '하나'의 플랫폼 독립적인 class 파일을 만들고, 해당 class 파일이 JVM(Java Virtual Machine) 위에서 동작하는 방식이다.


DLL 디컴파일, 코드 변조


위에서 말했다시피 Managed DLL 파일은 일반 DLL 파일과 달리 CIL(Common Intermediate Lanague), 즉 중간 언어로 구성되어서 디컴파일이 아주 쉽다. 이미 시중에도 무료로 사용할 수 있는 디컴파일 툴들이 많이 나와있는데, 나는 dnSpy 라는 툴을 사용하고 있다. 이 툴을 이용해서 디컴파일을 하고, 게임 코드를 바꾸는 과정을 간략하게 설명하겠다.



그림 2. dnSpy를 이용한 DLL 디컴파일


위 그림 2는 dnSpy를 이용하여 특정 게임에 있는 DLL 파일을 디컴파일 한 모습이다. 아주 깔끔하게 디컴파일되어 원본과 가까운 게임 소스 코드가 노출된 것을 볼 수 있다.


그림 3. dnSpy를 이용한 코드 변조


위 그림 3은 dnSpy를 이용하여 DLL 파일 내의 코드를 변조하는 모습이다. 그림 3처럼 C#을 사용해서 변조할 수도 있고, CIL(Common Intermediate Language)를 사용해 변조할 수도 있다. 그리고 이렇게 변조된 DLL 파일을 원본 DLL 파일과 바꿔치기 하는 식으로, 손쉽게 게임 코드를 변조할 수 있다.

(DLL 파일의 경로는 apk/assets/bin/Data/Managed/Assembly-CSharp.dll 이다)