
Для такого вот аппаратного ключа администратора нам понадобилось провести статический анализ кода. Как мы это делали - в статье.
Добрый день, уважаемые коллеги!
Хотел бы сегодня рассказать о несколько необычном опыте анализа кода. Предваряю возмущение многих – да, мсье действительно знает толк в извращениях ?
Итак, о них родимых. В одном нашем изделии понадобилось защитить от несанкционированного доступа администраторскую консоль управления, банальный 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)

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

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

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

VladSMR Автор
14.04.2026 04:33Нужен был аппаратный ключ администратора. Позавчера. Разработчик выбрал то, во что хорошо умел. Дополнительными плюсами были открытый код IDE и наработанные библиотеки. Потом уже всплыло, что для статанализа Ардуина подходит не очень. Статья о том, как выкрутились.
Иметь или не иметь - выбор Ваш :-)

SeyKo4
14.04.2026 04:33Просто cppcheck не подточен под wired (анализ кода с кучей макросов, если я правильно понял).И ведь выкрутились.
PS: вряд ли PVS Studio в этом аспекте более продвинута

Andrey2008
14.04.2026 04:33У PVS-Studio нет проблемы с макросами :) Он их раскрывает перед анализом с помощью препроцессора. Собственно, если этого не сделать, ни о каком нормальном анализ кода речь идти не может. Поэтому PVS-Studio работает только с компилируемым кодом и ему нельзя просто "скормить папку с исходниками".
В сложных случаях можно использовать отслеживание сборки, чтобы собрать всю необходимую информацию для анализа – Проверка проектов независимо от сборочной системы (C и C++).
Подробнее про технологии анализа кода, используемые в PVS-Studio: Статический анализатор кода PVS-Studio в 2026: ГОСТ Р 71207, ГОСТ Р 56939, приказ ФСТЭК №117.
Arhammon
Пояснительную бригаду плиз. Что не так со стандартным STM? Белекпил надо было? Или что человек не стал заморачиваться с Кубом и сделал на Ардуине?
VladSMR Автор
Именно
Плюс всё ПО Ардуино с открытым исходным кодом.
AbitLogic
Мне тоже надоели пляски с кубом, но не опустился до Ардуино, сейчас работаю с zed, rust-analyzer, rust, probe-rs, всё тоже открытое