Рендер аппаратного ключа администратора
Рендер аппаратного ключа администратора

Для такого вот аппаратного ключа администратора нам понадобилось провести статический анализ кода. Как мы это делали - в статье.

Добрый день, уважаемые коллеги!

Хотел бы сегодня рассказать о несколько необычном опыте анализа кода. Предваряю возмущение многих – да, мсье действительно знает толк в извращениях ?

Итак, о них родимых. В одном нашем изделии понадобилось защитить от несанкционированного доступа администраторскую консоль управления, банальный COM-порт с мостиком USB-UART на основе FT232. К сожалению, классическое решение с логином/паролем было обставлено целым частоколом формальных требований в виде (1) срока жизни паролей, (2) логирования успешных/неуспешных попыток, (3) минимальной длины паролей, (4) минимальным их алфавитом, (5) требований к применению больших и малых букв, и цифр, и спезнаков, именно «И», а не «ИЛИ». Перечислять можно бы и дальше, но зачем?

Объехать все эти требования по обочине было решено нестандартным путём – поскольку все требования относились к программному продукту, а про аппаратные устройства ничего не было сказано, то мы просто применили АКА – аппаратный ключ администратора. Он втыкается в разрыв USB-кабеля, идущего от АРМ администратора к устройству, и по свободным линиям обменивается с Изделием сообщениями по схеме challenge-response, не передавая напрямую через линии связи общий секрет, при этом перехват сообщений злоумышленнику не даёт ровно ничего. Если кому интересно, как конкретно это сделано – пишите в комменты или в личку.

Поскольку к историческому моменту принятия решения мы все были в жёстком цейтноте, изготовление АКА поручили стажёру. А он возьми и выбери за основу для разработки «голубую пилюлю (BluePill)» и STM32. Возмущаться, спорить и учить вечному было уже некогда, и тимлид, махнув рукой, согласился. Забегая вперёд, скажу, что отказов и/или сбоев АКА как с самого начала не наблюдалось, так и не наблюдается по сей день. Да, наверное, ПЛК на Ардуине – это уже слишком, но костыль и велосипед проходит вполне (рискую быть бит жёлтыми тряпками, но что было, то было).

Всё это было введение. А теперь про анализ кода. Уполномоченные принимать результат товарищи попросили (таким тоном, что не откажешь) провести ну хотя бы статический анализ кода АКА, чтобы быть уверенными в его качестве. В этом-то и заключалась засада и неприятная неожиданность. Мы рассчитывали на то, что от Ардуинки как от продукта с полностью открытым исходным кодом будет достаточно всех исходников, ан нет.

Шорт-лист продуктов для проверки состоял всего из двух пунктов: Cppcheck и PVS Studio. Гугление, отягощённое признаками ИИ, показало, что последний продукт (А) платный, (Б) больше предназначен для поиска плохо обнаружимых ошибок, не дающих нормально работать гаджету. Жаба оказалась непобедимой и мы выбрали Cppcheck.

Что в Cppcheck хорошо:

  • Можно выбрать нужную архитектуру, STM32 тут имеется. Надо сказать, что работать с кодом для архитектуры ARM Cortex M могут далеко не все анализаторы.

  • Продукт терпим к нестандартному синтаксису, чем обычно знамениты Embedded-приложения.

  • Не требует своего участия в компиляции продукта, работает с чистым исходным кодом.

  • Хорошо детектирует проблемы с неопределённым поведением: с выходом за границы массивов, неинициализированными переменными и утечками памяти.

К сожалению, просто натравить Cppcheck на папку с проектом в Arduino IDE ни к чему хорошему не привело. Первая причина в том, что Arduino IDE по сути работает с неким синтетическим языком (называемым Wired), сделанным в основном из макросов CPP, и пока Cppcheck их все не увидит и не распознает, ничего стоящего не получится.

Вторая причина – Cppcheck по умолчанию не знает, где искать заголовочные файлы для нашего микроконтроллера. Все пути нужно так или иначе указать. И тут вылезает ещё одна засада – сначала мы взяли просто рабочий ноут, на котором разрабатывалось ПО для АКА. Но вот беда – IDE на этом ноуте обросла целой тучей библиотек от других контроллеров, с которыми разработчик имел дело: от ATMega до ESP32. Было даже забавно: первый прогон показал четыре неподключенных библиотеки, мы научили Cppcheck, где их взять, и число нужных include возросло до трёх десятков ☹ В общем, под конец число подключённых библиотек доросло до 6000+

Пришлось собрать «стерильную» IDE на чистом ПК, только с необходимыми библиотеками, и тогда число их немного превышало 2000. В общем, не поленитесь потратить время на чистую сборку – это окупится.

В-третьих, нужно не забыть указать Cppcheck волшебный параметр --platform=arm32-wchar_t4, без которого анализатор не понимает, что имеет дело с архитектурой CortexM.

И наконец, нам оказалось проще расставить в исходном тексте программы в некоторых местах директивы «// cppcheck-suppress <идентификатор_ошибки>», чтобы замаскировать некоторые совсем странные конструкции, которыми иногда пользуется Ардуинка. Опыт показывает, что если этого не делать, то всё равно для того, чтобы аргументированно доказать, что мы имеем дело с ложным срабатыванием анализатора, приходится лезть в исходный код. Пусть уж лучше маскирующая директива и пояснение к ней сразу будут в коде – это экономит время.

К нашему удивлению, Cppcheck на нашем весьма небольшом коде нашёл с десяток недочётов, с которыми автор согласился и исправил. Ещё одно интересное наблюдение – все ошибки находились в написанном нами коде, в библиотеках ни одной Cppcheck не обнаружил. Правда, источником библиотек были Arduino IDE и проект STM32Duino, мусорного кода из сомнительных источников мы не тянули.

В заключение хочу сказать, что если Вам нужно разобраться с нестабильным поведением Вашего Embedded-решения, провести вот прямо очень серьёзный статический анализ, Вы используете серьёзные решения, а не Arduino IDE, то скорее всего Вашим выбором должна стать PVS Studio.

Для полноты картины - рендер обратной стороны АКА. Если кому интересно, пишите в комменты или в личку - выложу фото.

Комментарии (10)


  1. Arhammon
    14.04.2026 04:33

    А он возьми и выбери за основу для разработки «голубую пилюлю (BluePill)» и STM32.

    Пояснительную бригаду плиз. Что не так со стандартным STM? Белекпил надо было? Или что человек не стал заморачиваться с Кубом и сделал на Ардуине?


    1. VladSMR Автор
      14.04.2026 04:33

      не стал заморачиваться с Кубом и сделал на Ардуине

      Именно

      Плюс всё ПО Ардуино с открытым исходным кодом.


      1. AbitLogic
        14.04.2026 04:33

        Мне тоже надоели пляски с кубом, но не опустился до Ардуино, сейчас работаю с zed, rust-analyzer, rust, probe-rs, всё тоже открытое


  1. Rinat111
    14.04.2026 04:33

    Зачем использовать Arduino IDE в проекте с STM32? Есть же Cube Ide или на крайняк arm eabi компилятор.


    1. Goron_Dekar
      14.04.2026 04:33

      Чтобы использовать наработки комьюнити, часть из которых за 20 лет существования отлизаны вот прямо до идеального состояния.

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


      1. Am0k-HABR
        14.04.2026 04:33

        Куб не дотягивает по надёжности до Arduino IDE? Даже на не любимом всеми HAL код намного меньше и уж точно надежнее чем на смеси wiring и stm32duino.


  1. flankerus
    14.04.2026 04:33

    чем clang не устроил?


  1. VladSMR Автор
    14.04.2026 04:33

    Нужен был аппаратный ключ администратора. Позавчера. Разработчик выбрал то, во что хорошо умел. Дополнительными плюсами были открытый код IDE и наработанные библиотеки. Потом уже всплыло, что для статанализа Ардуина подходит не очень. Статья о том, как выкрутились.

    Иметь или не иметь - выбор Ваш :-)


    1. SeyKo4
      14.04.2026 04:33

      Просто cppcheck не подточен под wired (анализ кода с кучей макросов, если я правильно понял).И ведь выкрутились.

      PS: вряд ли PVS Studio в этом аспекте более продвинута


      1. Andrey2008
        14.04.2026 04:33

        У PVS-Studio нет проблемы с макросами :) Он их раскрывает перед анализом с помощью препроцессора. Собственно, если этого не сделать, ни о каком нормальном анализ кода речь идти не может. Поэтому PVS-Studio работает только с компилируемым кодом и ему нельзя просто "скормить папку с исходниками".

        В сложных случаях можно использовать отслеживание сборки, чтобы собрать всю необходимую информацию для анализа – Проверка проектов независимо от сборочной системы (C и C++).

        Подробнее про технологии анализа кода, используемые в PVS-Studio: Статический анализатор кода PVS-Studio в 2026: ГОСТ Р 71207, ГОСТ Р 56939, приказ ФСТЭК №117.