본문 바로가기

IT & AI

세이브 파일의 정체를 밝히는 리버스 엔지니어링 실전기

728x90

세이브 파일의 정체를 밝히는 리버스 엔지니어링 실전기

AI 뉴스 썸네일
AI 뉴스 썸네일

게임 세이브 파일을 헥스 에디터로 열어본 적 있어요? 수만 개의 바이트가 나열된 화면에서는 어디가 시간 정보이고 어디가 진행도인지 알 수 없어요. 매직 바이트나 형식 명세가 없는 파일은 바이트만 들여다봐서는 의미를 알기 어려워요. ImHex 개발자가 게임 FEZ의 세이브 파일을 직접 분석하며 이 문제를 푸는 전 과정을 공개했어요. 1

핵심 요약

구분핵심왜 볼 만한가요
개발 도구ImHex Pattern Language로 미지의 바이너리 구조를 정의하고 검증반복 수작업을 구조화된 문서로 바꾸는 방법을 배울 수 있어요
리버스 엔지니어링코드 역컴파일 → 직렬화 순서 추적 → 패턴 작성의 3단계 흐름명세 없는 파일을 다뤄야 하는 상황에 바로 쓸 수 있는 절차예요
실전 사례FEZ 세이브 파일의 시간, 버전, 문자열, 목록, 중첩 객체 해석이론이 아니라 실제 바이트와 비교해가며 확인한 결과예요

1. 명세 없는 파일은 코드에서 답을 찾는다

2012년에 나온 게임 FEZ은 완전히 자체 방식으로 세이브 파일을 만들어요. 파일 안에는 DOT_LOCKED_DOOR_A 같은 평문 문자열이 보여서 압축이나 암호화는 안 된 상태예요. 그런데 파일 시작에 형식을 알려주는 매직 문자열이 없어서 ImHex도 이 파일이 뭔지 자동으로 판별하지 못해요. 1

핵심 발상은 파일 자체가 아니라 파일을 읽고 쓰는 코드를 먼저 보는 거예요. 게임 설치 폴더의 System.Core.dll 같은 파일을 보면 이 게임이 C#으로 작성됐다는 걸 알 수 있고, JetBrains Rider로 바이너리를 원본과 비슷한 코드로 역컴파일할 수 있어요. EasyStorage 라이브러리의 PCSaveDevice 생성자에 "SaveSlot" + index라는 코드가 실제 파일명 SaveSlot2와 정확히 일치해서 저장 처리 위치를 바로 찾아냈어요. 2

저장 코드를 따라가면 파일 구조의 첫 조각이 보여요. PCSaveDevice.Save()는 40,960바이트 크기의 버퍼를 만들고, 첫 값으로 현재 시각을 기록한 뒤 게임 데이터를 쓰고, 남는 공간은 0으로 채워요. 데이터가 버퍼보다 길면 저장 자체가 실패해요.

728x90

2. 발견한 구조를 패턴으로 하나씩 옮긴다

코드에서 확인한 직렬화 순서를 ImHex Pattern Language로 옮기는 작업이 이어져요. 첫 필드는 Windows FILETIME 값이라서 리틀 엔디언 64비트 정수로 읽되, 표준 라이브러리의 FILETIME 타입을 쓰면 숫자를 사람이 읽을 수 있는 시각으로 보여줘요. 2

게임 데이터의 첫 값은 버전 번호예요. 읽기 쪽 코드가 이 값이 6이 아니면 예외를 발생시키기 때문에, 패턴에 조건 검사를 추가하면 호환되지 않는 파일을 패턴 단계에서 바로 거부할 수 있어요. 이렇게 코드에서 확인한 사실 하나하나를 패턴에 반영하면서 실제 바이트와 비교해가는 방식이에요.

특히 흥미로운 부분은 문자열 처리예요. .NET의 BinaryWriter.Write(string)은 문자열의 바이트 길이를 7비트 인코딩 정수로 먼저 기록해요. 각 바이트의 최상위 비트가 뒤에 바이트가 더 있는지 알려주는 방식이라, 이를 패턴으로 표현하면 가변 길이 문자열도 정확히 해석돼요. 값이 있을 때만 기록되는 선택적 객체, 항목 수가 앞에 붙는 목록, 정수로 저장되는 열거형처럼 바이너리 형식에서 자주 만나는 구조도 같은 방식으로 하나씩 정의했어요. 1

왜 중요한가요

완성된 패턴은 끝부분의 패딩을 제외한 모든 바이트를 구조화해 보여줘요. 값을 더블클릭하면 데이터를 직접 수정할 수도 있어요. 분석 결과가 그냥 문서가 아니라 실행 가능한 파일 검증기로 남는 셈이에요. 1

이 글의 가치는 도구 소개가 아니라 절차에 있어요. .NET 프로그램은 Rider, 네이티브 프로그램은 Ghidra나 IDA, JVM 언어는 Recaf처럼 언어에 맞는 역컴파일러를 고르고, 파일 입출력 코드를 찾아 직렬화 순서를 따라간 뒤, 발견한 구조를 패턴으로 옮기고 실제 바이트와 비교하는 흐름이 어떤 파일 형식에도 적용돼요. 게임 세이브 파일처럼 명세가 없는 오래된 데이터를 다뤄야 하거나, 레거시 시스템의 파일 형식을 문서화해야 하는 상황에서 바로 참고할 수 있는 사례예요. 2

참고 자료

  1. ImHex로 미지의 파일 형식 리버스 엔지니어링하기 — GeekNews
  2. Reverse Engineering Unknown File Formats with ImHex — WerWolv 블로그
728x90