40년 묵은 동글(Dongle)을 리버스 엔지니어링하며 깨달은 것들
엔지니어로서 경력이 쌓이다 보면 소위 ‘레거시(Legacy)‘라 불리는 괴물들을 마주하게 됩니다. 보통은 스파게티 코드나 문서 없는 API 정도지만, 가끔은 하드웨어의 유령과 싸워야 할 때가 있죠.
최근 Hacker News와 기술 블로그계를 달군 흥미로운 글이 하나 있었습니다. 무려 40년 된 회계 소프트웨어 를 최신 환경으로 마이그레이션 하기 위해, 병렬 포트(Parallel Port)에 꽂아야만 작동하는 하드웨어 동글을 무력화시킨 이야기입니다. 이 과정이 단순한 ‘크랙(Crack)‘을 넘어, 소프트웨어 아키텍처와 비즈니스 모델에 대해 꽤 깊은 통찰을 줍니다.
오늘은 이 ‘디지털 고고학’ 과정을 엔지니어 관점에서 뜯어보고, 우리가 배울 점이 무엇인지 이야기해 보려 합니다.
2026년에 만난 윈도우 98, 그리고 RPG
상황은 이렇습니다. 한 회계 법인이 40년 동안 써온 소프트웨어가 있는데, 이게 IBM RPG(Report Program Generator) 언어로 작성되었습니다. COBOL보다 오래된 그 언어 맞습니다. 이들은 2026년인 지금도 윈도우 98 머신에서 DOS 콘솔을 띄워 이 프로그램을 돌리고 있었습니다.
문제의 핵심은 하드웨어 동글 이었습니다. 이 프로그램은 LPT1(병렬 포트)에 특정 동글이 꽂혀 있지 않으면 실행조차 되지 않습니다. 가상화(Virtualization)를 하든 에뮬레이터를 돌리든, 이 물리적 장치를 소프트웨어적으로 해결하지 못하면 마이그레이션은 불가능한 상황이었죠.
기술적 분석: 복잡해 보이지만 단순한 진실
원작자(Dmitry Brant)는 디스크 이미지를 덤프 뜨고, 16비트 리얼 모드(Real Mode) 실행 파일을 분석하기 위해 Reko 라는 디컴파일러를 사용했습니다. 여기서 발견한 패턴이 아주 흥미롭습니다.
보통 하드웨어 락(Lock)이라고 하면 복잡한 암호화 챌린지-리스폰스(Challenge-Response)를 예상합니다. 하지만 분석 결과는 의외로 단순했습니다.
- 세그먼트 0x800의 비밀: 프로그램의 나머지 부분과 달리, 동글 체크 루틴은 별도의 세그먼트에 격리되어 있었습니다. 여기에는 병렬 포트 통신을 위한
IN,OUT명령어들이 가득했죠. - 입력이 없다?: 어셈블리 코드를 분석해보니, 이 루틴은 스택에서 인자를 받지도 않고, 레지스터 값을 입력으로 쓰지도 않았습니다.
- 출력은
BX레지스터: 루틴이 끝나면BX레지스터에 결과값을 담아RETF로 리턴합니다.
여기서 시니어 엔지니어라면 무릎을 탁 칠만한 결론이 나옵니다. “입력이 없는데 출력이 있다? 그렇다면 이 함수는 상수(Constant)를 반환하는 순수 함수다.”
즉, 동글이 내부적으로 얼마나 복잡한 타이밍 체크나 비트 연산을 하든, 결과적으로 반환하는 값은 항상 똑같은 매직 넘버 라는 것입니다.
브루트 포스(Brute Force)의 미학
코드를 더 뜯어보니 BH 레지스터는 항상 0x76이어야 했습니다. 남은 건 BL 레지스터의 8비트(0~255) 뿐이었죠. 256가지 경우의 수? 이건 사람이 손으로 해도 10분이면 끝납니다.
저자는 스크립트를 짜서 0부터 255까지 대입해 보았고, 정답이 0x06이라는 것을 찾아냈습니다. 결국 그 복잡했던 하드웨어 보안 장치는 단 4바이트의 패치로 무력화되었습니다.
BB 06 76 MOV BX, 7606h
CB RETF
이게 끝입니다. 허무한가요? 하지만 저는 이 부분에서 묘한 카타르시스를 느꼈습니다.
엔지니어링 관점에서의 고찰
1. 보안은 ‘충분함(Good Enough)‘의 영역이다
많은 개발자들이 이 글을 보고 “보안이 너무 허술하다”고 비웃을지도 모릅니다. 하지만 Hacker News의 댓글 중 인상 깊은 의견이 있었습니다.
“자물쇠는 정직한 사람들을 정직하게 유지하기 위해 존재하는 것이다.”
당시 이 소프트웨어의 타겟은 전문 해커가 아니라 회계사들이었습니다. 동글은 ‘실수로’ 불법 복제를 하는 것을 막는 용도였지, 작정하고 덤비는 리버스 엔지니어를 막기 위한 것이 아니었습니다. 비즈니스 요구사항에 딱 맞는 적정 기술(Appropriate Technology)이었던 셈이죠. 과도한 엔지니어링(Over-engineering)을 피한 좋은 예시일 수도 있습니다.
2. SaaS vs 영구 라이선스 (Perpetual License)
이 40년 된 동글 이야기는 의외로 현대의 SaaS(Software as a Service) 논쟁 으로 이어집니다. HN 커뮤니티에서는 왜 아직도 토목 공학이나 원자력 발전소 같은 곳에서 이런 물리적 동글을 선호하는지 토론이 벌어졌습니다.
- 에어갭(Air-gapped) 환경: 보안 시설은 인터넷 연결이 불가능합니다. 클라우드 인증? 말도 안 되는 소리죠.
- 소유권의 확실성: 엔지니어들은 내가 산 툴이 10년 뒤에서 작동하길 원합니다. SaaS는 회사가 망하거나 정책을 바꾸면 내 도구도 사라집니다. 하지만 동글은 (비록 고장 날 위험은 있어도) 내가 물리적으로 소유합니다.
저도 최근 구독형 모델로만 나오는 개발 툴들을 보며 피로감을 느낍니다. “내가 돈을 냈는데 왜 내 것이 아닌가?”라는 근원적인 질문을 이 낡은 플라스틱 쪼가리가 던지고 있는 것이죠.
3. 마케팅 용어의 허상
댓글 중에는 과거 ‘레이저 프로텍션(Laser Protection)‘이라 불렸던 기술에 대한 회고도 있었습니다. 디스크에 레이저로 구멍을 뚫었다고 광고했지만, 실제로는 그냥 핀으로 긁어서 배드 섹터를 만든 것과 다를 바 없었다는 증언들이었죠.
40년 전이나 지금이나, “AI 기반의”, “블록체인으로 검증된” 같은 수식어를 붙여 기술을 포장하는 마케팅은 변하지 않았다는 생각이 듭니다. 본질을 꿰뚫어 보는 눈이 시니어 엔지니어에게 필요한 이유입니다.
결론: 코드는 썩지만 논리는 남는다
이 프로젝트는 겉보기엔 낡은 시스템을 해킹하는 단순한 작업 같지만, 그 속에는 시스템의 입출력 관계를 파악하는 기본기 가 숨어 있었습니다. 아무리 복잡한 블랙박스라도 입력과 출력이 고정되어 있다면, 그건 그냥 상수(Constant)일 뿐입니다.
요즘 우리는 너무 많은 추상화 계층(Layer) 위에서 개발합니다. 가끔은 이렇게 밑바닥(Bare metal)까지 내려가서, 기계가 실제로 어떻게 대화하는지 들여다보는 시간이 필요합니다. 그것이 40년 전의 8비트 컴퓨터든, 최신 AI 모델이든 말이죠.
여러분이 관리하는 시스템에도 ‘마법’처럼 보이지만 사실은 단순한 MOV BX, 7606h 같은 코드가 숨어있지 않나요? 한 번쯤 들여다보시길 권합니다.