QEMU TCG — это режим QEMU без аппаратной виртуализации, где гостевые инструкции не выполняются напрямую на CPU, а переводятся и исполняются самим QEMU через Tiny Code Generator. Tiny Code Generator берет блоки инструкций гостевой архитектуры, переводит их во внутреннее представление, а затем генерирует исполняемый код для CPU хоста. Эти переведенные блоки кэшируются и переиспользуются, поэтому QEMU не интерпретирует каждую инструкцию заново, а выполняет динамическую бинарную трансляцию. Стек получился такой:
Proxmox VE -> Debian VM -> QEMU -> Windows 10 guest -> malware sample
На железе стоит Proxmox VE. Внутри него поднял минимальную Debian VM, а уже внутри Debian запускается QEMU с Windows 10. То есть Windows с малварью живет не напрямую в Proxmox, а внутри nested QEMU. Параметры Debian VM:
- Debian GNU/Linux 13 trixie
- 8 vCPU
- ~8 GB RAM
Режим TCG медленнее, зато QEMU сам транслирует guest-инструкции и может логировать выполнение на уровне блоков, инструкций и CPU state. QEMU запускался примерно так:
qemu-system-x86_64 \
-accel tcg,thread=multi \
-cpu max \
-smp 8 \
-m 4096 \
-display none \
-nic none \
-drive file=win10-run.qcow2,format=qcow2,if=ide \
-serial file:serial.log \
-D qemu-tcg.log \
-d guest_errors
Перед запуском создается snapshot/overlay, внутрь Windows копируется sample, затем Windows стартует в TCG. Один реальный прогон малвари занял примерно 5 минут. За 60 секунд полной трассировки получилось около 2.1 GB лога. Лог содержит сырые инструкции, который выполнялись на "процессоре":
IN:
0xfffff80577ca06a1: 48 8b c7 movq %rdi, %rax
0xfffff80577ca06a4: eb ac jmp 0xfffff80577ca0652
Trace 6:
RAX=0000000000000000 RBX=ffffe509e52773f8
RIP=fffff80577ca06a1 RFL=00040246
CR3=000000012dd3f000
Мы также видим весь kernel space, любой код который там выполнялся, все системколлы, полный доступ к памяти винды, что дает очень много инфы о запускаемой программы. Далее я хочу чекнуть как с 2 гигабайтным логом справится локальная ллм типа геммы