В компьютерной науке анализ программ [1] — это процесс автоматического анализа поведения компьютерных программ относительно таких свойств, как корректность, надежность, безопасность и жизнеспособность. Анализ программ фокусируется на двух основных областях: оптимизация программ и корректность программ . Первая фокусируется на улучшении производительности программы при одновременном снижении использования ресурсов, а вторая фокусируется на обеспечении того, чтобы программа делала то, что должна делать.
Анализ программы может быть выполнен без ее выполнения ( статический анализ программы ), во время выполнения ( динамический анализ программы ) или в комбинации обоих методов.
В контексте корректности программы статический анализ может обнаружить уязвимости на этапе разработки программы. [2] Эти уязвимости легче исправить, чем те, которые были обнаружены на этапе тестирования, поскольку статический анализ позволяет выявить корень уязвимости.
Из-за того, что многие формы статического анализа являются вычислительно неразрешимыми , механизмы его выполнения не всегда могут завершаться правильным ответом. Это может привести либо к ложным отрицательным результатам («проблем не обнаружено», когда в коде на самом деле есть проблемы), либо к ложным положительным результатам , или потому, что они могут никогда не возвращать неправильный ответ, но также могут никогда не завершаться. Несмотря на эти ограничения, статический анализ все еще может быть ценным: первый тип механизма может сократить количество уязвимостей, в то время как второй может иногда обеспечивать надежную гарантию отсутствия определенных классов уязвимостей.
Неправильные оптимизации крайне нежелательны. Поэтому в контексте оптимизации программ существуют две основные стратегии для обработки вычислительно неразрешимого анализа:
Однако существует и третья стратегия, которая иногда применима для языков, которые не полностью определены, таких как C. Оптимизирующий компилятор может генерировать код, который делает что угодно во время выполнения — даже аварийно завершает работу — если он сталкивается с исходным кодом, семантика которого не определена используемым стандартом языка.
Целью анализа потока управления является получение информации о том, какие функции могут быть вызваны в различных точках во время выполнения программы. Собранная информация представлена графом потока управления (CFG), где узлы являются инструкциями программы, а ребра представляют поток управления. Идентифицируя блоки кода и циклы, CFG становится отправной точкой для оптимизаций, выполняемых компилятором.
Анализ потока данных — это метод, разработанный для сбора информации о значениях в каждой точке программы и о том, как они изменяются с течением времени. Этот метод часто используется компиляторами для оптимизации кода. Одним из наиболее известных примеров анализа потока данных является проверка на наличие неисправностей , которая заключается в рассмотрении всех переменных, содержащих предоставленные пользователем данные, которые считаются «неисправными», т. е. небезопасными, и предотвращении использования этих переменных до тех пор, пока они не будут очищены. Этот метод часто используется для предотвращения атак с использованием SQL-инъекций . Проверка на наличие неисправностей может выполняться статически или динамически.
Абстрактная интерпретация позволяет извлекать информацию о возможном выполнении программы без фактического выполнения программы. Эта информация может использоваться компиляторами для поиска возможных оптимизаций или для сертификации программы против определенных классов ошибок.
Системы типов связывают типы с программами, которые удовлетворяют определенным требованиям. Их цель — выбрать подмножество программ языка, которые считаются правильными в соответствии с некоторым свойством.
Проверка типов используется в программировании для ограничения того, как используются программные объекты и что они могут делать. Это делается компилятором или интерпретатором . Проверка типов также может помочь предотвратить уязвимости, гарантируя, что знаковое значение не будет присвоено беззнаковой переменной. Проверка типов может выполняться статически (во время компиляции), динамически (во время выполнения) или комбинацией обоих.
Статическая информация о типе ( выведенная или явно предоставленная аннотациями типов в исходном коде) также может использоваться для оптимизации, например, для замены упакованных массивов на неупакованные массивы.
Системы эффектов — это формальные системы, разработанные для представления эффектов, которые может иметь выполнение функции или метода. Эффект кодифицирует то, что делается и с помощью чего это делается — обычно называемые видом эффекта и областью эффекта соответственно. [ требуется пояснение ]
Проверка модели относится к строгим, формальным и автоматизированным способам проверки того, соответствует ли модель (которая в данном контексте означает формальную модель фрагмента кода, хотя в других контекстах это может быть модель фрагмента оборудования) заданной спецификации. Благодаря присущей коду конечно-неопределенной природе, а также тому, что и спецификация, и код преобразуются в логические формулы , можно проверить, нарушает ли система спецификацию, используя эффективные алгоритмические методы.
Динамический анализ может использовать знания о программе во время выполнения для повышения точности анализа, а также обеспечивать защиту во время выполнения, но он может анализировать только одно выполнение задачи и может ухудшить производительность программы из-за проверок во время выполнения.
Программное обеспечение должно быть протестировано, чтобы убедиться в его качестве и в том, что оно работает так, как и должно, надежным образом, и что оно не будет создавать конфликтов с другим программным обеспечением, которое может функционировать параллельно с ним. Тесты проводятся путем выполнения программы с входными данными и оценки ее поведения и полученного вывода. Даже если требования безопасности не указаны, следует провести дополнительное тестирование безопасности , чтобы убедиться, что злоумышленник не сможет вмешаться в программное обеспечение и украсть информацию, нарушить нормальную работу программного обеспечения или использовать его в качестве опорной точки для атаки на его пользователей.
Мониторинг программ записывает и регистрирует различные виды информации о программе, такие как использование ресурсов, события и взаимодействия, чтобы ее можно было просмотреть для поиска или точного определения причин ненормального поведения. Кроме того, ее можно использовать для проведения аудита безопасности. Автоматизированный мониторинг программ иногда называют проверкой времени выполнения .
Для заданного подмножества поведения программы нарезка программы состоит в сокращении программы до минимальной формы, которая все еще производит выбранное поведение. Сокращенная программа называется «срезом» и является точным представлением исходной программы в области указанного подмножества поведения. Как правило, нахождение среза является неразрешимой проблемой, но, указав целевое подмножество поведения значениями набора переменных, можно получить приблизительные срезы с помощью алгоритма потока данных. Эти срезы обычно используются разработчиками во время отладки для определения источника ошибок.