| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 정보보호
- 화이트햇스쿨
- 코틀린
- 산학
- 플러그인
- 보안
- QEmu
- 프로젝트
- 후기
- 앱 개발
- 보안제품개발
- 프론트엔드
- 앱
- Kotlin
- Android Studio
- 개발
- bob 14기
- 소프트웨어
- 학부연구생
- IT
- 프로그래밍
- 해킹
- 소프트웨어학과
- BOB
- React Native
- 정보보안
- 애플리케이션
- 코딩
- 악성코드
- CPU
Archives
- Today
- Total
맨땅에 코딩
QEMU 그게 뭔데? 본문
졸려 죽겠지만 꾹 참고 QEMU 내부 구조에 대해 간단히 요약해봅니다....
우리 플러그인 개발 잘할 수 있겠지?
잘하고 싶다.
1. QEMU의 큰 그림
QEMU는 크게 2개의 층으로 구성된다.
| 층 | 설명 |
| Front-end (System Emulation) | 가상 머신 관리 (디스크, 네트워크, 장치, 스냅샷 등) |
| Back-end (CPU Emulation: TCG) | 게스트 CPU 명령어를 해석하고 실행하는 핵심 엔진 |
┌──────────────────────────┐
│ QEMU Frontend Layer │ ← CLI 옵션, 장치 모델, 스냅샷, QMP
└─────────────┬────────────┘
│
┌─────────────▼────────────┐
│ QEMU Backend (TCG) │ ← CPU 명령어 실행기 (Tiny Code Generator)
└─────────────┬────────────┘
│
┌─────────────▼────────────┐
│ QEMU Plugin API │ ← 우리가 만든 코드가 여기에 붙음
└──────────────────────────┘
2. QEMU의 실행 사이클(Main Loop)
while (vm_running) {
poll_hardware_events(); // 디바이스 I/O, IRQ 확인
execute_vcpu(); // 게스트 CPU 실행
handle_timers(); // 타이머 인터럽트 처리
}
위 루프는 "호스트 CPU 위에서 게스트 OS를 계속 돌리는 메인 엔진"이다.
우리가 만들 플러그인은 주로 execute_vcpu() 내부에서 콜백될 것이다.
3. TCG(Tiny Code Generator)란?
게스트 CPU 명령어를 호스트 CPU 명령어로 번역해 실행하는 엔진
이것을 QEMU가 실시간으로 만들어 실행한다.
mov eax, ebx
→ TCG: load ebx → store eax
→ 호스트: mov rax, rbx
플러그인은 이 변환된 블록(Translation Block, TB) 단위로 감시할 수 있다.
4. Translation Block(TB)
QEMU는 CPU 명령어를 TB(Translation Block) 단위로 묶어서 번역·캐시한다.
[TB1] 0x400000 → 0x40000F
[TB2] 0x400010 → 0x40002A
[TB3] 0x40002B → 0x400045
- TB는 "한 번 번역된 코드 블록"으로, 여러 번 재사용된다.
- CPU가 TB를 실행하면, 그 안의 모든 명령어를 순서대로 수행한다.
플러그인에서는 2가지 수준에서 감시가 가능:
- qemu_plugin_register_vcpu_tb_exec_cb() → TB 단위 콜백
- qemu_plugin_register_vcpu_insn_exec_cb() → 명령어 단위 콜백
5. QEMU → Plugin 호출 타이밍
게스트 명령 실행
↓
QEMU TCG 변환
↓
TB 실행 시작 → [on_tb_exec_start()]
↓
각 명령어 실행 → [on_insn_exec()]
↓
메모리 접근 발생 → [on_mem_access()]
↓
IRQ / 예외 발생 → [on_interrupt()]
↓
TB 종료 → [on_tb_exec_end()]
우리가 짜는 플러그인 콜백들은 이 시점들에 정확히 연결된다.
즉, QMEU는 매 실행 루프마다 "어떤 이벤트가 발생했는지"를 플러그인에게 알려준다.
6. 플러그인 구조 개요
plugin_main.c
├─ qemu_plugin_install() ← 플러그인 진입점
├─ register_exec_callback() ← 명령어/메모리 콜백 등록
├─ on_exec_cb() ← 명령어 실행 시 호출
├─ on_mem_cb() ← 메모리 접근 시 호출
└─ on_irq_cb() ← 인터럽트 발생 시 호출
7. 실제 콜백 흐름 예시
void on_exec(unsigned int vcpu, uint64_t pc)
{
printf("[EXEC] vCPU%d @0x%lx\n", vcpu, pc);
}
void on_mem(unsigned int vcpu, uint64_t addr, uint8_t is_store)
{
printf("[MEM] vCPU%d %s @0x%lx\n",
vcpu, is_store ? "WRITE" : "READ", addr);
}
void qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info,
int argc, char **argv)
{
qemu_plugin_register_vcpu_insn_exec_cb(id, on_exec);
qemu_plugin_register_vcpu_mem_cb(id, on_mem);
}
→ 게스트 OS가 실제로 명령을 실행하거나 메모리에 접근할 때마다, 이 콜백들이 "호스트 콘솔"에 로그를 남긴다.
8. 플러그인 호출 타이밍 도식
QEMU 실행 루프
│
├─ poll_hardware_events()
│
├─ execute_vcpu()
│ ├─ TCG 번역 (TB 생성)
│ ├─ TB 실행 시작 → [TB 콜백]
│ ├─ 명령어 실행 → [Insn 콜백]
│ ├─ 메모리 접근 → [Mem 콜백]
│ ├─ IRQ 발생 → [IRQ 콜백]
│ └─ TB 종료 → [TB end 콜백]
│
└─ handle_timers()
9. 이벤트별 플러그인 콜백 매핑
| 이벤트 | QEMU 내부 | 플러그인 콜백 |
| TB 생성 | Translation Block 생성 | qemu_plugin_tb_trans_cb |
| TB 실행 시작 | TB 실행 시 | qemu_plugin_register_vcpu_tb_exec_cb |
| 명령어 실행 | Instruction execution | qemu_plugin_register_vcpu_insn_exec_cb |
| 메모리 접근 | load/store | qemu_plugin_register_vcpu_mem_cb |
| 인터럽트 발생 | IRQ raise | qemu_plugin_register_vcpu_interrupt_cb |
| 예외 발생 | Trap 발생 | qemu_plugin_register_vcpu_exception_cb |
| CPU 상태 변경 | Resume/Pause | qemu_plugin_register_vcpu_state_cb |
10. 플러그인 데이터 흐름 구조
[게스트 OS 실행]
↓
QEMU 내부 이벤트
↓
플러그인 콜백 호출
↓
로그 수집 (Collector)
↓
파일 저장 / 압축 (Storage)
↓
분석 / 시각화 (Python 등)
QEMU는 이벤트 생성기, 플러그인은 이벤트 수집기, Python은 이벤트 분석기 역할
'낙서장' 카테고리의 다른 글
| "플러그인 개발"이 와닿지 않아 (0) | 2025.10.26 |
|---|---|
| 메모리 구조 핵심 요약(QEMU·플러그인 관점) (0) | 2025.10.26 |
| CPU 동작 원리 핵심 정리(QEMU·플러그인 관점) (0) | 2025.10.26 |
| 운영체제 그게 뭔데?(QEMU·플러그인 관점) (0) | 2025.10.26 |
| 유니스트 컴퓨터공학과 대학원 전기 1차 합격 후기 (0) | 2025.09.25 |
