Нейрослоп ниже.
Главная интрига этого номера «Хакера» строится на двух темах: аппаратных/низкоуровневых абстракциях (интерпретатор байт-кода внутри шрифта) и новом векторе атак на ML-инфраструктуру.
Разберём детально архитектуру виртуальной машины TrueType и содержание статей из выпуска.
Что за виртуальная машина живёт внутри шрифта TrueType?
Когда в конце 1980-х Apple (а затем совместно с Microsoft) проектировала формат TrueType (TTF), инженеры столкнулись с фундаментальной проблемой растеризации: векторные кривые Безье при отображении на экранах с низким разрешением (DPI) неизбежно искажаются. Теряются засечки, сливаются параллельные линии, плывёт толщина штрихов (stems).
Чтобы глифы выглядели читаемо на любых размерах, был придуман механизм хинтинга (grid-fitting) — подтягивания контрольных точек контура к пиксельной сетке. Вместо статических декларативных подсказок (как в Adobe PostScript Type 1) создатели TrueType встроили в спецификацию полноценную стековую виртуальную машину, исполняющую низкоуровневый байт-код прямо в процессе рендеринга.
1. Архитектура и память TrueType VM
Виртуальная машина TTF — это изолированный процессор инструкций со следующими компонентами:
Стек операндов (Interpreter Stack): 32-битный стек LIFO, куда помещаются аргументы и результаты инструкций.
Хранилище (Storage Area): адресуемый массив ячеек оперативной памяти (фактически регистры общего назначения), доступный через инструкции RS (Read Storage) и WS (Write Storage). Индексы задаются целыми числами.
Сумеречная зона (Twilight Zone): специальный вспомогательный массив координат (виртуальный глиф), используемый как черновик для промежуточных геометрических вычислений, не отображаемый на экране.
Графическое состояние (Graphics State): набор системных регистров, управляющих проекцией, векторами перемещения точек, округлением и масштабом (DPI, Point Size).
Таблица значений управления (CVT — Control Value Table): глобальная таблица констант шрифта (например, стандартная толщина линий).
2. Система команд (байт-код)
Набор инструкций насчитывает свыше 200 опкодов. Среди них:
Арифметика и логика: ADD, SUB, MUL, DIV, NEG, ABS, побитовые/булевы AND, OR, NOT.
Управление потоком (Branching): условные переходы IF, ELSE, EIF, а также относительные прыжки JMPR, JROT (Jump Relative On True) и JROF (Jump Relative On False).
Функции и циклы: FDEF (Function Definition), ENDF, CALL, LOOPCALL.
Манипуляция геометрией: сдвиг точек контура глифа относительно сетки или других точек (MDAP, MIAP, MDRP, MIRP, SHP).
3. Таблицы исполнения в файле .ttf
Код внутри шрифта разбит по таблицам и исполняется на разных этапах:
fpgm (Font Program): выполняется один раз при загрузке шрифта. Здесь объявляются функции (FDEF) и глобальные процедуры.
prep (Control Value Program): исполняется каждый раз при изменении размера шрифта, трансформации или DPI матрицы.
glyf: у каждого глифа есть свой локальный поток байт-кода, который триггерится непосредственно при отрисовке данного символа на экране.
4. Тьюринг-полнота и Doom.ttf
Наличие произвольного чтения/записи в память (RS/WS), циклов, условных переходов и стека делает байт-код TrueType полным по Тьюрингу.
Статья в номере («ttf. Запускаем код в виртуальной машине шрифта TrueType») отсылает к вирусному проекту TTF-DOOM (исследователь 4RH1T3CT0R7). Автор реализовал рейкастинг-движок в стиле Doom (3D-стены, расчет дистанций, трассировка лучей) целиком на байт-коде хинтинга TTF размером всего 6.5 КБ (13 функций):
Ввод игрока (координаты X, Y, угол обзора) передаётся через оси вариативного шрифта (font-variation-settings).
Внутренняя VM шрифта производит трассировку лучей по карте и перемещает контрольные точки глифа, генерируя геометрию стен псевдо-3D кадра.
Браузерный JavaScript считывает результирующие координаты глифа и отрисовывает пиксели.
5. Почему это исторически обожали безопасники
Шрифтовой стек — один из самых уязвимых компонентов ОС. Исторически (до Windows 10 версии 1709) парсер и интерпретатор TrueType в Windows находились прямо в пространстве ядра (win32k.sys / GDI), чтобы ускорить рендеринг GUI.
Сложная стековая VM, исполняющая недоверенный байт-код из загруженного файла (через веб-страницу или документ Office), регулярно страдала от:
Out-of-bounds чтения/записи в Storage Area или Twilight Zone;
Целочисленных переполнений при вычислении координат;
Повреждения внутреннего состояния стека.
Пример: Знаменитый эксплойт Duqu (CVE-2011-3402) эксплуатировал именно ошибку интерпретатора TTF в ядре Windows для получения нулевого кольца (Ring 0). В современных системах разбор шрифтов вынесен в песочницы (например, font-drvhost.exe в Windows), но парсеры FreeType, DirectWrite и CoreText остаются объектом пристального фаззинга.