# 1998년 Ultima Online 데모 서버 역공학

> Clean Markdown view of GeekNews topic #29240. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=29240](https://news.hada.io/topic?id=29240)
- GeekNews Markdown: [https://news.hada.io/topic/29240.md](https://news.hada.io/topic/29240.md)
- Type: GN+
- Author: [xguru](https://news.hada.io/@xguru)
- Published: 2026-05-07T07:03:31+09:00
- Updated: 2026-05-07T07:03:31+09:00
- Original source: [draxinar.github.io](https://draxinar.github.io/articles/2026-05-01-uodemo-reverse-engineering.html)
- Points: 1
- Comments: 1

## Topic Body

- [OUO](https://github.com/draxinar/ouo)는 1998년 `Ultima Online` 데모 서버를 완전히 리버스 엔지니어링한 프로젝트로, MSVC x86 바이너리의 약 **5,000개 함수**를 디스어셈블해 휴대 가능한 **C99**로 옮김  
- `UoDemo.exe`는 `Ultima Online: The Second Age` 첫 릴리스에 포함된 독립 실행형 데모였고, 클라이언트와 Windows로 포팅된 전체 서버 코드·데이터를 함께 담고 있었음  
- 각 함수는 원본 바이너리와 명령어 단위로 비교됐으며, 클래스 계층과 vtable 레이아웃을 맞춘 뒤 원본과 같은 제어 흐름·구조체 레이아웃·분기를 유지하도록 수동 변환됨  
- 복원본은 1998년 중반 실제 라이브 `Ultima Online` 서버 코드에 가깝지만, 충돌·오버플로·초기화되지 않은 변수 같은 **안정성 문제**와 스킬 상승·스폰 밀도 같은 **게임플레이 문제**가 태그와 함께 수정돼 있음  
- 원래 데모는 클라이언트 1.25.33만 지원했지만, 복원본은 1.25.30부터 **5.0.9.1**까지의 [클라이언트](https://github.com/draxinar/uoclients)를 암호화 유무와 관계없이 지원하며, 1997~2003년 서버 데이터 파일도 요청 중  
  
---  
  
### 데모 파일의 출처와 범위  
- 각 함수는 원본 바이너리와 명령어 단위로 비교됐으며, 10년에 걸친 간헐적 작업 끝에 최근 LLM 발전으로 마무리할 수 있었음  
- `UoDemo.exe`의 날짜는 **1998-09-02**이며, 서버 데이터는 **1998년 6월 2일** 운영 서버에서 추출된 것이었음  
- 데모용으로 일부 기능이 스텁 처리되고 플레이 가능한 지도는 **Ocllo** 섬으로 줄었지만, 나머지는 1998년 중반 실제 라이브 `Ultima Online`에서 돌던 운영 서버 코드였음  
- `Ultima Online`은 Origin Systems Inc.가 개발한 1997년 MMORPG였고, 상업적으로 성공한 초기 MMORPG 중 하나였음  
- Windows에서 클라이언트가 실행됐고, 서버인 “shards”는 여러 Solaris 머신에서 돌아갔으며 지도는 지역별로 나뉨  
- 데모는 Ocllo 섬에서 드래곤을 죽이는 간단한 퀘스트를 제공했고, 대화, 거래, 전투 등 기본 게임 메커니즘을 둘러볼 수 있게 구성됨  
- 여러 `UO` 서버 에뮬레이터가 이 데모의 일부를 재사용했지만, 지금까지 완전히 역공학한 경우는 없었음  
- `UoDemo.exe`는 Microsoft Visual C++ 5.0, 즉 Visual Studio 97로 컴파일됐고, C++98 이전 방언의 C++를 대상으로 했음  
  
### 역공학 방법  
- ## 디스어셈블과 심볼 추정  
  - 디스어셈블에는 [radare2](https://rada.re/)를 사용함  
  - 심볼 이름은 C++ 심볼이 포함된 실험적 Linux 포트 `UO` 클라이언트 1.25.37에서 유추함  
- ## C99 수동 변환  
  - 각 함수는 원본 바이너리와 같은 제어 흐름, 구조체 레이아웃, 분기를 유지하도록 손으로 C99로 번역됨  
  - 차이가 있는 부분은 데모의 실제 버그 수정 또는 플랫폼 적응이며, 소스에 표시돼 있음  
- ## 검증 방식  
  - C 빌드를 다시 `r2`로 디스어셈블해 원본과 비교함  
  - 두 결과가 일치할 때만 함수가 완료된 것으로 표시됨  
  - 헬퍼 함수는 반복되는 인라인 패턴에만 쓰였고, 헬퍼가 인라인 버전과 같은 코드로 다시 확장될 때만 사용됨  
- ## 클래스 계층 복원  
  - 초기에 가장 중요했던 작업은 클래스 계층을 정확히 맞추는 것이었음  
  - 핵심 계층은 `CEntity (0x10) -> CResourceEntity (0x1C) -> CItem (0x50) -> CContainer (0x5C) -> CMobile (0x37C) -> CPlayer (0x458)`였음  
  - 가상 디스패치는 vtable 슬롯을 통해 이뤄졌고, 예를 들어 `vtable[0x18]`은 `IsPlayer`, `[0xD0]`은 `IsMobile`, `[0xE4]`는 `IsNPC`였음  
  - 이 레이아웃이 확정된 뒤에는 바이너리 대부분을 비교적 직접적으로 번역할 수 있었음  
  
### 복원 결과와 원본과의 차이  
- 결과물은 1998년 `Ultima Online` 서버의 거의 완벽한 복제에 가깝지만, 일부 차이가 있음  
- 원본 코드 대비 충돌, 오버플로, 초기화되지 않은 변수 같은 **안정성 문제**가 수정됨  
- 스킬 상승, fame/notoriety 방향, 스폰 밀도 같은 **게임플레이 문제**도 고쳐짐  
- 각 수정은 소스에 태그가 붙어 있어, `UoDemo.exe`와 비교하는 사람이 무엇이 왜 바뀌었는지 정확히 확인할 수 있음  
- 스폰 시스템과 decay 시스템 같은 일부 기능은 깨져 있었고, 데모 릴리스를 위해 부분적으로 비활성화되거나 스텁 처리됐을 가능성이 있음  
- 해당 기능들의 코드는 남아 있었지만 라이브 호출 지점이 도달하지 않았고, 따로 디컴파일한 뒤 디스패치를 다시 연결하는 것만으로 동작시킬 수 있었음  
- 게임 지도는 Ocllo 섬만 담는 등 일부 데이터가 빠져 있었음  
- 서버 데이터 포맷을 조작하는 전체 도구 모음을 만들었고, 나머지 세계의 문, 표지판, 장식, 텔레포터, 함정, 상자, 스폰 위치를 완전히 재구성함  
  
### 남아 있던 생태계 시스템  
- 은퇴한 유명한 [ecology system](https://www.youtube.com/watch?v=KFNxJVTJleE)은 함수 호출이 끊긴 상태였지만 코드 안에 여전히 남아 있었음  
- 포식자, 먹이, 청소동물 시스템을 다시 연결해 늑대가 토끼를 쫓거나 까마귀가 아이템을 먹는 모습을 볼 수 있게 됨  
- 다만 정확한 데이터가 부족해 전체 자원·생산 시스템까지 구현하지는 않음  
- 관련 배경 자료로 Raph Koster의 `UO` [ecology system](https://www.raphkoster.com/games/snippets/did-players-destroy-the-uo-ecology/) 및 `UO` 자원 시스템 글 [1](https://www.raphkoster.com/2006/06/03/uos-resource-system/), [2](https://www.raphkoster.com/2006/06/04/uos-resource-system-part-2/), [3](https://www.raphkoster.com/2006/06/05/uos-resource-system-part-3/)가 연결돼 있음  
  
### 추가 기능과 클라이언트 호환성  
- OSI가 1999년 2월 추가한 Meditation, Stealth, Remove Trap 스킬이 새로 들어감  
- 이 기능들의 일부 초기 흔적은 이미 코드에 남아 있었음  
- 대부분의 새 기능은 시작 시 `-features` 매개변수로 켜거나 끌 수 있음  
- 데모 서버에는 계정 시스템이 완전히 없었기 때문에, 원 개발자들이 구현했을 방식을 추정해 약간 현대화된 형태로 다시 구현함  
- 원래 데모 서버는 클라이언트 1.25.33만 지원했지만, 1.25.30부터 5.0.9.1, 즉 **2007-03-27**까지의 모든 [클라이언트](https://github.com/draxinar/uoclients)를 암호화 유무와 관계없이 지원하도록 확장됨  
- 여러 해 동안 완전히 다른 암호화 방식이 다섯 가지 있었기 때문에, 각 방식을 클라이언트 바이너리에서 역공학해야 했음  
  
### 32비트 원본과 64비트 기본 빌드  
- 원본 바이너리는 32비트였지만, 현재 기본 빌드는 64비트를 대상으로 함  
- 클래스 계층은 C 구조체 임베딩으로 원래 C++ 상속을 재현함  
- 이 방식 덕분에 `CMobile*`을 `CContainer*`가 필요한 곳에 전달할 수 있음  
- 64비트에서 포인터 폭이 넓어지면 상속된 필드 위치가 밀릴 수 있기 때문에, 일부 구조체는 32비트와 64비트 모두에서 상속 및 vtable 레이아웃이 바이너리와 맞도록 의도적으로 패딩됨  
  
### 공개 리소스  
- [https://github.com/draxinar/ouo](https://github.com/draxinar/ouo): 코드  
- [https://github.com/draxinar/rundir](https://github.com/draxinar/rundir): `UoDemo.dat` 기반 데이터, 수정, 완성된 데이터, 새 기능 포함  
- [https://uo.serpent-isle.com/](https://uo.serpent-isle.com/): Test Center, 실제 shard는 아니며 1998년 `Ultima Online` 서버에 매우 충실한 재현을 시험할 수 있는 환경  
- [UO:98](https://uo98.org/): Batlin과 Derrick의 프로젝트로, 2016년에 이 작업을 시작하게 만든 영감의 출처  
- `OUO`는 아직 초기 단계이며 문제가 남아 있을 수 있음  
- 발견한 문제는 [issue](https://github.com/draxinar/ouo/issues)로 보고할 수 있고, 기여도 환영됨  
  
### Ultima Online 커뮤니티에 대한 요청  
- 1997~2003년 무렵 원래 `Ultima Online` 서버의 `dynamic0.mul`, `dynamic0.bkp`, `regions.txt`, `resbank.mul` 파일을 가진 사람이 있다면 전달을 요청함  
- `dynamic0.mul`과 `dynamic0.bkp`는 서버 저장 파일이고, `regions.txt`는 스폰 정의, `resbank.mul`은 자원 정의 파일임  
- 원본 `dynamic0.mul`이나 `dynamic0.bkp`가 완전히 사라졌을 가능성은 낮아 보임  
- `dynamic0.mul` 파일에서 플레이어 데이터를 제거해 개인정보를 보존한 뒤 배포할 수 있는 도구는 이미 갖춰져 있음  
- 이 파일들은 `Ultima Online` 세계 콘텐츠를 매우 정확하게 재현하는 데 큰 가치가 있음

## Comments



### Comment 56977

- Author: neo
- Created: 2026-05-07T07:03:31+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=48032976) 
- 원본 **Ultima Online 서버**의 dynamic0.mul, dynamic0.bkp, regions.txt, resbank.mul 파일을 가진 사람이 있다면 보내주면 정말 고마울 듯함  
  1997~2003년 무렵 서버 저장 게임, 스폰 정의, 리소스 정의 파일이고, 특히 dynamic0.mul이나 dynamic0.bkp가 여러 안전한 장소에 백업됐을 테니 완전히 사라졌다고 보긴 어려움  
  이 파일들은 Ultima Online 세계 콘텐츠를 매우 정확하게 재현하는 데 **극도로 가치 있음**

- 정말 멋짐. 마침 옛 **Ultima 게임 사운드트랙**을 듣고 있다가 이걸 봤다는 게 신기함  
  원본에서 쓰던 **C++98 이전 C++ 방언**으로 디스어셈블리 결과를 작성하고 원래 컴파일러를 대상으로 삼는 걸 고려했는지 궁금함  
  빈티지 시스템에서 돌던 바이너리를 디스어셈블한 적이 있는데, 가능했다면 원래 툴체인을 목표로 했을 것 같음. 꽤 흥미로운 철학적 질문임

- eqclassic의 마지막 생존 개발자로서 흥미롭게 읽었지만, 도구를 어떻게 썼고 전체 과정이 어땠는지에 대한 **더 깊은 이야기**를 기대했음. 그래도 좋은 글임  
  당시에는 LLM이 없었지만, 3년 뒤의 PowerPC 바이너리에서 나온 일부 디버그 심볼이 있어서 조금 도움이 됐음  
  packet_handler나 entitylist 같은 파일 이름이 묘하게 익숙함 :D  
  마지막 관문은 나머지를 다듬기 전에 사실상 완벽한 **네트워크 코드**를 갖추는 일인데, 이미 여기에 수백 시간을 날렸음  
  소스를 조금 훑어봤을 뿐이지만, 전부 TCP 기반이라 그 위에 별도의 신뢰성 메커니즘을 얹은 것 같지는 않아 보임. 그렇다면 당시 MMO치고는 꽤 “느린” 선택처럼 느껴져서 흥미로움

- UO를 해보고 싶은 사람이라면 아직도 **활성 플레이어 기반**이 있는 게임. UO Outlands 같은 서드파티 서버는 원래 게임플레이에 더 가까운데, 요즘 MMO에 익숙한 기준으로는 꽤 가혹함  
  다른 플레이어가 와서 갱킹할 수 있고 장비를 잃을 수도 있음  
  지금도 해당 서버에 **2500명 이상**이 접속 중이라 여전히 매우 활발함
  - UO Outlands는 원래 UO보다 운영이 더 잘되는 느낌임. Discord도 꽤 활발하고 사용자가 약 2만 명쯤 있음

- 내 첫 진짜 프로그래밍 성취는 **Ultima Online 샤드 웹사이트**를 만든 일이었음  
  형편없는 PHP와 HTML을 썼지만, 이후 20년 넘게 동작했음. 좋은 추억임  
  UO 주변에 아직도 활발한 커뮤니티가 있다는 점이 놀라웠고, 어쨌든 이 프로젝트는 정말 멋짐
  - 비슷하게 웹사이트 제작을 돕고, 포럼 설치를 관리하다가, 샤드를 운영하던 사람들이 나중에는 에뮬레이터 코드도 맡겨줬음  
    당시 12~13살이었고 90년대 말~2000년대 초였음. 에뮬레이터 이름은 이제 기억나지 않지만 아마 POL이었을 가능성이 큼  
    샤드의 목표는 UO:Renaissance 이전 공식 서버에 최대한 가깝게 만드는 것이어서, T2A처럼 보이고 느껴지게 하려고 꽤 많이 작업했음  
    많은 걸 배웠고, 이후 RunUO가 나오고 2003년쯤 어느 정도 안정화되자 POL에서 만든 것들을 RunUO용 **C# 코드**로 옮기는 작업도 도왔고, 따라가려면 더 많이 배워야 했음  
    그 샤드에서 함께 일하던 사람들은 모두 대학에서 컴퓨터과학을 공부하거나 이미 프로그래머로 일하고 있었고, 나는 스크립트 몇 개 쓸 줄 아는 어린애였음  
    이 경험이 나중에 프로가 되는 데 결정적이었다고 봄. 실제 기술 회사에서의 첫 직장도 그중 한 명이 인턴 자리가 났을 때 추천해줘서 얻게 됨  
    어떤 의미에서는 **UO와 사설 샤드** 덕분에 지금의 커리어가 생긴 셈임
  - 내 경우는 **UOInject**라는 보조 도구로 광석 채굴을 자동화한 것이 시작이었음. 그 언어는 Visual Basic이었던 것 같음  
    순전히 필요해서 프로그래밍을 시작했음
  - MMO나 온라인 게임이었다면 사설 서버 커뮤니티는 끝없이 생김  
    게임 이름은 잊었지만 아마 City of Heroes였던 것 같고, 몇 년 동안 종료돼 있다가 어느 날 누군가 사설 서버를 다시 띄웠음  
    예전 Shockwave 온라인 게임들도 틈새 커뮤니티가 서버를 재구축하고, Shockwave 런타임과 디컴파일러를 만들고 있음  
    서로 비슷한 문제를 풀다 보니 게임 간 커뮤니티도 겹침 ;)
  - 나도 첫 진짜 프로그래밍 성취가 **Ultima Online 샤드 웹사이트**였음  
    두 번째는 지도를 바꾸는 일이었고, 정적 아이템 제거, 새 섬과 건물 추가 같은 걸 했음  
    세 번째는 verdata.mul을 바꿔 새 애니메이션과 아이템 그래픽을 추가하는 일이었음  
    비공식 POL 서버에서 Ultima Online을 한 덕분에 말 그대로 IT에 들어오게 됐음. 그전에는 회계사가 되려고 공부하고 있었음
  - 내 첫 웹사이트는 Chesapeake의 내 길드용이었고, 각종 스킬을 매크로로 올리는 스크립트를 엉성하게 만든 것이 첫 “실제 프로그래밍” 프로젝트였음  
    이것 때문에 처음 IRC에 들어갔고, 나중에는 freenode까지 이어졌음

- **UO 에뮬레이터 씬**이 나를 네트워크 프로그래밍으로 이끌었음  
  온라인 게임 중에서 이렇게 많은 부수적·창발적·우연적 게임플레이 메커니즘을 잘 담아낸 사례를 본 적이 없음  
  이후 3D MMO들은 UO가 제공했던 흥미로운 경제, 건축, 탐험 요소를 많이 낮춰버린 것 같음  
  PvP나 퀘스트류는 다른 게임들이 더 나을 수 있지만, UO는 여전히 매력적이었고 혼자 하거나 그룹으로 하거나 낯선 사람과 가볍게 상호작용하다가 기분에 따라 자연스럽게 전환할 수 있었음
  - 아쉽게도 두 가지가 사실로 드러났음  
    대부분의 사람은 이런 걸 원하지 않고 **정해진 레일** 위에 있는 걸 선호함  
    그리고 이런 게임에 가장 끌리는 두 집단은 한쪽이 있으면 다른 한쪽이 게임을 떠나는 역학에 빠짐. 그런데 두 번째 집단은 첫 번째 집단이 플레이하기를 필요로 함
  - 몇몇 오래된 **3D MMORPG**는 그런 메커니즘을 넣으려 했음  
    예를 들면 Asheron's Call은 모드 커뮤니티가 매우 활발했고 지금은 에뮬레이터 씬도 있음. 다만 서버 인기는 UO만큼은 아닌 것 같음  
    Shadowbane은 길드 중심이 강했지만, 약간 무법자처럼 굴면서 임의의 사람이나 길드와 PvP하는 재미가 있었음
  - 그쪽에 기회가 있을지도 모름. 솔직히 지금 **MMO 시장**에는 별로 움직임이 없음  
    WoW, Old School RuneScape, Final Fantasy Online 정도 말고는 크게 할 만한 게 많지 않음

- 10년 동안 간헐적으로 이 프로젝트를 진행하다가, 최근 **LLM 발전** 덕분에 끝이 없어 보이던 작업을 마침내 완료할 수 있었다는 대목이 인상적임  
  나도 MFC C++ 디컴파일 프로젝트를 하고 있는데, 이런 작업에서 LLM이 말도 안 되게 유용함
  - 이 작업에 LLM을 **자동화된 방식**으로 쓰고 있는지 궁금함. 로컬인지 클라우드인지도 궁금함

- 예전에 **Ultima Online**을 즐겼음  
  최근에는 TazUO 게임 클라이언트에서 Python 스크립팅을 재미있게 하고 있음. 약간 오래된 Python 3 버전이지만 Razor나 SteamUO에서 스크립트 짜는 것보다는 훨씬 나음  
  조용한 싱글플레이어 샤드에서 이것저것 해보고 싶다면 Memento가 괜찮았음

- Ultima 4 NES 버전의 **스페인어 또는 프랑스어 현지화 모바일판**을 찾고 있었음. 다른 작품들도 마찬가지임  
  FF 시리즈의 Pixel Remaster처럼 처리된 형태를 원함  
  현재는 에뮬레이터로만 플레이할 수 있음  
  텍스트가 많은 현지화 RPG는 외국어를 “놀면서 배우는” 데 아주 쉬운 방법이고, 읽기에도 좋음  
  이런 게 만들어지면 좋겠음

- 아, UO… 정말 좋은 추억임. 카드가 있을 나이가 아니라 Palo Alto의 Cybersmith까지 자전거를 타고 가서 **선불 시간**을 사던 기억이 남  
  예전에는 Napa Valley 샤드에서 꽤 열심히 했음. Catskills에 갈 만큼 용감하진 않았음  
  요즘은 UO 같은 경험이 그립지만, 그런 게임에 쏟을 시간이 도저히 없음
  - 왜 Catskills는 안 됐는지 궁금함. 달랐나? 더 어려운 규칙 세트가 있던 **Siege Perilous**를 떠올린 건 아닌가?
