[ 게임 해킹 ] #1 세이브 데이터 변조
by 월루⚠️ 포스팅 시작 전 유의사항!
본 포스팅에서 다루는 모든 행위는 정식 서비스중인 게임이나 제공자가 허가하지 않은 상태에서 진행시 정보통신망법 컴퓨터등 장애 업무방해죄 제 314조 또는 게임산업진흥법 제32조
에 따라 처벌 받을 수 있습니다. 따라서 해당 학습 내용은 게임 동작원리 및 리버싱 학습 용도로만 사용하여야 합니다.
⚙️ 본 포스팅 시작에 앞서 아래의 프로그램이 필요합니다!
- Process Monitor v3.89
- https://docs.microsoft.com/en-us/sysinternals/downloads/procmon
- 실시간 쓰레드 활동을 보여주는 Windows용 고급 모니터링 프로그램
- HxD v2.5.0.0
- https://mh-nexus.de/en/hxd/
- 정적 바이너리 파일 분석 프로그램
- Squally (선택사항)
- https://squallygame.com/
- 게임해킹 연습용 게임 (유료)
- 해킹 학습용으로 개발된 게임이기 때문에 자유롭게 실습 가능
❓ 파일 변조(Hex Editing)란 무엇인가요?
파일 변조는 프로그램의 정적 상태의 바이너리를 분석 및 수정하는것을 말합니다.
흔히 다른 기술인 어셈블리 변조(Assembly editing)와 헷갈리기도 합니다. 사실 의미 자체만 보면 어셈블리 변조도 하나의 파일 변조에 포함됩니다만, 해당 포스팅에서 얘기하는 파일 변조는 단순 데이터로만 구성된 저장 데이터 또는 Config(설정)데이터를 변조하는것을 말합니다. 단순 데이터 변조와 인스트럭션(명령어) 변조는 다르니까요. 난이도 자체도 어셈블리 변조가 훨신 어렵습니다.
🔑 실제 Squally의 세이브 데이터를 찾고 수정해봅시다!
Squally란?
우선 Squally는 CS420이라는 프로젝트의 결과물입니다. CS420은 간단히 말해서 게임 해킹을 누구나 쉽게 공부할 수 있도록 도와주는 튜토리얼을 만든다는 프로젝트입니다. Squally는 스팀 게임이며, 유료이지만 게임 파일을 뜯어보고 수정해도 법적으로 문제가 없습니다(무단 배포 제외). 그래서 해당 포스팅에선 위 게임을 사용하여 실습을 진행해보겠습니다.
세이브 데이터란?
우선 대부분의 게임에서는 게임저장
이라는 기능을 구현합니다. 게임을 껐다 키더라도 혹은 클라우드 저장일 경우 게임을 지웠다가 설치 하더라도, 게임 진행상황을 유지하기 위함입니다. 이런 세이브 데이터들은 로컬 컴퓨터에 설치된 저장장치에 저장되게 됩니다. 다른 저장장치인 레지스터, 메모리, 캐시는 휘발성이거나 데이터가 자주 바뀌기 때문에 세이브 데이터가 위치하기에 옳바르지 않습니다.
가정
만약 게임에서 돈을 5,000원을 가지고 있고, 특정 상점에서 해당 재화를 통해 물건을 살 수 있다고 가정 해보겠습니다. 게임을 종료하기전 게임에선 돈에 해당되는 데이터 부터, 캐릭터 위치, 필요시 체력이나 기타 진행상황을 저장하게 됩니다. 만약 이 파일을 찾고, 수정할 수 있다면 캐릭터의 체력이나 돈을 원하는 값으로 바꿀 수 있지 않을까요?
실행
[ 세이브 데이터 위치 찾기 ]
- 세이브 데이터가 저장되는 위치를 찾는 방법은 다양합니다.
- 게임 파일 전부 확인하며 찾아보기 (비효율적)
- 구글에 해당 게임 세이브 데이터 위치 검색 (마이너한 게임은 결과 X)
- 게임을 정적 및 동적 분석(리버싱)하며 세이브 및 로드 로직을 파악하여 위치 찾기 (많은 시간)
- 특정 프로세스 모니터링 툴을 이용하여 세이브 지점 확인 (추천)
- ETC...
위 처럼 다양한 방법이 있지만, 가장 확실하고 빠른 방법인 5번을 이용하여 실습을 진행해보겠습니다.
[ 프로세스 모니터링 툴 ]
윈도우에서 프로세스 모니터링 툴은 윈도우에서 특정 프로세스/쓰레드에서 발생하는 윈도우 이벤트(레지스터, 메모리, 파일 쓰기/읽기 등) 모니터링 할 수 있도록 도와주는 툴입니다. 해당 툴을 이용하여 Squally를 필터링하면 Squally에서 발생하는 파일 저장/읽기 이벤트를 상세하게 분석할 수 있습니다!
Squally에서 상점에 들어와봤습니다. 우측 상단에 현재 소지금이 보입니다.
아래에서 AND 아이템을 구매하니 소지금에 1000 -> 458로 변경되었습니다.
변경된 소지금은 게임을 껐다 키더라도 유지됩니다. 아무래도 특정 경로에 세이브 데이터에 해당 데이터가 저장된것 같습니다. 그럼 저장된 데이터를 찾아봅시다.
포스팅 시작전 설치했던 "Process Monitor" 툴을 실행시킵니다.
그 후 필터링에 Squally 프로세스를 넣어보면 위와 같이 Squally에서 윈도우 커널에게 요청했던 여러 이벤트 메시지를 확인할 수 있습니다. 하지만 대부분 특정 리소스 폴더에서 .mp3 즉 음원 파일을 불러오는것을 볼 수 있습니다. 아무래도 Squally에서 실시간으로 리소스 폴더안의 음원 파일을 불러와서 재생시키는것 같습니다. 하지만 우리에겐 필요없는 정보입니다.
필요없는 메시지를 우클릭하면 아래와 같이 해당 메시지를 필터링할 수 있습니다. "ReadFile" 이벤트는 세이브 데이터가 저장될때는 호출되지 않음으로 제외합니다. 그후 필터링된 정보를 조금 스캔해보면
위와 같이 파일을 생성하고, 쓰고, 닫는 이벤트가 호출된것을 볼 수 있습니다. 그리고 해당 파일의 경로도 같이 확인이 가능합니다. 아무래도 경로와 이름을 봤을때 저희가 원하는 "세이브 데이터"가 맞다고 유추가 가능합니다. 그럼 실제로 해당 경로의 폴더로 이동해보겠습니다.
이동한 경로의 폴더에서 Config.txt, Global.sqa 외에 다양한 파일을 볼 수 있습니다. 일단 저희의 목표로 추정되는 "Global.sqa" 파일을 메모장 프로그램으로 열어보겠습니다.
메모장 프로그램에서 데이터를 정상적으로 못 불러오는것을 볼 수 있습니다. 이는 해당 "Global.sqa" 파일이 단순 문자열로 구성된 파일이 아님을 알 수 있습니다. 몇몇 게임에선 세이브 데이터를 JSON이나, XML같은 파싱 과정을 통해 문자열로 데이터를 저장하기도 합니다. 하지만 그렇게 문자열로 데이터를 저장하면 변조가 너무나 쉬워지기 때문에 위 파일처럼 바이너리로 저장하는 경우도 있습니다. (물론 최적화나 기타 이유에서 바이너리 파일로 저장하는 경우도 많습니다.) 우선 해당 바이너리를 파일을 상세하게 분석하기 위해 HxD 툴을 사용해봅시다.
[ 바이너리 파일 분석 툴 ]
컴퓨터의 모든 바이너리 파일은 0과 1로 이루어진 기계어로 작성되어 있습니다. 따라서 사람이 해당 파일을 2진수로 한눈에 보는것은 어렵습니다. 그래서 좋은 바이너리 분석 툴이 필요합니다. 바이너리 분석 툴은 기본적으로 2진수로 작성된 바이너리를 사람이 그나마 보기 쉬운 16진수(Hex)값으로 변환하여 보여줍니다. 또한 특정 바이너리 검색 및 10진수 검색 및 일반 문자열 검색도 지원됨으로 다양한 바이너리 파일의 정적 분석에 많은 도움이 됩니다.
TMI: 왜 기본적으로 10진수가 아닌 16진수(Hex)로 변환하는지는 컴퓨터가 사용하는 2진수와 16진수의 서로의 연관성에 있습니다. 이에 대한 정보는 해당 포스팅에서 다루기엔 다소 많음으로 따로 검색해보시길 추천드립니다.
이제 HxD를 실행 후 "Global.sqa" 파일을 불러와봅시다.
파일에 내용이 그렇게 많지 않고, 바로 "SAVE_KEY_GOLD"라는 문자열이 보입니다. 아무래도 해당 문자열이 저희가 사용한 재화와 관련된 문자열이라고 유추할 수 있습니다.
그 후 바로 뒤 데이터를 INT 크기(4바이트)만큼 확인해보겠습니다. 우측에 "Data Inspector"에서 스캔한 데이터의 10진수 값(Int32)가 2라는것을 알 수 있습니다. 하지만 저희가 위에서 마지막으로 확인했던 금액은 458이였음으로 해당 데이터는 금액 데이터가 아닐 가능성이 높습니다.
바로 다음 Integer 바이트를 읽어보겠습니다. 스캔 후 변환값을 보니 458입니다. 저희가 찾던 데이터가 맞을 가능성이 굉장히 높습니다.
해당 데이터를 저희가 원하는 임의의 숫자 10000으로 수정 후 저장해보겠습니다. (수정 전 꼭 원본 데이터 파일을 백업 해두세요! 혹시나 바이너리를 잘 못 수정하면 복구해야할 수도 있습니다!)
게임을 재시작해보니 저희가 원하는 값으로 수정된것을 볼 수 있습니다.
QNA
Q. 왜 바이너리를 읽을때 4바이트씩 읽었나요?
A. 32/64 bit 운영체제의 PC에서 숫자 데이터를 사용할때 사용하는 대표적인 자료형은 int(Integer)입니다.
평균적으로 int 자료형의 크기는 32 bit(4 byte)이기 때문에 4바이트씩 읽었습니다.
또한 바이너리를 읽을때 문자열 바로 다음으로 [0x02, 0x00, 0x00, 0x00] 바로 뒤에 [0xCA, 0x01, 0x00, 0x00]로 나왔습니다. 따라서 해당 바이너리의 구조만 보고도 충분히 Int형이라고 판단할 수 있습니다. 하지만 이 경우에는 많은 바이너리 파일을 분석하다 보면 생기는 노하우 같은 느낌입니다.
Q. 보통 저장된 데이터가 458이라면 바이너리에는 [0x00, 0x00, 0x01, 0xCA]로 저장될것 같은데 왜 실제로는 [0xCA, 0x01, 0x00, 0x00]으로 데이터가 저장되어 있나요?
A. 이는 바이트 오더링 때문에 발생합니다. 데이터 오더링(엔디언)에 대한 자세한 정보는 아래 다른 포스팅에서 확인하실 수 있습니다.
https://southern-island.tistory.com/29
자, 저희가 원하는 데이터로 수정에 성공하였습니다. 하지만 그래도 아직 찝찝합니다. 만약에 바이너리 데이터에 재화를 뜻하는 문자열이 없었다면 어떻게 찾아서 수정해야 할까요? 사실 이 경우도 아무런 문제가 없습니다. 바로 세이브 데이터에서 저희가 마지막으로 저장했던 재화 데이터의 값을 바이너리에서 검색하면 되기 때문입니다. 한번 실제로 마지막 데이터였던 458(10진수)를 검색해보겠습니다.
HxD의 10진수 데이터 검색 기능을 통해 쉽게 검색이 가능했습니다.
⚰️ 파일 변조의 한계
- 수정할 수 있는 데이터가 한정적입니다. (돈, 체력, 진행상황 등)
- 만약 파일이 암호화되어 있거나, 세이브 시점마다 파일 구조가 달라지면 변조가 힘듭니다.
- 그 외에도 다른 기술들에 비해 한계가 명확합니다.
따라서 실제 인게임 해킹에서는 파일 변조는 많이 사용하지 않습니다. 그럼 이번시간에 배운 내용이 아무런 필요가 없는 내용인가? 그건 아닙니다. 해당 파일 변조에서 배운 내용은 추후 메모리 변조나 다른 기술에서도 활용되기 때문에 굉장히 중요한 개념입니다.
🙋 저는 정보보안을 공부하는 학생입니다!
- 본 포스팅에서 다루는 모든 내용은 학습한 내용을 정리해둔것이기 때문에 오류가 있을 수 있습니다
- 오류나 기타 지적사항이 있으시다면 댓글로 말씀해주시면 공부에 더 많은 도움이 됩니다!
'정보보안 > Game Hacking' 카테고리의 다른 글
[ 게임해킹 ] #0 게임해킹 개요 (0) | 2022.04.02 |
---|
블로그의 정보
남쪽의 외딴섬
월루