기타 Lobsters · 2026-10-26

"매뉴얼 보고 언제 다 침?" 어셈블러 굴려서 기계어 비트 알아내는 역공학 툴 (2001)

핵심 요약
  • 2001년 USENIX에서 발표된 'DERIVE'는 어셈블러에 명령어를 조합해 넣고 출력된 기계어를 분석해 비트 인코딩을 자동으로 알아내는 도구입니다.
  • 개발자가 매뉴얼을 보고 손수 비트 규격을 코딩하던 지루하고 오류 많은 과정을 자동화하여 C 언어 구조체로 뽑아냅니다.
  • MIPS, SPARC, x86 등을 분석해 Java JIT(Kaffe) 백엔드 코드를 40% 줄였으며 매뉴얼과 어셈블러의 불일치까지 잡아냈습니다.
요약 JIT 컴파일러나 디스어셈블러, 바이너리 재작성기 같은 시스템 도구를 개발할 때는 각 CPU 기계어 명령어가 비트 단위로 어떻게 인코딩되는지 파악하는 작업이 필수적입니다. 하지만 기존 방식은 개발자가 아키텍처 레퍼런스 매뉴얼을 일일이 보면서 오프코드, 오프셋, 비트 크기 등을 직접 손으로 작성해야 했기 때문에 실수하기 쉽고 지루한 노가다 작업이었습니다. 2001년 USENIX 학술대회에서 발표된 논문은 이러한 비효율을 해결하기 위한 도구 'DERIVE'를 소개했습니다. 연구진은 거의 모든 아키텍처에 이미 해당 바이너리 인코딩 정보를 완벽하게 알고 있는 '어셈블러' 프로그램이 존재한다는 점에 주목했습니다. 개발자가 명령어 이름과 피연산자 유형(레지스터, 즉시값 등)만 입력하면, DERIVE가 어셈블러에 다양한 순열의 명령어를 자동으로 집어넣고 출력된 기계어 결과를 방정식 형태로 분석해 인코딩 규칙을 역공학합니다. 이 도구는 MIPS, SPARC, Alpha, PowerPC 명령어 세트를 100% 풀어냈으며, 구조가 복잡한 ARM과 x86도 대부분 성공적으로 분석해 C 언어 구조체 형태로 추출했습니다. 나아가 연구진은 이 결과를 바탕으로 빠른 코드 생성을 위한 C 매크로를 자동 생성하는 도구를 만들었고, 이를 통해 오픈소스 Java JIT 컴파일러인 Kaffe의 백엔드 코드 크기를 40%나 줄이는 성과를 거두었습니다. 부수적인 효과로 매뉴얼과 실제 어셈블러 구현 사이의 차이점이나 버그를 찾아내는 테스터 역할까지 수행할 수 있다고 설명합니다.
Sponsored · 광고