Thunking-слой¶
Thunking-слой (от англ. thunk — «заглушка», «преобразователь») — это программный механизм, обеспечивающий совместимость между 32-разрядными (x86) и 64-разрядными (x64) приложениями и системными компонентами в операционных системах, в частности в Microsoft Windows. Он представляет собой набор системных библиотек и драйверов, которые транслируют вызовы функций, передаваемые данные и структуры из одной «разрядной» среды в другую, позволяя 32-разрядному коду выполняться в 64-разрядной операционной системе без необходимости перекомпиляции.
¶Принцип работы
Основная задача thunking-слоя — преобразование вызовов между двумя разными архитектурами. В контексте Windows это называется WOW64 (Windows 32-bit on Windows 64-bit). Когда 32-разрядное приложение запускается в 64-разрядной среде, оно не может напрямую обращаться к 64-разрядным системным библиотекам (DLL) из-за различий в размере указателей (4 байта против 8 байт), структурах данных и соглашениях о вызовах. Thunking-слой перехватывает такие вызовы:
- Перехват вызова: 32-разрядное приложение вызывает функцию, например, из kernel32.dll. WOW64-прослойка (thunk) перехватывает этот вызов.
- Преобразование параметров: Thunk преобразует 32-разрядные указатели в 64-разрядные, корректирует структуры данных (например, выравнивание) и переупаковывает аргументы в соответствии с 64-разрядным соглашением о вызовах.
- Вызов 64-разрядной функции: Преобразованный вызов направляется в 64-разрядную версию системной библиотеки.
- Обратное преобразование: Результат выполнения функции (возвращаемое значение, изменённые структуры) преобразуется обратно в 32-разрядный формат и передаётся приложению.
Thunking-слой работает на уровне пользовательского режима, не затрагивая ядро операционной системы напрямую. Однако для некоторых операций, связанных с реестром, файловой системой и системными вызовами, используются дополнительные механизмы перенаправления.
¶История и развитие
¶Появление 64-разрядных систем
С переходом на 64-разрядную архитектуру (x86-64, также известную как AMD64 или Intel 64) в начале 2000-х годов возникла проблема обратной совместимости. Множество существующих приложений было написано для 32-разрядной платформы, и их полный перезапуск (перекомпиляция под x64) был невозможен или нецелесообразен. Microsoft в Windows XP Professional x64 Edition (2005 год) и последующих версиях (Windows Vista, 7, 8, 10, 11) внедрила подсистему WOW64 как основной thunking-слой.
¶WOW64 в Windows
WOW64 — это не просто один слой, а совокупность компонентов:
- 32-разрядные библиотеки-заглушки: Файлы вроде wow64.dll, wow64win.dll, wow64cpu.dll. Они загружаются в 32-разрядное приложение и эмулируют 64-разрядную среду.
- Перенаправление реестра и файловой системы: 32-разрядные приложения видят «виртуальные» ветки реестра (например,
HKLM\Software\WOW6432Node) и папки (C:\Program Files (x86)), чтобы не конфликтовать с 64-разрядными программами. - Эмуляция системных вызовов: Некоторые 32-разрядные системные вызовы (например, для работы с памятью или процессами) транслируются в 64-разрядные эквиваленты.
¶Альтернативные реализации
Помимо Windows, thunking-слои существуют и в других ОС:
- Linux: Для запуска 32-разрядных приложений на 64-разрядных ядрах используется набор 32-разрядных библиотек (например, libc6-i386) и механизм совместимости на уровне ядра (ia32el). Однако полноценного thunking-слоя, аналогичного WOW64, нет — чаще используется изоляция через контейнеры или эмуляцию.
- macOS: В macOS до версии 10.15 (Catalina) существовала поддержка 32-разрядных приложений через 32-битные библиотеки и ядро, но без специального thunking-слоя — они работали напрямую, если система была собрана с поддержкой 32-бит. Начиная с macOS 10.15, 32-битная поддержка полностью удалена.
- Эмуляторы: В некоторых случаях (например, Wine на Linux) thunking-слой может быть реализован через эмуляцию, но это уже выходит за рамки нативной совместимости.
¶Классификация thunking-слоёв
Thunking-слои можно классифицировать по способу реализации и области применения:
¶По типу преобразования
- Трансляция системных вызовов: Преобразование вызовов API между разными версиями ОС или архитектурами (например, WOW64).
- Трансляция данных: Преобразование форматов данных (например, структур, строк) между разрядностями.
- Трансляция протоколов: Используется в сетевых или межпроцессных взаимодействиях (например, преобразование 32-битных RPC-вызовов в 64-битные).
¶По месту в системе
- Пользовательский режим: Работает в пространстве пользователя, как WOW64. Это наиболее распространённый тип.
- Режим ядра: Встраивается в ядро ОС для поддержки старых драйверов или системных вызовов (например, в Windows есть 32-битный слой совместимости для драйверов, но он ограничен).
¶По архитектуре
- Однонаправленный: Только от 32-бит к 64-бит (как в WOW64). Обратное (64-бит к 32-бит) обычно не требуется, так как 64-битные приложения могут загружать только 64-битные библиотеки.
- Двунаправленный: Используется в редких случаях, например, при эмуляции целых платформ (QEMU, эмуляторы игровых консолей).
¶Технические детали реализации
¶Структура WOW64
В Windows thunking-слой WOW64 состоит из нескольких ключевых DLL:
- wow64.dll: Основной диспетчер, управляющий загрузкой 32-разрядных приложений и преобразованием вызовов.
- wow64win.dll: Обрабатывает вызовы к подсистеме Windows (USER32, GDI32), преобразуя их в 64-разрядные.
- wow64cpu.dll: Эмулирует 32-разрядный процессорный режим для некоторых инструкций, хотя в основном используется аппаратная поддержка (процессор может переключаться между 32- и 64-битными режимами).
¶Проблемы производительности
Thunking-слой вносит накладные расходы:
- Каждый вызов API требует преобразования параметров, что может замедлить работу приложения на 5–15% в зависимости от частоты вызовов.
- Особенно критичны вызовы к графическим функциям (GDI, DirectX), где преобразование структур может быть сложным.
- Для уменьшения задержек Microsoft оптимизировала WOW64: многие вызовы кэшируются, а некоторые функции (например, математические) транслируются напрямую без thunking.
¶Ограничения
- Невозможность загрузки 64-битных библиотек: 32-разрядное приложение не может напрямую использовать 64-разрядные DLL или драйверы.
- Проблемы с памятью: 32-разрядные приложения ограничены 4 ГБ виртуальной памяти (на практике до 3–3,5 ГБ), даже в 64-разрядной ОС.
- Конфликты реестра и файлов: Разделение на «виртуальные» папки и ветки реестра может привести к путанице, если приложение не рассчитано на это.
¶Применение
¶Обратная совместимость
Основное применение — запуск старых 32-разрядных приложений в 64-разрядных операционных системах. Это критически важно для:
- Корпоративного сектора: Многие бизнес-приложения (бухгалтерия, ERP-системы) были написаны для 32-бит и не обновлялись.
- Игровой индустрии: Старые игры (до 2010-х годов) часто 32-битные, и без thunking-слоя они бы не работали на современных ПК.
- Научных и инженерных программ: Специализированный софт, разработанный десятилетия назад.
¶Разработка и тестирование
Thunking-слои используются разработчиками для тестирования совместимости приложений, а также для создания «мостов» между разными версиями API (например, в эмуляторах или виртуальных машинах).
¶Встраиваемые системы
В некоторых встраиваемых системах (например, на базе ARM) thunking-слои применяются для запуска x86-приложений, хотя это менее распространено из-за высокой производительности эмуляции.
¶Критика и альтернативы
¶Критика WOW64
- Производительность: Как упоминалось, thunking замедляет работу, особенно для приложений, интенсивно использующих системные вызовы.
- Сложность поддержки: Microsoft вынуждена поддерживать WOW64 в каждой новой версии Windows, что увеличивает размер ОС и потенциальные уязвимости.
- Ограничения 32-бит: Даже с thunking-слоем 32-разрядные приложения не могут использовать преимущества 64-битной архитектуры (больше памяти, лучшая производительность).
¶Альтернативы
- Полная перекомпиляция: Идеальный, но часто невозможный вариант.
- Виртуализация: Запуск 32-разрядной ОС внутри виртуальной машины (например, VirtualBox, VMware) даёт полную совместимость, но требует больше ресурсов.
- Эмуляция: Использование эмуляторов (например, QEMU) для запуска 32-битных приложений на 64-битных системах, но это ещё медленнее.
- Контейнеризация: В Linux можно запускать 32-битные приложения в изолированных контейнерах (Docker) с 32-битными библиотеками, что не требует thunking-слоя.
¶Будущее
С постепенным отказом от 32-битных систем (Microsoft прекратила поддержку 32-битных версий Windows 10, а новые процессоры Intel и AMD с 2023 года перестали включать поддержку 32-битного режима в некоторых моделях) thunking-слои становятся менее востребованными. Однако они останутся важным инструментом для обратной совместимости в ближайшие 10–15 лет, пока не будут полностью вытеснены виртуализацией или эмуляцией.
¶Источники
- Microsoft Docs: «WOW64 Implementation Details»
- «Windows Internals, Part 1» (7th Edition) — Pavel Yosifovich, Mark Russinovich, David Solomon, Alex Ionescu
- «Understanding the WOW64 Subsystem» — TechNet Magazine
- «64-bit and 32-bit Application Compatibility in Windows» — Microsoft Support
- «Thunking in Operating Systems» — ACM Computing Surveys
