Violent_Maid @dxe_0x0 Channel on Telegram

Violent_Maid

@dxe_0x0


Low level insanity

Violent_Maid (English)

Are you a fan of mystery and crime-solving? Look no further than the 'Violent_Maid' channel on Telegram, managed by the username @dxe_0x0. This channel is dedicated to all things related to thrilling detective stories, intriguing crime cases, and engaging mysteries. Join us to immerse yourself in a world of suspense, clues, and plot twists. Whether you are a seasoned detective novel reader or just starting to explore the genre, 'Violent_Maid' offers a space for enthusiasts to discuss, share, and discover gripping tales. Stay updated on the latest releases, classic masterpieces, and hidden gems in the world of crime fiction. Connect with like-minded individuals, exchange theories, and engage in thought-provoking discussions. Let your inner detective shine as you follow the breadcrumbs of each story to unravel the truth. Join 'Violent_Maid' today and embark on a thrilling journey into the realm of mysteries and suspense!

Violent_Maid

27 Dec, 18:42


Даров, pirozhki!
Последняя пятничка 24 года — самое время подвести некоторые свои итоги и поделиться планами на ближайшее будущее.

Давайте с итогов:
1. ЯМы сделали внеочередной SMM драйвер для манипуляции с памятью платформы (надо называть бекдоры красиво), при этом параллельно запилив ещё прокладки в виде DXE и R0 драйверов, которые можно преобразовать под ваши нужды. Считайте, что совершенно случайно получилась гигамашина, затрагивающая так или иначе почти все возможные уровни абстрагирования (для красоты ещё не хватает PEIM).
Этот проект дался мне весьма трудно, я работал над ним практически без выходных с апреля по август, параллельно готовясь к защите дипломной работы. Данная приколюха на текущий момент является для меня одной из самых больших и значимых, что я когда-либо делал. Я как горжусь ей, так и искренне ненавижу по ряду личных причин; но, всё же гордость за эту штуковину преобладает, она помогла мне во многом по итогу (а ещё её заметил автор HyperDbg, приятно).
2. Я в Позитиве!!!!!!!!!!11111111111111111
Вчерашнего студента случайно находят ребята из PT, этот уженестудент с дикой тряской сидит на собеседованиях, с такой же дикой тряской делает тестовое и совершенно не ожидает положительного исхода, но получает оффер и не верит своим глазам. Я, так-то, до сих пор отойти не могу. Мне очень приятно попасть сразу на позицию, на которую планировал прорываться в лучшем случае через пару лет. Буду стараться радовать всех деталями о уязвимостях и зиродеечками 😅.
Также весьма приятно понимать, что тебя узнаЮт по твоим наработкам, я счастлив что кому-то интересны такие специфичные темы. Я давно не ощущал себя так, надо признаться.
3. Как вы могли уже догадаться — был пересмотрен немножечко концепт канала. Теперь редко, но зато своё, по-моему это лучше, чем коллекционировать интернет (хоть иногда и нужно).

Что там про будущее? Не очень много, но есть некоторые идеи!
1. У меня в планах провести пару ресёрчей (один точно будет, а второй потребует времени, и, возможно, железа), я планирую с ними поездить немного. Не могу говорить, что будет конкретно, но будет весело, правда!
2. В голове с августа витает идея попробовать побаловаться с режимом энергопотребления S3. У меня уже есть некоторые наработки на этот счёт, но они настолько мизерные, что не имеет смысла расписывать, что там да как.
3. Зиродеечки!!1

Мне немного проблематично поздравлять всех с наступающим, так как теперь вас много! Но я однозначно желаю всем успехов в следующем году!
Держите одну из моих самых любимых смешнявок, которую я уже до дыр затёр c релиза.

Violent_Maid

30 Nov, 00:27


Но мы пришли не за WSMT, а за WPBT! WPBT — это Windows Platform Binary Table. Из названия можно примерно предположить что она делает, но мы будем максимально прямолинейными — она позволяет вам в физическом адресном пространстве ACPI (точнее — EfiAcpiReclaimMemory) хранить PE бинарь, которое загрузит ядро винды во время инициализации Session Manager. Для регистрации таблицы нам соответственно, нужно для начала зарегистрировать данную таблицу. Логично, что делается из UEFI, но для начала нам бы узнать её вид:

typedef struct _WPBT_VIEW {
EFI_ACPI_DESCRIPTION_HEADER Header;
UINT32 HandoffMemSize;
UINT64 HandoffMemLocation;
UINT8 ContentLayout;
UINT8 ContentType;
UINT16 Argc;
UINT64 Argv[1];
} WPBT_VIEW, *PWPBT_VIEW;


Поле Header это стандартное поле для всех ACPI таблиц, содержащее в себе сигнатуру, ревизию, OEM и т.д. Поля HandoffMemSize и HandoffMemLocation относятся к нашему бинарю, которое загрузит Session Manager! Поля ContentLayout и ContentType - константные поля и по спецификации должны всегда равнятся 1. Последние два существуют для шелла. Соответственно, для того, чтоб зарегистрировать таблицу, надо притащить с собой PE бинарь, выделить под него память и записать его туда, затем найти EFI_ACPI_TABLE_PROTOCOL (тык) и вызвать сервис InstallAcpiTable (тык). Позже, когда дело дойдёт до инита Session Manager, он вызовет функу SmpGetPlatformBinary. Внутри происходит следующее: SmpGetPlatformBinary вызывает NtQuerySystemInformation с SYSTEM_INFORMATION_CLASS равным 133. Этот ID вызовет ExpGetSystemPlatformBinary, который сканит физическую память с ACPI таблицами в поиске WPBT и пытается замаппить её содержимое. Когда инфа от WPBT получена, создаётся файл под именем wppbin.exe по пути %systemroot%\System32\wppbin.exe самим Session Manager, а немного попозже запускается соответствующий процесс. Цепочку фунок и их содержимого можно увидеть на скринах 1 и 2.

Касательно проблем абьюза WPBT, их достаточно.
1. Требуется цифровая подпись, что уже порой не так просто заполучить, особенно, если WPBT используется именно для закрепа. Конечно, мы можем заюзать ликнутые серты.
2. Бинарь может быть только приложухой, т.е условной DLL он быть не может.
3. Бинарь может использовать только функи из ntdll, придётся реализовать множество вещей самому.
4. Не уверен, что вам поможет code execution в SMM, если вы атакующий, то есть, вам придётся записывать бинарь с алгосом регистрации WPBT в образ на SPI (ничего конечно не мешает снять SPI Protection, при соответствующих примитивах) и триггерить ресет, а только потом уже DXE Dispatcher сможет зарегать вашу табличку. Во время написания своего смешного SMM драйвера я столкнулся с некоторыми проблемами при работе с ACPI — некоторые сервисы юзают системную таблицу, которая терминируется после вызова ExitBootServices, из-за чего платформа искренне не выкупает и процессор генерит #PF.

Собственно, вот такой интересный метод перзиста в теории может быть, но на практике он весьма трудно реализуем. Зато это можно где-то заюзать в своих ресёрчах.

P.S: Все описания таблиц можно найти самостоятельно. Микромягкие почему-то распространяют их как отдельные документы, поэтому не стал вставлять ссылки на них.

Violent_Maid

30 Nov, 00:27


Даров!

Не секрет для многих — я люблю обскурный и не сильно понятный стафф, это очень весело ковырять что-либо с недостатком инфы. Пока я отвлёкся от расковыра ME (спасибо Горячему, который помогает мне временами) и замашек на PSP — хочу поведать про одну забавную штуку, которая вроде и известная, а вроде и не очень, она весьма всратая и малоюзабельна, но чё бы и нет (я и так хотел её затронуть как-то).

Как известно — Микромягкие любят запускать свои руки во всё что угодно, EFI не исключение, собсна как и ACPI, о котором и пойдёт речь. В ACPI есть такое понятие, как ACPI таблицы, которые содержат в себе различную инфу для конфигурации и настройки платформы, например, там можно найти так мною любимый порт для SW SMI, настройки APIC и многое другое. Ближе к делу: Микромягкие имеют в спецификации как минимум три своих ACPI таблицы — WSMT, WPBT и iBFT. Мы остановимся на первых двух, так как iBFT по сути относится к iSCSI.

Первая расшифровывается как Windows SMM Security Mitigations Table, она появилась с таким больным понятием как VBS и по сути является "описателем" для "защиты" платформы от эксплойтов, нацеленных на SMM (и TrustZone, да, его тоже эта таблица затрагивает). По сути эта таблица представляет из себя битовое поле с тремя параметрами (битами, первый скрин):
1. Фиксированные адреса для буферов для коммуникации. Это включает в себя буферы для протокола EFI_MM_COMMUNICATION_PROTOCOL (тык, + его вторая версия), ACPINVS, различные регистры с указателями на буферы и т.д.
2. Защита "вложенных" указателей — здесь подразумеваются указатели внутри SMM-хендлеров, соответственно, этот бит должен быть выставлен вместе с первым.
3. Защита различных критических ресурсов — он запрещает изменения софтварью таких компонентов, как IOMMU, PCI, FACS, специфичные объекты ACPI и др. после достижения ExitBootServices.
Звучит круто.. Только оно нигде не используется (т.е существует чисто номинально), у всех материнок с которыми я сталкивался — биты равны нулю. Я также нигде не видел, чтоб эти биты где-то кем-то юзались.

Violent_Maid

26 Oct, 02:06


А теперь поговорим о PEIM для обновления Intel ME 😌. Мы немного перешли вниз по чейну загрузки: в PEI фазу, где инициализирован минимум и ещё не произведён переход в DXE фазу. Ниже только SEC (я опущу IBG и PSB здесь, это отдельная тема для разговоров)

PEIM обычно сопровождаются регистрацией или нотификацией определённых дескрипторов (структур). Есть два вида: дескрипторы для нотификаторов и для описателей доступных сервисов для PEI Foundation. Наш PEIM только оповещает определённый PPI (PEIM-to-PEIM Interface). Оба этих дескрипторов имеют одинаковый вид, но я приведу только один, нужный нам:
struct _EFI_PEI_NOTIFY_DESCRIPTOR {
UINTN Flags;
EFI_GUID *Guid;
EFI_PEIM_NOTIFY_ENTRY_POINT Notify;
};

Соответственно, наш PEIM именно что уведомляет платформу о доступном PPI, это видно на первом скрине 😏. Если смотреть на raw вид дескриптора мы имеем следующий вид. Стоит отметить, что дескриптора тут два, но используется конкретно этим PEIM только один (значит, есть в чейне ещё один промежуточный драйвер 😶). Они имеют одинаковые флаги: 80000020 — в нашем случае это означает, что мы смотрим на коллбеки.

Перейдём к коллбекам 😁. Коллбек, который уведомляет наш PEIM по сути просто получает режим загрузки платформы (скрин 3). Этот коллбек служит для верификации режима загрузки (например, чтоб мы случайно не обновились в S3 или S4 😁) уже другими PEIM. Не забываем про второй коллбек, он выглядит намного интереснее (скрин 4) 😏. В первую очередь он получает список всех доступных HOB (Hand-off Block) в платформе на текущий момент, затем, из текущего HOB извлекает структуру, описывающую доступные разделы в прошивке (это, по идее, EFI_FIRMWARE_VOLUME_HEADER, если текущий HOB ею является 😶). Когда структура получена, функция начинает искать определённый раздел с GUID 9F8B1DEF-B62B-45F3-8282-BFD7EA19801B (вы можете похлопать гениальности иды, которая очень плохо жрёт терсы (TE Image)), предварительно валидировав сигнатуру _FVH. Судя по всему, тот раздел используется платформой для содержания образа ME для обновления, наверное 😶. Я не уверен, что этот GUID одинаков в каждой прошивке, но он действительно существует и имеет в себе несколько полей (скрины 5 и 6). После того, как проверка завершилась, платформа обращается к неизвестному мне регистру 0x1800 и 0x1804, а затем пытается ресетнуть платформу через RST_CNT регистр. Сначала ресетает процессор, а затем ресетает что-то неизвестное никому (биты с 4 по 6 зарезервированы, судя по документации) 😳.

Упомяну ещё один неиспользуемый функционал нашего PEIM. Эта штука умеет выходить в длинный режим (скрин 7) 😏😏😏. Она изменяет DTB на какой-то свой, полученный извне, модифицирует CR4 регистр. Что интересно, обычно достаточно только PAE бита, однако, конкретно здесь присутствуют ещё биты для SSE — весьма нестандартно и непонятно зачем. Очевидно, что она ещё сетает бит LME в MSR_EFER и PG бит в CR0, сетапит новый стек и вызывает нужную функцию с новым стеком 😯. Для справки: выход в длинный режим платформой используется только в трёх случаях (минимум): передача управления DXE Core, выход из S3 и работа с капсульными обновлениями. Мы относимся к последнему!

DXE драйвер, который мы вытащили ранее можно найти по GUID A11585B7-8FA2-4F1C-AA6F-DD6309469613. PEIM можно найти по GUID FD27652D-F758-4EFC-B1A9-283EFE51F4E9. Дерзайте 😏😏😏

Violent_Maid

17 Oct, 10:31


da swag
😁😁😁

Violent_Maid

15 Oct, 16:15


Даров! 😳

На днях выловил одну замечательную штуку — DXE драйвер, что регистрирует протокол для обновления прошивки Intel ME. Мне понравилась эта находка, но пока что исключительно в статике.

К сожалению, на данный момент не выловил прямое его использование, хотя желание есть найти хотя бы в статике (это в динамике оч больно тыкать 😁). Но, предполагаю, что использование протокола происходит в следующем порядке: получаем ревизию (ищем HOB с пейлоудом ME) => сравниваем ревизии => тыкаемся в PCI для записи апдейта => сигнализируем об апдейте платформу => отваливаемся перезагружаемся 😁😁😁😂😂😂. Всё просто и понятно, в принципе.

Под капотом помимо стандартного PCI протокола используется несколько других (скрин 2), идентифицировал я только один: HECI, это сугубо интеловский драйвер для работы и общения с периферией. Посмотреть на него можно тута. Оставшиеся протоколы — это WDT_PROTOCOL (судя по всему это Watchdog, но вроде бы у EDK2 был свой протокол для этого) и PLATFORM_SEC_HOOK. Они используются единожды, но инфы как-то о них и нет.

Гораздо интереснее дела обстоят с ревизиями 😁. Intel пошли по правильному пути, у них для пейлоудов есть HOB'ы, которые можно найти самостоятельно по GUID 992C52C8-BC01-4ECD-20BF-F957160E9EF7. Формат такой же, как и везде: есть хидер HOB'а, его "имя" (GUID по которому его можно идентифицировать) и остальная инфа (собственно, пейлоуд в нашем случае). Формат у пейлоуда весьма большой (скрин 3), и, если попытаться, его можно даже достать и сдампить себе (Почему попытаться? Потому что я не уверен, лежит ли оно в локбоксе или нет 🅰️, но из локбокса можно вытащить, просто это больше кода).

Собсна, достучаться и побаловаться с самим протоколом можно через GUID DCA334AB-56E3-4EDE-B9B3-8EAE2ACF5E78, драйвер у нас DXE, так что играться будет проще 😂. У нас также по идее должен лежать PEIM, который, скорее всего, будет работать также, как и с обычными капсульными обновами, только для ME.

Я в комментах оставлю парочку хидеров, где описан формат HOB'ов (честно выдрал из Kabylake) и хидер с форматом протокола обновления 😏 (там есть ещё парочка структур, которых нет в других хидерах), если кому-то интересно сделать что-то самопальное или выдрать что-нибудь 😏😏😏. А я пока в спячку.

Violent_Maid

07 Aug, 00:50


Привет!
Я наконец-то доделал, что хотел. Это заняло неприлично много времени у меня, но что поделать. Я планирую пополнять эту штуку функционалом время от времени, как мне будет что-то приходить в голову интересное.

Насчёт чего-то дальнейшего: у меня есть идеи немного посидеть над ACPI и прочим Power Management stuff, но я пока говорить ничего не буду.

Stay safe!

Violent_Maid

07 Aug, 00:46


https://github.com/0x00Alchemist/Deadwing

Violent_Maid

26 Jul, 18:59


Дарова!

Сразу скажу, ничего не проплачено, я просто делюсь проектом ещё одного своего знакомого (я уже это делал, когда делился CTF ивентом от своего дорогуши).

Ближе к сути. Опять же, один из моих знакомых тут решил поднять тележную конфу/форум по разработке читов и всему присущему (реверс, сесурити). Поэтому, если вам интересно что-то из этого, вы можете присоединиться к конфе смешной. Ссылочка, соответственно: https://t.me/makingcheat

P.S: ведите себя хорошо там!
P.P.S: скорее всего релиз моей штуки будет на следующей неделе. А также расскажу, что ждать от меня далее

Violent_Maid

15 Jul, 23:31


Хорошо, мы зарегистрировали свой хендлер. А как нам общаться, ебать? Платформа предоставляет два протокола для коммуникации, которые доступны нам как в SMM, так и в DXE, а также в последующих фазах, в том числе в рантайме, при условии, что указатель на протокол будет сконвертирован. У нас есть EFI_MM_COMMUNICATION_PROTOCOL и EFI_MM_COMMUNICATION2_PROTOCOL протоколы (1, 2), которые обращаются к SMM Core и триггерят (1, 2) нужный хендлер через сервисы SmiManage или Trigger (1, 2). Учитывая, что данные протоколы конвоируют данные, нам также необходимо хранить где-то данные для хендлера, которые будут позже конвоированы в пространство SMM. Платформа для таких вещей имеет несколько типов пулов: EfiRuntimeServicesData, EfiRuntimeServicesData, EfiReservedMemoryType, EfiACPIMemoryNVS (и вроде бы ещё EfiACPIReclaimMemory, если не ошибаюсь). С другими типами памяти протоколы не работают, так как не предоставляются фазе рантайма.
Где же выделять буфер для коммуникации? В любом месте, кроме как SMM, так как SMRAM закрывается и открывается отдельным протоколом (мы, технически, можем даже это контролировать, неся ущерб целостности платформы), а в эти окошки очень трудно попасть. Единственное релевантное решение, которое я придумал - написание промежуточного рантаймового DXE драйвера, который ловит регистрацию EFI_MM_COMMUNICATION_PROTOCOL/EFI_MM_COMMUNICATION2_PROTOCOL (1, 2), выбрасывает тестовый SMI в ивенте, который триггерит сервис ExitBootServices и ещё один ивент, что конвертирует указатель на проткол, пул памяти и пару функций, реализующих коммуникацию между режимами и публикует пакет данных для модулей ОС. Это удобно, тащемта, несмотря на то, что в итоге мой драйвер находится в HOB, который загружается DXE Core ещё раньше, чем SMM Core.
Я опущу ещё один метод, потому что хочу рассказать ещё о двух менее очевидных, а ко второму "официальному" вернусь позже. Мы можем общаться с "внешним миром" и SMM, неиронично, через NVRAM переменные, при условии, что у нас есть флаг EFI_VARIABLE_NON_VOLATILE. Это может быть удобно в том случае, если целевая ОС реализует возможность регистрировть такие пременные (кеширует сервисы напрямую, я рассказывал об этом здесь, где это можно увидеть на винде, например). Однако, при работе с SMI хендлерами мы не можем обращаться напрямую к рантаймовым сервисом, так как это "не кекурно" и вообще процессор выбросит #PF, потому что вызов данных сервисов будет за SMRAM (очень красиво cтавим классы). Поэтому, нам необходимо предварительно зарегистрировать коллбек на регистрацию протокола EFI_SMM_VARIABLE_PROTOCOL, только тогда мы можем общаться с рантаймом через NVRAM переменные. Мне, лично, этот метод кажется костыльным.
Есть ещё забавный вариант общаться через Save State (это по сути "карта" со всеми регистрами и их состояниями на момент срабатывания перырвания), кешируя в SMM драйвере EFI_MM_CPU_PROTOCOL протокол, я читал, что это работает на CSM системах с легаси прерываниями (например, INT15 D042). Я смотрел, как это работает, и работает оно не очень, подозреваю, что из-за эмуляции.
Перейдём к ещё одному специфическому методу коммуникации - мы можем регистрировать ACPI таблицы определённого типа (но не сразу, только по прошествию какого-то промежутка времени), выделяя физический буфер с типом EfiACPIMemoryNVS или EfiACPIReclaimMemory, эти таблицы позже будут опубликованы для ОС. Это требует от нас возможность регистрировать SW SMI хендлеры, которые уже не доступны при эмуляции. Этим методом пользуется TCG драйвер для работы с TPM. Увы, нет возможности это затестить сейчас.

По правде говоря, у меня сейчас есть некоторые технические шоколадки, которыми я занимаюсь и я опять же не знаю, сколько на это уйдёт времени, но я постараюсь опубликовать это дело в законченном состоянии и оповестить вас, так как не хочу выкидывать на помойку работу, на которую ушло у меня несколько месяцев (могу выкинуть только себя).
Спасибо моим нескольким друзьям, которым я иногда ною по всему этому поводу и они это терпят.

Stay safe. 😅😅😅

Violent_Maid

15 Jul, 23:15


Дарова, блин! 👋👋👋
Мы давно с вами не виделись, пирожочечки!

Я обещал запостить кое-что интересное, однако у меня как всегда не было времени, надо было кое-что закрыть (например, диплом (я получил смешную бумажечку от областных минцифр за это)) и ещё некоторые вещи, что не давали нормально работать. Я всё ещё намерен доделать и выложить это кое-что, но я не могу сказать точно, сколько на это ещё уйдёт времени.
Собственно, поэтому, я пишу сейчас с некоторой информацией, которую я накопил за несколько месяцев работы (часто, ленивой работы). Я не думаю, что вы узнаете что-то новое, но я хочу коротко расписать чем занимаюсь и чтоб паблек не стоял в простое.

Я занимался написанием SMM драйвера, что изначально казалось весьма сложной задачей, однако, по прошествию времени оказалось, что нет, это по сути более аутичное направление разработки (ну, как и вся около-прошивочное/embedded направление(я)) со своими приколами и постприколами. Ближе к сути со следующего абзаца.

Первым вопросом может стать коммуникация с "внешним миром" и SMM. У спецификации инициализации платформы есть несколько "официальных" предложений на этот счёт и ещё парочка неочевидных (один зависит от платформы).
Вся коммуникация, очевидно, происходит через SMI-хендлеры, которые, очевидно, регистрируются нами при первой инициализации SMM (DXE Foundation передаёт "список" драйверов платформы DXE Core, онный запускает SMM Core (не всегда первым)). Мы, в свою очередь, имеем 10 типов хендлеров (по спецификации), но только 4 нам интересны:
1. Root SMI - хендлеры, срабатывающие при каждом SMI, выброшенных платформой.
2. Child SMI - хендлеры, срабатывающие при явном указании SMM Core GUID данных хендлеров.
3. SW SMI - софтварные SMI, срабатывающие через триггер-порт B2, могут принимать данные через порт B3. Триггер-порты теоретически могут меняться, смотрите на FADT/FACP ACPI таблицу.
4. Periodic SMI - из названия, хендлеры, срабатывающие в период N времени.
5. SX SMI - хендлеры Sleep State (S0 - S5 или G1 -G3, если описывать комплексно).
6. USB SMI - хендлеры, что срабатывают при подключении USB устройств.
7. GPI SMI - General Purpose Input, не уверен за что они отвечают.
8. Standby SMI - хендлеры, что триггерятся на нажатие кнопки ожидания.
9. Power Button SMI - хендлеры, что триггерятся на нажатие кнопки питания.
10. I/O Trap SMI - хендлерры, обрабатывающие специфичные адреса/диапазоны I/O процессора.

Я работал с первыми тремя и самым удобным оказался в итоге второй вариант, так как для него завезён нормальный протокол в двух его версиях (1, 2). Последний имеет в себе возможность работать с виртуальными адресами (а ещё он реализован как отдельный драйвер на армах). Если мы работаем с рутовыми хендлерами, то их суть заключается в том, что они срабатывают при каждом выброшенном SMI. Это не совсем релевантно, так как им не очень удобно передавать пул памяти, в котором может содержаться необходимая информация (о пулах я скажу позже). Дебажить рутовые хендлеры также не сильно удобно при отладке бутовых фаз (DXE, BDS, TSL), так как, опять же, процессор в этих фазах выбрасывает их достаточное количество.
Интереснее обстоит вопрос с софтварными хендлерами (SW SMI). Видите ли, пирожочки, в основном отладка подобных вещей в первую очередь производится на QEMU и подобных вещах, а только потом на реальных машинах. Так вот, OVMF (образ прошивки для QEMU и подобных) не подразумевает реализацию протокола EFI_MM_SW_DISPATCH_PROTOCOL в виду некоторых хардварных особенностей. Этот протокол регистрируют "silicon-based" драйвера, которые не могут эмулироваться в виду тех или иных особенностей. В теории, нам ничего не мешает написать собственные драйвера или портировать один из предложенных (1, 2) с заменой и переработкой некоторых функций (например, этой), но это не входит в мои текущие задачи. Мы можем "эмулировать" работу софтварных хендлеров, регистрируя, например, рутовый хендлер, записывать в порт B2 номер хендлера и читать порт в хендлере, сравнивая значения из порта с нашим. На мой взгляд это кринжово и костыльно.