Главная / Кейсы / PC Control
Эксплуатация 24/7 IoT & Systems Architecture Windows 10 / 11 Kernel ESP8266 Bare-Metal C++

PC Control: распределенная система внеполосного управления и разблокировки рабочей станции

Инженерный разбор гибридного контура управления настольным ПК: от импульсного замыкания контактов питания материнской платы до защищенной инжекции в защищенный рабочий стол Windows Winlogon и облачной FSM-оркестрации по MQTT TLS.

Ключевое инженерное решение: авторизация без USB HID эмулятора
В традиционных проектах для удаленного ввода пароля используют дорогие микроконтроллеры с аппаратным USB HID (ESP32-S3, RP2040, Leonardo), которые определяются операционной системой как физическая клавиатура и постоянно занимают USB-порт. Здесь разблокировка Windows 10 реализована на базовом контроллере ESP8266, который в принципе не имеет USB-стека. Контроллер берет на себя физический контур питания (ATX PWR_SW) и аппаратный замок Морзе, а ввод пароля делегируется системному агенту Session 0. Агент преодолевает изоляцию сессий через защищенную инжекцию в десктоп Winlogon и транслирует виртуальные скан-коды напрямую в подсистему ввода ядра.
Время разблокировки
1.4 – 1.8 с
Полный цикл авторизации со сбросом шторки
Аппаратные USB-донглы
0 шт
Никаких эмуляторов клавиатуры и занятых портов
Окно верификации выключения
20 с
Защита от фантомных сетевых пакетов
Тестовое покрытие
194 теста
Unit, FSM, сетевые сбои и Win32 API
Глубина архива метрик
30 дней
Срез активности окон и сети в SQLite WAL

Интерактивное моделирование цикла запуска

Запустите симуляцию, чтобы визуально проследить прохождение импульса через всю цепь: от физического реле на контактах платы до инжекции виртуальных клавиш в защищенный стол входа Windows.

Контур прохождения сигналов системы
ШАГ 1 • ESP8266
Импульс ATX PWR_SW
GPIO5 HIGH • 500мс
ШАГ 2 • ЖЕЛЕЗО / ОС
POST & Kernel-Boot
UEFI BIOS • Event ID 27
ШАГ 3 • SESSION 0
WTS API & PsExec
login_screen ➔ Desktop -x
ШАГ 4 • WINLOGON
Скан-коды и вход
VkKeyScanW ➔ UNLOCKED
[IDLE] Нажмите «Запустить моделирование старта», чтобы увидеть трассировку событий в реальном времени...

Сквозная топология и протоколы передачи

Система разделена на изолированные контуры безопасности. Ни один пользовательский процесс не имеет доступа к системным паролям, а микроконтроллер изолирован от прямого доступа к файловой системе Windows.

topology_map.txt — PC Control System Overview TLS 1.3 / QoS 1
┌────────────────────────────────────────────────────────────────────────────────────────┐
│                             КЛИЕНТСКИЙ ИНТЕРФЕЙС TELEGRAM                              │
│     • Мобильный клиент / Desktop   • Custom Emoji UI   • Интерактивные кнопки          │
└───────────────────────────────────────────┬────────────────────────────────────────────┘
                                            │ HTTPS (Bot API)
                                            ▼
┌────────────────────────────────────────────────────────────────────────────────────────┐
│                         ОБЛАЧНЫЙ КООРДИНАТОР VDS (Ubuntu Linux)                        │
│  Хостинг: api.w1bbex.ru • systemd: pc-control-bot.service (User: pccontrol, Sandboxed) │
│                                                                                        │
│  ┌────────────────────────┐  ┌────────────────────────┐  ┌──────────────────────────┐  │
│  │     power_flow.py      │  │    health_engine.py    │  │       history.py         │  │
│  │  Конечный автомат FSM  │  │  Фильтр Retain-пакетов │  │  SQLite WAL Хранилище    │  │
│  │  Атомарный State JSON  │  │  20с окно тишины сети  │  │  Серверный Matplotlib    │  │
│  └───────────┬────────────┘  └───────────┬────────────┘  └──────────────────────────┘  │
│              └─────────────────────┬─────┘                                             │
│                                    ▼                                                   │
│                      Брокер Mosquitto MQTT (Порт 8883, TLS 1.2/1.3)                    │
└────────────────────────────────────┬───────────────────────────────────────────────────┘
                                     │
             ┌───────────────────────┴────────────────────────┐
             │ MQTT TLS (Wi-Fi)                               │ MQTT TLS (Tailscale / WAN)
             ▼                                                ▼
┌─────────────────────────────────────────┐   ┌──────────────────────────────────────────┐
│      АППАРАТНЫЙ УРОВЕНЬ (ESP8266)       │   │        ЛОКАЛЬНЫЙ ХОСТ ПК (WINDOWS)       │
│                                         │   │                                          │
│  • Микроконтроллер: ESP8266 (160 МГц)   │   │ ┌──────────────────────────────────────┐ │
│  • Реле: GPIO5 (D1) на контакты PWR_SW  │   │ │ SESSION 0: boot_agent.py (SYSTEM)    │ │
│  • Кнопка кейса: GPIO14 (D5, IRAM ISR)  │   │ │ • Запуск при старте ОС (Планировщик) │ │
│  • Стейт-машина замка Морзе (EEPROM)    │   │ │ • WTS API (честные статусы экрана)   │ │
│  • BearSSL TLS 1.2 (PROGMEM X.509)      │   │ │ • Мост сенсоров LibreHardwareMonitor │ │
│  • Акустическая пасхалка: playRelayBeat │   │ │ • Вызов PsExec64 -s -x -i            │ │
└────────────────────┬────────────────────┘   │ └──────────────────┬───────────────────┘ │
                     │ Физический             │                    │ PsExec64 -s -x -i   │
                     │ импульс ATX            │                    ▼                     │
                     ▼                        │ ┌──────────────────────────────────────┐ │
┌─────────────────────────────────────────┐   │ │ ДЕСКТОП WINLOGON: type_password.py   │ │
│    КОНТАКТЫ PWR_SW МАТЕРИНСКОЙ ПЛАТЫ    │   │ │ • SetThreadDesktop(hDeskWinlogon)    │ │
│  • Короткий клик: 500 мс (включение)    │   │ │ • Сброс шторки блокировки            │ │
│  • Удержание: 5000 мс (аварийный сброс) │   │ │ • Скан-коды клавиш (VkKeyScanW)      │ │
└─────────────────────────────────────────┘   │ └──────────────────┬───────────────────┘ │
                                              │                    │ Успешный вход       │
                                              │                    ▼                     │
                                              │ ┌──────────────────────────────────────┐ │
                                              │ │ SESSION 1+: agent.py (User Desktop)  │ │
                                              │ │ • Запуск при интерактивном входе     │ │
                                              │ │ • Опрос окон (3с poll, SQLite WAL)   │ │
                                              │ │ • Извлечение иконок GDI -> TG Emoji  │ │
                                              │ │ • Бинарный JPEG-протокол скриншотов  │ │
                                              │ │ • WinRT GSMTC + PyCaw (CoreAudio)    │ │
                                              │ └──────────────────────────────────────┘ │
                                              └──────────────────────────────────────────┘
Главное меню бота PC Control (/menu) — статус сессии, датчики и кнопки действий Команда /menu в Telegram

Центральный пульт управления: дашборд и основные функции

Вместо перегруженных веб-панелей единой точкой входа выступает Telegram-бот. При вызове команды /menu формируется лаконичный статус-отчет и адаптивная клавиатура управления:

  • Мониторинг сессии Windows: честный статус через WTS API (ПК в сети 2 ч 56 мин), адаптивный эмодзи ОС Windows, фиксация активного окна на рабочем столе и текущий играющий трек с кастомным эмодзи ❤️.
  • Атомарный срез LibreHardwareMonitor: точная температура и процент загрузки CPU (42% • 46°C), нагрузка видеокарты с отображением потребляемой мощности (45°C • 20.7 Вт), занятая оперативная память (8.4 ГБ / 17.1 ГБ) и разбивка по дискам [C:] и [E:].
  • Пульт быстрых действий: кнопки управления питанием, мгновенное получение скриншота всех мониторов без сжатия в JPEG, лаунчер программ, регулировка звука и кнопка аварийного выключения.

Интерактивный разбор компонентов

Переключайтесь между вкладками для детального анализа физического железа, изоляции ядра Windows, облачного FSM и пользовательского медиа-агента.

Интерактивный анализатор подсистем • Выберите модуль для разбора архитектуры
ARCH_INSPECTOR // V2.0
СИСТЕМНЫЙ ИНВАРИАНТ: АППАРАТНЫЙ КОНТУР

Аппаратный замок Морзе и неблокирующий IRAM-буфер: микроконтроллер физически замыкает контакты PWR_SW материнской платы и дебаунсит кнопку в оперативной памяти без эмуляции USB HID и без блокировки сетевого стека.

Микроконтроллер ESP8266 на частоте 160 МГц

Прошивка написана на C++ и оптимизирована для работы в условиях нестабильного Wi-Fi и жестких ограничений оперативной памяти (heap < 10 KB). Все критические обработчики кнопок выполняются в оперативной памяти контроллера.

  • Неблокирующая очередь ISR: прерывание кнопки вынесено в IRAM_ATTR и пишет события в кольцевой буфер на 16 элементов с дебаунсом 35 мс.
  • Замок Морзе: распознавание кликов (< 500мс) и удержаний (≥ 500мс). Защищен фильтром тишины: 5 секунд до ввода и 3 секунды после.
  • Анти-брутфорс в EEPROM: 3 неверных ввода блокируют кнопку с записью контрольной суммы XOR в энергонезависимую память. Сброс только по MQTT.
pc_remote_mqtt.ino
// Кольцевой буфер прерываний кнопки в IRAM
void IRAM_ATTR physicalButtonISR() {
  unsigned long now = millis();
  int pinState = digitalRead(PHYSICAL_BUTTON_PIN);
  uint8_t nextHead = (isrQueueHead + 1) % ISR_QUEUE_SIZE;
  if (nextHead != isrQueueTail) {
    isrTimeQueue[isrQueueHead] = now;
    isrStateQueue[isrQueueHead] = pinState;
    isrQueueHead = nextHead;
  }
}
Интерактивный эмулятор аппаратного замка Морзе (GPIO14)

Проверьте работу физического алгоритма: зажимайте кнопку на нужное время. Короткий клик (< 500мс) распознается как «К» (•), зажатие (≥ 500мс) — как «Д» (—).

Анти-брутфорс EEPROM:
Целевой код замка: К — Д — К — К — Д
1 К • <500мс
2 Д — ≥500мс
3 К • <500мс
4 К • <500мс
5 Д — ≥500мс
500мс
Короткий клик (<500мс) Удержание (≥500мс)
Статус контроллера GPIO14
Ожидание ввода... Зажмите кнопку для первого символа.
СИСТЕМНЫЙ ИНВАРИАНТ: ИЗОЛЯЦИЯ SESSION 0

Преодоление изоляции Session 0 через PsExec64 -x: запуск скрипта ввода пароля прямо на защищенном столе Winlogon с эмуляцией скан-кодов VkKeyScanW и аварийным выходом при несовпадении десктопа.

Низкоуровневые хуки Win32 и изоляция сессий

Системный агент запускается из-под учетной записи NT AUTHORITY\SYSTEM в Session 0. Он не имеет графического контекста, но обладает правами взаимодействовать с Service Control Manager и рабочими столами Windows.

  • Консенсус WTS API: опрашиваются WTSGetActiveConsoleSessionId, флаг WTSSessionInfoEx и дескриптор OpenInputDesktop.
  • Инжекция через PsExec64: вызов с флагом -x запускает поток непосредственно на защищенном столе входа hDeskWinlogon.
  • Защитный аборт ввода: если за 5 секунд имя десктопа не переключилось в Winlogon, скрипт завершается без ввода символов (код 2).
type_password.py
# Привязка потока к активному десктопу ввода
hDesk = user32.OpenInputDesktop(0, False, DESKTOP_SWITCHDESKTOP)
user32.SetThreadDesktop(hDesk)

# Проверка защитного барьера Winlogon
if get_desktop_name() != "Winlogon":
    sys.exit(2)  # Экстренный выход без ввода пароля

# Трансляция скан-кодов и эмуляция ввода
for char in password:
    vk = user32.VkKeyScanW(ord(char))
    user32.keybd_event(vk & 0xFF, 0, 0, 0)
СИСТЕМНЫЙ ИНВАРИАНТ: КОНЕЧНЫЙ АВТОМАТ FSM

Фильтр Retain-призраков и 20-секундное окно тишины: брокер отбрасывает любые устаревшие команды при реконнекте, а статус выключения фиксируется только после 20 секунд непрерывного отсутствия обоих агентов.

Конечный автомат FSM и фильтрация сетевых призраков

Облачный координатор на Linux VDS выступает единым источником правды. Он транслирует команды только при подтвержденных переходах FSM и страхует систему от распространенных багов брокеров сообщений.

  • Фильтр Retained-пакетов: отбрасывание любых пакетов с msg_ts < last_ts для защиты от фантомных команд перезагрузки при реконнекте.
  • Окно выключения 20 секунд: статус SHUTDOWN фиксируется только при непрерывном отсутствии heartbeat от обоих агентов в течение 20 секунд.
  • Атомарный деплой: скрипт deploy_vds.py считает SHA-256, проводит preflight-импорты и откатывает релиз при первой ошибке в journalctl.
health_engine.py
# Защита от фантомных пакетов с устаревшим timestamp
if packet_ts < component.last_valid_ts:
    logger.warning("Dropped outdated MQTT packet")
    return

# Верификация отключения хоста
if silent_duration >= 20.0 and agents_offline:
    self.state = PCState.SHUTDOWN_OBSERVED

Серверная аналитика и графики телеметрии (Matplotlib + SQLite WAL)

Все телеметрические срезы с агентов Windows непрерывно агрегируются в локальную базу SQLite на VDS. Для исключения перегрузки сети бот не передает миллионы сырых точек на телефон, а на лету генерирует темный четырехслойный дашборд через Matplotlib.

Точек в базе: 117 482
Периоды: 1ч • 6ч • 24ч • 7д • 30д
Сетевой трафик: до 125 Мбит/с
График телеметрии нагрузки CPU/GPU, температур, памяти и сети за 30 дней (117k точек) Генерация на VDS • 30 дней истории
СИСТЕМНЫЙ ИНВАРИАНТ: ИНТЕРАКТИВНЫЙ DESKTOP

WinRT GSMTC и динамический экспорт GDI-иконок: прямое управление треками Яндекс Музыки («Моя Волна») и автоматическая сборка нативных пиктограмм 256x256 в Telegram Custom Emoji.

Интерактивная сессия, WinRT GSMTC и GDI иконки

Пользовательский агент в Session 1+ обслуживает мультимедиа и интерфейс Telegram. Все тяжелые вызовы дедуплицированы и оптимизированы для нулевой нагрузки на процессор.

  • Локальный якорь времени GSMTC: расчет позиции трека через _anchor + (time - anchor_time) исключает ежесекундные COM-запросы к Explorer.
  • GDI экстрактор иконок: извлечение 256x256 иконок через PrivateExtractIconsW, исправление альфа-канала и заливка в Telegram Custom Emoji.
  • Бинарный протокол скриншотов: 4 байта длины uint32 BE + JSON заголовок + сжатый JPEG с валидацией сигнатур 0xFF 0xD8.
media_manager.py
# Локальный субсекундный расчет времени трека (0% CPU)
def get_current_position(self):
    if not self.is_playing:
        return self._anchor_pos
    elapsed = time.time() - self._anchor_time
    return min(self.duration, self._anchor_pos + elapsed)
Пульт управления музыкой в Telegram — таймлайн, навигация и Моя Волна WinRT GSMTC • Пульт плеера

Полноценный пульт музыки в боте

В большинстве DIY-систем мультимедиа игнорируется, но здесь реализован полноценный медиа-пульт прямо в чате Telegram. Через Windows Runtime GSMTC бот перехватывает метаданные любого системного плеера (Яндекс Музыка, Spotify, VK, браузер).

  • Интерактивный таймлайн: отображение прогресса трека (01:04 / 02:15), автор и название композиции (sekairotten, pas de vie).
  • Полный контроль трека: пауза, перемотка на ±10 секунд, переключение треков («Пред» / «След») и добавление в избранное.
  • «Моя Волна»: отдельная выделенная кнопка для быстрого запуска персонального бесконечного радиопотока в Яндекс Музыке.
Кастомный эмодзи-пак иконок приложений Windows (PC Control App Icons) GDI Win32 • Custom Emoji Pack

Генератор кастомных эмодзи для лаунчера

Модули app_emoji_manager.py и icon_extractor.py связывают файловую систему Windows с интерфейсом Telegram. Бот автоматически сканирует установленные программы на хосте.

  • GDI PrivateExtractIconsW: извлечение нативных иконок высокого разрешения 256x256 без артефактов.
  • Автоматический пак: сборка и загрузка пакета «PC Control App Icons» в Telegram через Bot API.
  • Наглядный запуск: кнопки программ (Steam, Zed, VS Code, GTA V, Torrent, OBS, Chrome) снабжены нативными иконками.

Сводные технические характеристики

Аппаратная платформа
ESP8266 NodeMCU v2
160 МГц Turbo Clock, Wi-Fi 802.11 b/g/n, BearSSL TLS 1.2.
Реле питания ATX
GPIO5 (D1) / 500 мс импульс
Параллельное подключение к кнопке включения материнской платы.
Физический ввод пароля
GPIO14 (D5) / IRAM ISR
Азбука Морзе, защита тишиной (5с/3с), 3-strike EEPROM lock.
Механизм разблокировки
PsExec64 -s -x -i → Winlogon
Переключение на hDeskWinlogon, эмуляция через VkKeyScanW.
Определение сессии
WTS API (5 сигналов)
Различение locked, login_screen, no_console и unlocked.
Сенсоры оборудования
LibreHardwareMonitor .NET
Атомарный срез температур CPU/GPU Hotspot, кулеров и NVMe.
Хранилище телеметрии
SQLite WAL / 30 дней
Динамическое бакетирование от 60с до 7200с, B-Tree индексы.
Тестовое покрытие
194 автоматизированных теста
Тестирование FSM, mock WTS API, Paho socketpair и таймингов.

Анализ решенных инцидентов и краевых случаев

Неочевидные проблемы, выявленные на стыке ядра Windows, сетевого стека Paho MQTT и аппаратных интерфейсов.

Краш Paho MQTT при засыпании Windows (WinError 10054 / 1236)
Критический сбой
В библиотеке paho-mqtt для межпоточных уведомлений на платформе Windows создается локальная сокет-пара. При сетевом разрыве или переходе сетевой карты в энергосберегающий режим сокет закрывался системой, вызывая неперехватываемое исключение и аварийное падение процесса агента.
Решение: внедрен низкоуровневый monkey-patch методов Client._loop и _packet_queue. Ошибки сокет-пары 10054/1236 перехватываются без падения с мягким перезапуском сетевого цикла.
Рекурсивные перезагрузки из-за Retained сообщений брокера
Сетевая аномалия
При реконнекте к MQTT-брокеру Mosquitto клиенты получали старые сохраненные команды выключения или перезагрузки. Это приводило к тому, что только что включившийся компьютер повторно уходил в шатдаун.
Решение: в health_engine.py реализована проверка строгой монотонности временных меток. Любой пакет с msg_ts < last_valid_ts немедленно отбрасывается.
Защита от случайной блокировки учетной записи Windows
Защита от локаута
При удаленном вводе пароля смена раскладки или отсутствие маппинга символа в скан-код могли привести к отправке искаженного пароля и исчерпанию попыток входа в Windows.
Решение: перед началом ввода проверяется маппинг каждого символа через VkKeyScanW. Если хотя бы один символ возвращает ошибку, процедура мгновенно прерывается до отправки нажатия Enter.