На WWDC 2025 Apple анонсировала macOS 26 Tahoe. Вместе с ней появился новый формат образов дисков — ASIF. Он разработан для виртуальных машин и живёт внутри Virtualization framework. ASIF — это разрежённый (sparse) формат, как VMDK, VHDX или QCOW2: можно хранить большой диск, занимая на хосте меньше места.
Эрик Шампер решил написать парсер для ASIF вскоре после выхода системы. Он создал тестовый образ через diskutil image create, заполнил его повторяющимся паттерном и начал смотреть hex-дампы. В начале файла сразу видна сигнатура shdw и несколько целых чисел в big endian.
Дальше — поиск бинарника, который умеет читать формат. Шампер просто grep-нул по /System/Library/Frameworks и нашёл diskimagescontroller внутри DiskImages2.framework. Строки из него выдали названия полей заголовка и сообщения об ошибках. Бинарник загрузили в IDA.
Функция парсинга заголовка дала полную картину: header_signature, header_version, header_size, directory_offsets (два смещения на каталоги аллокации), GUID, sector_count, max_sector_count, chunk_size (обычно 1 MiB), block_size (512 байт), поле metadata_chunk и флаги. Поля directory_offsets ведут к структуре с каталогами: каждый каталог начинается с версии uint64, активен тот, у кого версия выше (это даёт атомарные обновления). Внутри — список таблиц, в каждой — uint64-записи (data entries). Каждая запись указывает на чанк данных и имеет 55 бит номера чанка и 9 бит флагов. Флаги: 00 — не инициализирован, 01 — полностью инициализирован, 10 — не отображён, 11 — есть битмап.
Битмапы и группировка чанков — ключевая деталь. Записи чанков сгруппированы в «chunk groups», после каждой группы идёт битмап. Битмап использует 2 бита на блок. Размер битмапа — 1 чанк, полный битмап покрывает 4 чанка данных. Чтобы прочитать произвольный offset виртуального диска, нужно превратить его в номер чанка через многослойную математику: вычисляется номер таблицы, номер записи внутри неё, а затем — номер чанка с учётом группы и битмапа. Шампер признаётся, что сначала просто скопировал декомпилированный код из IDA и не разбирался до конца. Понял всё только после того, как наткнулся на репозиторий huven на GitHub, где формат уже документирован, и пересмотрел свою реализацию.
В итоге формат оказался довольно элегантным и простым по сравнению с аналогами. Максимальный размер виртуального диска при дефолтном chunk_size — чуть меньше 4 PiB, небольшой кусок в конце зарезервирован под метаданные (plist с внутренними и пользовательскими ключами).