에뮬레이션(emulation)
에뮬레이션은 호스트(host)라고 하는 시스템에서 지원하지 않는 소프트웨어, 즉 게스트(guest)를 실행하기 위해 에뮬레이터(emulator)라는 서포트 프로그램을 이용하는 방법이다. 이 때 원본 코드를 호스트에 맞게 번역(traslate)해야 하고, 적절한 주변기기(peripheral), 타이머(timer), 가속기(accelerator), 센서(sensor) 역시 맞춰야 한다.
에뮬레이션은 기기(device)나 기기를 구매할 비용이 부족할 때 큰 도움이 된다.
에뮬레이션과 보안
에뮬레이션은 스위스 군용 칼처럼 보안과 취약점 분석에 있어서 아주 강력한 도구이다. 기기를 직접 보유하기 않고도 가상화된 시스템에서 시스템 함수와 시스템 콜을 실행해보거나, 악성 소프트웨어를 실행해보는 등 다양한 실험을 할 수 있다.
에뮬레이션과 가상화의 차이점
가상화(Virtualization)는 다른 운영체제를 현재의 시스템에서 실행할 수 있는 기술이다. 논리적으로 호스트 시스템과 게스트 시스템을 나눈다. 가상화의 핵심 컴포넌트는 하이퍼바이저(hypervisor)로, 게스트 운영체제의 실행을 제어한다. 파일 시스템 역시 가상화되지만 결국 모든 소프트웨어는 물리적 프로세서에서 실행된다. 이런 이유로 가상화는 호스트 머신과 같은 아키텍처를 사용하거나 최소한 호환이 되는 아키텍처를 사용해야 한다.
하이퍼바이저는 타입 1과 2로 나뉘는데, 타입 1은 베어메탈(bare-metal) 하드웨어에 설치되어 가상 머신을 관리하는 작은 운영체제를 실행한다. 타입 2는 호스트 운영 체제에 설치되는 애플리케이션
반면 에뮬레이션은 가상화 계층보다 높은 단계로, 호스트 또는 게스트 운영 체제의 내부 프로세스로 실행되는 독립 소프트웨어다. 호스트의 CPU에 의존적이지 않고 다른 아키텍처의 소프트웨어를 실행할 수 있다. 운영체제 위(above)에서 실행되는 프로세스에 의해 번역(interpret)되어야 하므로 시간 손실(time penalty)이 있다.
에뮬레이션 성능을 향상시키기 위해 JIT(Just in time) 방식이 사용된다. 호스트 아키텍처에서 컴파일되고, 프로세서에서 코드를 실행한다. 다른 전략으로는 중간 표현(Intermediate Representation, IR)이 있다. 실행된 코드를 IR로 전환하고 내장된 인터프리터에서 IR 명령을 실행하는 방식이다. 에뮬레이션은 사용자 공간(user space) 수준에서도 가능하고, 전체 시스템(full system) 수준에서도 가능하다. 전체 시스템 에뮬레이션 도구로는 QEMU가 대표적이다.
도커(Docker)는 하이퍼바이저도 아니고, 에뮬레이터도 아니고, 가상화 시스템도 아니다. 단순히 컨테이너 엔진이다. 도커는 다양한 프로그램, 실행환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해주는 플랫폼이다.
에뮬레이터의 동작
에뮬레이터는 일반적으로 특정 마이크로프로세서에 대한 명령 해석기(interpreter)로 구현된다.
기본 구조는 명령어를 페치(fetch)하고 인터럽트를 관리(handle)하고, 그래픽, 소리, 사용자 입력, 타이머 동기화 등을 실행하는 while 루프로 생각할 수 있다.
while(!stop_emulation)
{
executeCPU(cycles_to_execute);
generateInterrupts();
emulateGraphics();
...
}
에물레이션하고 싶은 마이크로컨트롤러가 7MHz의 클럭 속도로 동작하고, 호스트 CPU가 70MHz로 동작한다면, 에뮬레이터는 10배 느리게 동작해야 신뢰성 있는 에뮬레이션이 가능하다. 부드럽게 실행하려면 반복(loop)하는 동안 언제 디스플레이를 출력하고, 키보드 인터럽트를 실행할지 알아야 한다.
executeCPU 함수는 두 가지 방식으로 구현될 수 있다.
- interpreted emulation
원시 바이트(raw byte)를 얻고 명령어의 opcode를 해독(decode)한 다음 다음 명령어의 효과를 시뮬레이션하는 함수를 호출하는 방식이다. 속도는 느리지만 구현이 가장 쉽다.
- binary translation
모든 명령어를 호스트 아키텍처에 맞게 번역(translate)하고 CPU에 실행시키는 방식이다.
참고자료
Antonio Nappa , Eduardo Blázquez - Fuzzing Against the Machine
'보안 > fuzzing' 카테고리의 다른 글
[하드웨어 해킹] 퍼징 기술 (0) | 2024.01.15 |
---|---|
[하드웨어 해킹] 퍼징과 분석 기술 - 심볼릭 실행 (0) | 2024.01.11 |
[하드웨어 해킹] QEMU 실행 모드 (1) | 2024.01.11 |
[하드웨어 해킹] QEMU (2) | 2024.01.09 |
퍼징(fuzzing) 환경 구축하기 (1) | 2024.01.06 |