본문으로 건너뛰기
피드

SGI O2 PROM 펌웨어 리버스 엔지니어링: 900MHz CPU 업그레이드를 향한 여정

general 약 9분
vote
0
댓글
북마크

SGI O2 워크스테이션의 512KiB PROM 바이너리를 역컴파일하여 수정 가능한 어셈블리 소스로 변환하는 데 성공한 과정을 다룬 글임. SHDR 헤더 구조, 체크섬 알고리즘, firmware 섹션의 .text/.rodata/.data 서브섹션 구조 등을 하나씩 밝혀내며, bit-identical 재조립이 가능한 수준까지 도달함. 이를 통해 RM7900(900MHz) CPU 지원을 위한 PROM 수정이 가능해짐.

  • 1

    ip32prom-decompiler를 제작해 512KiB PROM을 수정 가능한 어셈블리로 역컴파일, 재조립 시 원본과 bit-identical한 이미지 생성 확인

  • 2

    SHDR(72바이트) 구조 해석: 매직넘버, 섹션 길이, 이름/버전, 타입 비트필드, 체크섬 등 필드 완전 분석

  • 3

    firmware 섹션(전체의 91%)은 0x81000000(kseg0)에 로드되는 .text/.rodata/.data 서브섹션으로 구성되어 있음을 발견

  • 4

    체크섬은 단순 2의 보수 합산 방식으로, SHDR 체크섬이 유효하면 섹션 체크섬 계산 시 SHDR을 건너뛸 수 있음

  • 5

    version 섹션의 SHDR이 ELF 헤더와 오버레이되어 있음을 발견 — e_ident 패딩 영역에 SHDR 메타데이터가 삽입됨

  • 6

    Capstone 디스어셈블러 + BFS 코드 탐색 + XPM 시각화를 조합한 체계적 분석 방법론 활용

SGI O2 PROM 리버스 엔지니어링: CPU 업그레이드를 위한 펌웨어 해부기

  • Silicon Graphics O2는 MIPS CPU를 탑재한 유닉스 워크스테이션으로, 2000년대 초반부터 커뮤니티에서 CPU 업그레이드를 시도해왔음
  • RM5200(300MHz), RM7000A(350MHz)를 600MHz RM7000C로 교체하는 것은 펌웨어 수정 없이 가능했으나, 900MHz RM7900 업그레이드는 PROM 펌웨어 수정이 필수적이었음
  • 당시 SGI에 소스코드 접근을 요청할 수 있었으나, SGI가 사라진 지금은 소스코드도 함께 소실된 상태임
  • 저자는 ip32prom-decompiler를 직접 제작해 512KiB PROM 바이너리를 수정 가능한 어셈블리(.S) 파일로 역컴파일하는 데 성공함
  • 역컴파일된 어셈블리를 재조립하면 원본과 bit-identical한 이미지가 생성되어, 역컴파일의 정확성이 검증됨

SHDR 구조 발견 과정

  • mips64-unknown-linux-gnu-objdump로 바이너리를 디스어셈블한 결과, 오프셋 0x08에서 0x53484452라는 값을 발견했고, 이것이 ASCII "SHDR"임을 strings 명령으로 확인함
  • SHDR은 각 섹션의 헤더로, branch+delay slot 패턴으로 경계가 구분되며 총 72바이트 크기임
  • 바이너리 내에 5개의 SHDR이 존재: sloader, env, post1, firmware, version
graph TD
    subgraph "PROM 512KiB 바이너리 구조"
        A["sloader
@0x00000000
16,384 bytes
type=1 (code)"] B["env
@0x00004000
1,024 bytes
type=0 (data)"] C["post1
@0x00004400
19,780 bytes
type=1 (code)"] D["firmware
@0x00009200
393,212 bytes
type=3 (code+metadata)"] E["version
@0x00069200
904 bytes
type=0 (ELF)"] end A --> B --> C --> D --> E

SHDR 필드 구조

  • [0x00-0x08): 엔트리 명령어 — 코드 섹션은 branch로 SHDR을 건너뛰고, 데이터 섹션은 nop
  • [0x08-0x0C): 매직 넘버 "SHDR"
  • [0x0C-0x10): 섹션 길이 (다음 SHDR 오프셋 계산에 사용, 256바이트 경계로 라운드업)
  • [0x10-0x12): name 길이 + version 길이 (각 1바이트)
  • [0x12-0x13): 섹션 타입 — bit 0이 코드 여부, bit 1이 메타데이터 존재 여부를 나타냄
  • [0x14-0x34): 섹션 이름 (32바이트 고정), [0x34-0x3C): 버전 문자열 (8바이트 고정)
  • [0x3C-0x40): SHDR 체크섬, [0x40-0x48): 메타데이터 (타입에 따라 존재 유무 결정)

코드 식별: BFS 기반 접근

  • Capstone 디스어셈블러를 활용해 branch 타겟을 따라가는 BFS(너비 우선 탐색)로 코드를 자동 식별함
  • 초기에는 전체의 약 10%만 코드로 식별되었는데, jal 명령어의 점프 타겟 계산 방식을 이해하지 못했기 때문임
  • MIPS에서 리셋 후 실행은 0xBFC00000부터 시작됨 — --adjust-vma=0xbfc00000 플래그 적용 후 jal 타겟이 정상적으로 해석됨
  • 점프 테이블이나 런타임에 주소를 조립하는 함수, dead code 등은 자동 발견이 불가능해 functions.json에 수동 어노테이션으로 보완함

바이너리 시각화의 위력

  • XPM 포맷으로 바이너리 구조를 이미지로 시각화함: 빨강=코드, 파랑=헤더/체크섬, 초록=ASCII, 노랑=접근된 메모리, 검정=0x0, 흰색=0xFFFFFFFF, 회색=미식별
  • 시각화를 통해 미식별 영역의 존재를 직관적으로 파악할 수 있었고, 진행 상황을 확인하는 동기 부여 수단으로도 유용했음

firmware 섹션의 서브섹션 구조

  • firmware 섹션은 PROM의 91%를 차지하며(384KiB/422KiB), 섹션 타입 필드의 bit 1이 설정된 유일한 섹션임
  • SHDR 메타데이터의 첫 4바이트 0x81000000이 실행 시 로드 주소였음 — kseg0 영역(캐시 가능, TLB 불필요)의 물리 주소 0x01000000(16MiB)에 해당
  • 두 번째 메타데이터 값 0x00048e70은 .text 섹션 길이였고, 각 서브섹션 끝에 (로드 주소, 길이) 쌍이 연결 리스트처럼 이어져 있었음
  • 서브섹션은 .text(실행 코드), .rodata(읽기 전용 데이터/문자열/점프 테이블), .data(읽기-쓰기 초기화 데이터)로 구성되며, 길이 0인 센티널 값으로 종료됨
  • C로 작성되어 정적 ELF 바이너리로 컴파일된 후, 섹션을 추출해 커스텀 포맷으로 리패킹한 것으로 추정됨

체크섬 알고리즘

  • sloader의 is_section_checksum_valid 함수를 분석한 결과, 단순한 2의 보수 체크섬 방식임
  • SHDR 이후의 모든 32비트 워드를 더한 값을 부정(negate)하여 저장하면, 체크섬 포함 전체 합이 0이 됨
  • SHDR 체크섬도 동일한 방식이며, 유효한 SHDR 체크섬의 기여분은 항상 0이므로 섹션 체크섬 계산 시 SHDR을 건너뛸 수 있음

version 섹션의 정체: ELF 바이너리

  • version 섹션의 초기 바이트 0x7F454C46이 ELF 매직 넘버(\x7fELF)임을 뒤늦게 발견함
  • ELF 헤더와 SHDR이 오버레이되어 있었음 — e_ident의 패딩 영역에 "SHDR" 매직과 섹션 길이가 들어가 있었고, e_machine(0x08 = EM_MIPS) 필드가 섹션 타입 0에 자연스럽게 대응됨
  • 패딩 바이트에 8이 들어있던 것도 ELF 헤더의 e_machine 필드 값이었던 것임

의의와 향후 전망

  • 2004년 메일링 리스트에서 "SGI 엔지니어급 실력과 카페인이 필요하다"며 불가능에 가깝다고 평가받았던 작업이 실제로 완수됨
  • 1996년산 512KiB 펌웨어의 주된 난이도는 복잡성이 아니라, 무수히 많은 세부 사항을 하나하나 맞추는 인내심이었음
  • 이 작업으로 RM7900(900MHz) CPU 지원을 위한 "distinctly modified IP32 PROM image" 생성이 가능해졌으며, SGI의 도움 없이도 O2의 CPU 업그레이드 경로가 열림

1996년산 펌웨어도 체계적 접근과 끈기로 완전히 해부할 수 있다는 것을 보여주는 사례임. 특히 바이너리 시각화가 미지 영역 파악과 동기 부여 모두에 효과적이었다는 점이 다른 리버스 엔지니어링 프로젝트에도 참고할 만함.

댓글

댓글

댓글을 불러오는 중...

general

Last.fm, 소유권 바뀌고 독립 회사로 새 출발

Last.fm이 소유권 변경을 거쳐 독립 회사로 운영된다고 밝혔다. 계정, 청취 기록, 스크로블, Pro 구독, API 기능은 그대로 유지되며 사용자 데이터 처리 방식도 바뀌지 않는다고 안내했다.

general

구글이 “사람들은 AI 모드를 좋아한다”고 하자 덕덕고 방문이 28% 가까이 늘어남

구글 검색이 AI 모드와 AI 개요를 전면에 밀어붙이는 사이, AI 없는 검색을 내세운 덕덕고 쪽 트래픽이 눈에 띄게 뛰었다. 덕덕고는 “사람들이 원하는 건 AI 자체의 찬반이 아니라 선택권”이라고 보고 있다.

general

경기도, 도민 15만 명 대상 AI·디지털 교육 시작

경기도가 2026년 AI디지털배움터를 열고 약 15만 명을 대상으로 스마트폰, 키오스크, 생성형 AI, 업무 자동화 교육을 운영해. 고령층과 정보취약지역 주민을 위한 찾아가는 교육, 청년·소상공인 대상 AI 활용 교육까지 범위를 넓힌 게 특징이야.

general

NIA “공공 AX 표준 만들고, 정책부터 현장 구현까지 직접 잇겠다”

한국지능정보사회진흥원(NIA)이 AI 기본법에 따른 인공지능정책센터로 지정되며 공공 부문의 AI 전환을 지원하겠다는 방향을 밝혔다. 핵심은 부처·지자체가 각자 따로 AI를 도입하다 생기는 중복 투자와 표준 부재를 줄이고, 일부 유스케이스는 정책 설계에서 구현까지 직접 밀어붙이겠다는 것.

general

최악의 면접은 코딩 테스트가 아니라 ‘무단 심리평가’였다

한 엔지니어가 정신건강 스타트업의 창업 엔지니어 면접에서 겪은 일을 공유했다. 기술 평가도 하기 전에 90분짜리 컬처핏 인터뷰에서 인생의 가장 힘든 날, 가족 문제, 실패한 관계 같은 사적인 이야기를 끌어냈고, 다음 날 한 줄짜리 탈락 메일을 받았다는 내용이다.