Исследование программного кода на предмет ошибок это

Тестирование программного обеспечения.

Тестирование программного обеспечения — процесс исследования программного обеспечения (ПО) с целью получения
информации о качестве продукта.

Введение

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

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

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

С точки зрения ISO 9126, Качество (программных средств) можно определить как совокупную характеристику исследуемого ПО с учётом следующих составляющих:

·        
Надёжность

·        
Сопровождаемость

·        
Практичность

·        
Эффективность

·        
Мобильность

·        
Функциональность

Более полный список атрибутов и критериев можно найти в стандарте ISO 9126 Международной организации по стандартизации. Состав и содержание документации, сопутствующей процессу
тестирования, определяется стандартом IEEE 829-1998 Standard for Software Test Documentation.

История развития тестирования программного обеспечения

Тестирование программного обеспечения

Существует несколько признаков, по которым принято производить классификацию видов тестирования. Обычно выделяют следующие:

По объекту тестирования:

·        
Функциональное тестирование (functional testing)

·        
Нагрузочное тестирование

·        
Тестирование производительности (perfomance/stress testing)

·        
Тестирование стабильности (stability/load testing)

·        
Тестирование удобства использования (usability testing)

·        
Тестирование интерфейса пользователя (UI testing)

·        
Тестирование безопасности (security testing)

·        
Тестирование локализации (localization testing)

·        
Тестирование совместимости (compatibility testing)

По знанию системы:

·        
Тестирование чёрного ящика (black box)

·        
Тестирование белого ящика (white box)

·        
Тестирование серого ящика (gray box)

По степени автоматизированности:

·        
Ручное тестирование (manual testing)

·        
Автоматизированное тестирование (automated testing)

·        
Полуавтоматизированное тестирование (semiautomated testing)

По степени изолированности компонентов:

·        
Компонентное (модульное) тестирование (component/unit testing)

·        
Интеграционное
тестирование (integration testing)

·        
Системное
тестирование (system/end-to-end testing)

По времени проведения тестирования:

·        
Альфа тестирование (alpha testing)

·        
Тестирование при приёмке (smoke testing)

·        
Тестирование новых функциональностей (new feature testing)

·        
Регрессионное тестирование (regression testing)

·        
Тестирование при сдаче (acceptance testing)

·        
Бета тестирование (beta testing)

По признаку позитивности сценариев:

·        
Позитивное тестирование (positive testing)

·        
Негативное тестирование (negative testing)

По степени подготовленности к тестированию:

·        
Тестирование по документации (formal testing)

·        
Эд Хок (интуитивное) тестирование (ad hoc testing)

Уровни тестирования

Модульное тестирование (юнит-тестирование) — тестируется минимально возможный для тестирования компонент, например,
отдельный класс или функция. Часто модульное тестирование осуществляется разработчиками ПО.

Интеграционное тестирование — тестируются интерфейсы между компонентами, подсистемами. При наличии резерва
времени на данной стадии тестирование ведётся итерационно, с постепенным подключением последующих подсистем.

Системное тестирование — тестируется интегрированная система на её соответствие требованиям.

Альфа-тестирование — имитация реальной работы с системой штатными разработчиками, либо реальная работа с системой потенциальными пользователями/заказчиком.
Чаще всего альфа-тестирование проводится на ранней стадии разработки продукта, но в некоторых случаях может применяться для законченного продукта в качестве внутреннего приёмочного тестирования. Иногда альфа-тестирование выполняется под отладчиком или с использованием
окружения, которое помогает быстро выявлять найденные ошибки. Обнаруженные ошибки могут быть переданы тестировщикам для дополнительного исследования в окружении, подобном тому, в котором будет использоваться ПО.

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

Часто для свободного/открытого ПО стадия Альфа-тестирования характеризует функциональное наполнение кода, а Бета тестирования — стадию исправления ошибок. При этом как правило
на каждом этапе разработки промежуточные результаты работы доступны конечным пользователям.

Тестирование «белого ящика» и «чёрного ящика»

В терминологии профессионалов тестирования (программного и некоторого аппаратного обеспечения), фразы «тестирование белого ящика» и «тестирование чёрного ящика»
относятся к тому, имеет ли разработчик тестов доступ к исходному коду тестируемого ПО, или же тестирование выполняется через пользовательский интерфейс либо прикладной программный интерфейс, предоставленный тестируемым модулем.

При тестировании белого ящика (англ. white-box testing, также говорят — прозрачного ящика), разработчик теста имеет доступ к исходному коду программ и может писать код, который
связан с библиотеками тестируемого ПО. Это типично для юнит-тестирования (англ. unit testing), при котором тестируются только отдельные части системы. Оно обеспечивает то, что компоненты конструкции — работоспособны и устойчивы, до определённой степени.
При тестировании белого ящика используются метрики покрытия кода.

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

Если «альфа-» и «бета-тестирование» относятся к стадиям до выпуска продукта (а также, неявно, к объёму тестирующего сообщества и ограничениям на методы тестирования),
тестирование «белого ящика» и «чёрного ящика» имеет отношение к способам, которыми тестировщик достигает цели.

Бета-тестирование в целом ограничено техникой чёрного ящика (хотя постоянная часть тестировщиков обычно продолжает тестирование белого ящика параллельно бета-тестированию). Таким
образом, термин «бета-тестирование» может указывать на состояние программы (ближе к выпуску чем «альфа»), или может указывать на некоторую группу тестировщиков и процесс, выполняемый этой группой. Итак, тестировщик может продолжать
работу по тестированию белого ящика, хотя ПО уже «в бете» (стадия), но в этом случае он не является частью «бета-тестирования» (группы/процесса).

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

Описанные выше техники — тестирование белого ящика и тестирование чёрного ящика — предполагают, что код исполняется, и разница состоит лишь в той информации, которой
владеет тестировщик. В обоих случаях это динамическое тестирование.

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

Также к статическому тестированию относят тестирование требований, спецификаций, документации.

Регрессионное тестирование

Регрессио́нное тести́рование (англ. regression testing, от лат. regressio — движение назад) — собирательное название для всех видов тестирования программного обеспечения,
направленных на обнаружение ошибок в уже протестированных участках исходного кода. Такие ошибки — когда после внесения изменений в программу перестает работать то, что должно было продолжать работать, — называют регрессионными ошибками (англ. regression
bugs).

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

Из опыта разработки ПО известно, что повторное появление одних и тех же ошибок — случай достаточно частый. Иногда это происходит из-за слабой техники управления версиями или
по причине человеческой ошибки при работе с системой управления версиями. Но настолько же часто решение проблемы бывает «недолго живущим»: после следующего изменения в программе решение перестаёт работать. И наконец, при переписывании какой-либо
части кода часто всплывают те же ошибки, что были в предыдущей реализации.

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

Регрессионное тестирование является неотъемлемой частью экстремального программирования. В этой методологии проектная документация заменяется на расширяемое, повторяемое и автоматизированное
тестирование всего программного пакета на каждой стадии цикла разработки программного обеспечения.

Регрессионное тестирование может быть использовано не только для проверки корректности программы, часто оно также используется для оценки качества полученного результата. Так, при
разработке компилятора, при прогоне регрессионных тестов рассматривается размер получаемого кода, скорость его выполнения и время компиляции каждого из тестовых примеров.

Цитата

«Фундаментальная проблема при сопровождении программ состоит в том, что исправление одной ошибки с большой вероятностью (20-50%) влечет появление новой. Поэтому весь процесс
идет по принципу «два шага вперед, шаг назад».

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

Вследствие внесения новых ошибок сопровождение программы требует значительно больше системной отладки на каждый оператор, чем при любом другом виде программирования. Теоретически,
после каждого исправления нужно прогнать весь набор контрольных примеров, по которым система проверялась раньше, чтобы убедиться, что она каким-нибудь непонятным образом не повредилась. На практике такое возвратное (регрессионное) тестирование действительно
должно приближаться к этому теоретическому идеалу, и оно очень дорого стоит.»

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

Тестовые скрипты

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

Покрытие кода

Покрытие кода — мера, используемая при тестировании программного обеспечения. Она показывает процент, насколько исходный код программы был протестирован. Техника покрытия
кода была одной из первых методик, изобретённых для систематического тестирования ПО. Первое упоминание покрытия кода в публикациях появилось в 1963 году.

Критерии

Существует несколько различных способов измерения покрытия, основные из них:

·        
Покрытие операторов — каждая ли строка исходного кода была выполнена и протестирована?

·        
Покрытие условий — каждая ли точка решения (вычисления истинно ли или ложно выражение) была выполнена и протестирована?

·        
Покрытие путей — все ли возможные пути через заданную часть кода были выполнены и протестированы?

·        
Покрытие функций — каждая ли функция программы была выполнена

·        
Покрытие вход/выход — все ли вызовы функций и возвраты из них были выполнены

Для программ с особыми требованиями к безопасности часто требуется продемонстрировать, что тестами достигается 100 % покрытие для одного из критериев. Некоторые из приведённых критериев
покрытия связаны между собой; например, покрытие путей включает в себя и покрытие условий и покрытие операторов. Покрытие операторов не включает покрытие условий, как показывает этот код на Си:

printf(«this is «);

if (bar < 1)

{

   
printf(«not «);

}

printfa
positive
integer«);

Если здесь bar = −1, то покрытие операторов будет полным, а покрытие условий — нет, так как случай несоблюдения условия в операторе if — не покрыт. Полное покрытие
путей обычно невозможно. Фрагмент кода, имеющий n условий содержит 2n путей; конструкция цикла порождает бесконечное количество путей. Некоторые пути в программе могут быть не достигнуты из-за того, что в тестовых данных отсутствовали такие, которые могли
привести к выполнению этих путей. Не существует универсального алгоритма, который решал бы проблему недостижимых путей (этот алгоритм можно было бы использовать для решения проблемы останова). На практике для достижения покрытия путей используется следующий
подход: выделяются классы путей (например, к одному классу можно отнести пути отличающиеся только количеством итераций в одном и том же цикле), 100 % покрытие достигнуто, если покрыты все классы путей (класс считается покрытым, если покрыт хотя бы один путь
из него).

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

Практическое применение

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

Степень покрытия кода обычно выражают в виде процента. Например, «мы протестировали 67 % кода». Смысл этой фразы зависит от того какой критерий был использован. Например,
67 % покрытия путей — это лучший результат чем 67 % покрытия операторов. Вопрос о связи значения покрытия кода и качеством тестового набора ещё до конца не решён.

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

Как правило, инструменты и библиотеки, используемые для получения покрытия кода, требуют значительных затрат производительности и/или памяти, недопустимых при нормальном функционировании
ПО. Поэтому они могут использоваться только в лабораторных условиях.


E-mail: Svatoslav.Pankratov@gmail.com

Ревьюирование(инспекция) программного кода  Инспекция кода (Code review) – систематический и периодический анализ программного кода, направленный на поиск необнаруженных на ранних стадиях разработки программного продукта ошибок, а также, на выявление некачественных архитектурных решений и критических мест в программе.

Ревьюирование(инспекция) программного кода

Инспекция кода (Code review) – систематический и периодический анализ программного кода, направленный на поиск необнаруженных на ранних стадиях разработки программного продукта ошибок, а также, на выявление некачественных архитектурных решений и критических мест в программе.

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

Задачи и цели проведения формальных инспекций

Не всегда возможна разработка автоматических или хотя бы четко формализованных ручных тестов для проверки функциональности программной системы. В некоторых случаях выполнение тестируемого программного кода невозможно в условиях, создаваемых тестовым окружением. Такая ситуация возможна во встроенных системах, если программный код предназначен для обработки исключительных ситуаций, создаваемых только на реальном оборудование.

В тех случаях, когда верифицируется не программный код, а проектная документация на систему, которую нельзя «выполнить» или создать для нее отдельные тестовые примеры, также обычно прибегают к методу экспертных исследований программного кода или документации на корректность или непротиворечивость.

Такие экспертные исследования называют инспекциями или просмотрами. Существует два типа инспекций — неформальные и формальные.

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

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

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

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

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

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

Этапы формальной инспекции и роли ее участников

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

Процедура формальной инспекции проекта должна точно описывать порядок проведения формальных инспекций в данном проекте. После устранения обнаруженных в ходе формальной инспекции несоответствий процесс формальной инспекции повторяется, возможно, в другой форме и с другим составом участников. Процедура формальной инспекции должна регламентировать возможные формы проведения повторной инспекции в зависимости от объема и характера изменений, внесенных в объект инспекции. Как правило, допускается упрощение процесса повторной инспекции (проведение инспекции одним инспектором, отсутствие фазы обсуждения) при внесении в объект инспекции незначительных изменений относительно ранее инспектировавшейся версии. Инициализация  Руководитель проекта или его заместитель запрашивает из базы, хранящей все данные проекта (например, из системы конфигурационного управления), список объектов, готовых к инспекции, выбирает объект инспекции, затем назначает участников формальной инспекции: автора, ведущего и одного или нескольких инспекторов.

Процедура формальной инспекции проекта должна точно описывать порядок проведения формальных инспекций в данном проекте.

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

Инициализация

Руководитель проекта или его заместитель запрашивает из базы, хранящей все данные проекта (например, из системы конфигурационного управления), список объектов, готовых к инспекции, выбирает объект инспекции, затем назначает участников формальной инспекции: автора, ведущего и одного или нескольких инспекторов.

Инициализация (продолжение)

Ведущий также может выполнять роль инспектора; остальные участники выполняют только одну роль. На роль ведущего или инспектора не допускается назначать сотрудников, участвовавших в разработке объекта инспекции.

В роли автора выступает один из разработчиков объекта инспекции, но возможны ситуации, когда разработчик недоступен — например, переведен в другой проект или находится в отпуске. Тогда на роль автора назначается сотрудник, который будет исправлять обнаруженные несоответствия в инспектируемых документах. При инспектировании документов, разработанных заказчиком, автор может не назначаться.

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

В обоснованных случаях процедура формальной инспекции проекта может допускать проведение инспекции единственным инспектором, например, когда объект инспекции отличается особой простотой и оцениваемые характеристики такого объекта инспекции тривиальны.

Инициализация (продолжение) В случае, если проводится повторная инспекция по сокращенной форме, ведущий самостоятельно инициирует процесс повторной инспекции без участия руководителя проекта. Процедура формальной инспекции проекта может разрешать ведущему самостоятельно инициировать процесс повторной инспекции (в том же составе участников), даже когда она проводится в полной форме, если это диктуется спецификой проекта.

Инициализация (продолжение)

В случае, если проводится повторная инспекция по сокращенной форме, ведущий самостоятельно инициирует процесс повторной инспекции без участия руководителя проекта. Процедура формальной инспекции проекта может разрешать ведущему самостоятельно инициировать процесс повторной инспекции (в том же составе участников), даже когда она проводится в полной форме, если это диктуется спецификой проекта.

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

Планирование

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

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

После этого ведущий должен скопировать из базы данных проекта бланк инспекции и занести в него идентификаторы инспектируемых и исходных документов и номера их версий, список участников с указанием их ролей и дату фактического начала процесса инспекции, т.е. того момента, когда инспектируемые документы были переведены в состояние Review

Ведущий должен оценить время, необходимое инспекторам для подготовки, и продолжительность обсуждения. Время, отводимое на этап подготовки, не может быть менее одного часа. Также ведущий должен определить дату, время и место обсуждения, если оно будет проходить в форме собрания. При этом может потребоваться согласование с другими участниками инспекции. Если оценка продолжительности обсуждения в форме собрания превышает 2 часа, то необходимо запланировать несколько собраний, каждое из которых будет длиться не более двух часов.

Процедура формальной инспекции проекта может допускать проведение повторной инспекции без собрания, если итогом предыдущей инспекции было решение о проведении повторной инспекции в сокращенной форме. Также допускается не проводить собрание, если результаты формальной инспекции ведутся и хранятся в электронном виде.

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

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

  • Подготовив бланк инспекции и определив время и место собрания, ведущий должен известить участников инспекции о времени и месте проведения собрания и разослать им подготовленный бланк инспекции.
  • Процедура формальной инспекции проекта может предусматривать использование бланка, заполненного в ходе предыдущей инспекции, если проводится повторная инспекция в сокращенной форме и при этом ведущий является единственным инспектором.

1.

Кафедра КБ-4 «Автоматизированные системы управления»
Исследование программного кода
Для курса 3 группы УУБВ-01-16
По направлению подготовки
09.03.02 «Информационные системы и технологии»
Москва, 2018
1

2.

Кафедра КБ-4 «Автоматизированные системы управления»
Содержание:
1. Базовые понятия и определения (Лекция 1)…………….4
2. Статический анализ (Лекция 2-3)……….………..……….34
3. Обнаружение нефункциональных ошибок в
последовательных программах (Лекция 3)…………….88
4. Анализ отказоустойчивости программного кода(Лекция
5-6)..……………….………………………..142
Москва, 2018
2

3.

Кафедра КБ-4 «Автоматизированные системы управления»
Кашкин
Евгений
Владимирович
кандидат технических наук,
доцент кафедры «Информатика»,
доцент кафедры КБ-4
«Автоматизированные системы
управления»
[email protected]
Москва, 2018
3

4.

Базовые понятия и определения
Тема №1
«Базовые понятия и определения »
Цели занятия
• Качество ПО;
• Функциональность, надежность, удобство использования,
переносимость, удобство сопровождения, эффективность;
• Задачи обеспечения качества;
• Методы анализа ПО: ручные, динамические, статические,
гибридные;
• Надежность ПО;
• Ошибки в ПО;
Москва, 2018
4

5.

Базовые понятия и определения
5

6.

Базовые понятия и определения
6

7.

Базовые понятия и определения
7

8.

Базовые понятия и определения
8

9.

Базовые понятия и определения
9

10.

Базовые понятия и определения
10

11.

Базовые понятия и определения
11

12.

Базовые понятия и определения
12

13.

Базовые понятия и определения
13

14.

Базовые понятия и определения
14

15.

Базовые понятия и определения
15

16.

Базовые понятия и определения
16

17.

Базовые понятия и определения
17

18.

Базовые понятия и определения
18

19.

Базовые понятия и определения
19

20.

Базовые понятия и определения
20

21.

Базовые понятия и определения
21

22.

Базовые понятия и определения
22

23.

Базовые понятия и определения
23

24.

Базовые понятия и определения
24

25.

Базовые понятия и определения
25

26.

Базовые понятия и определения
26

27.

Базовые понятия и определения
27

28.

Базовые понятия и определения
28

29.

Базовые понятия и определения
29

30.

Базовые понятия и определения
30

31.

Базовые понятия и определения
31

32.

Базовые понятия и определения
Выводы по теме 1
В рамках данной темы были получены
знания в области надежности ПО.
Рассмотрены составляющие качества ПО, а
именно функциональность, надежность,
удобство использования, переносимость,
удобство сопровождения, эффективность.
Выявлены методы анализа ПО: ручной,
статический, динамический.
32

33.

Базовые понятия и определения
Вопросы для
самостоятельного изучения:
1. Требования к надежности программного обеспечения№
2. Эффективность программного обеспечения№
3. Причины ненадежности исполняемого кода.
33

34.

Статический анализ
Тема №2
«Статический анализ»
Цели занятия
Основные задачи и принципы статического анализа;
Классификация программных ошибок;
Виды статического анализа;
RD, AE, VBE, LV, CP, UD – анализ кода;
Алгоритмы анализа потока данных;
Эффективность статического анализа;
34

35.

Статический анализ
35

36.

Статический анализ
36

37.

Статический анализ
37

38.

Статический анализ
38

39.

Статический анализ
39

40.

Статический анализ
40

41.

Статический анализ
41

42.

Статический анализ
42

43.

Статический анализ
43

44.

Статический анализ
44

45.

Статический анализ
45

46.

Статический анализ
46

47.

Статический анализ
47

48.

Статический анализ
48

49.

Статический анализ
49

50.

Статический анализ
50

51.

Статический анализ
51

52.

Статический анализ
52

53.

Статический анализ
53

54.

Статический анализ
54

55.

Статический анализ
55

56.

Статический анализ
56

57.

Статический анализ
57

58.

Статический анализ
58

59.

Статический анализ
59

60.

Статический анализ
60

61.

Статический анализ
61

62.

Статический анализ
62

63.

Статический анализ
63

64.

Статический анализ
64

65.

Статический анализ
65

66.

Статический анализ
66

67.

Статический анализ
67

68.

Статический анализ
68

69.

Статический анализ
69

70.

Статический анализ
70

71.

Статический анализ
71

72.

Статический анализ
72

73.

Статический анализ
73

74.

Статический анализ
74

75.

Статический анализ
75

76.

Статический анализ
76

77.

Статический анализ
77

78.

Статический анализ
78

79.

Статический анализ
79

80.

Статический анализ
80

81.

Статический анализ
81

82.

Статический анализ
82

83.

Статический анализ
83

84.

Статический анализ
84

85.

Статический анализ
85

86.

Статический анализ
Выводы по теме 2
В рамках данной темы были получены
знания в области статического анализа
программного кода. Рассмотрены вопросы
различных подходов при анализе
последовательного кода. Даны примеры
решения системы дискретных уравнений в
рамках RD-анализа
86

87.

Статический анализ
Вопросы для
самостоятельного изучения:
1. Обнаружение функциональных и нефункциональных
ошибок;
2. Теория решеток;
3. Алгоритмы вычисления LFP;
4. Определение недостижимых переходов.
87

88.

Обнаружение нефункциональных ошибок в последовательных
программах
Тема №3
«Обнаружение нефункциональных ошибок в последовательных
программах»
Классификация программных дефектов (RES, LEAK, BUF, INI, IO);
Абстрактное синтаксическое дерево;
Абстрактный семантический граф;
Граф зависимостей по данным;
Граф потока управления;
Анализ программ на основе состояний;
Интервальный анализ;
Анализ указателей;
Ресурсный анализ.
88

89.

Обнаружение нефункциональных ошибок в последовательных
программах
89

90.

Обнаружение нефункциональных ошибок в последовательных
программах
90

91.

Обнаружение нефункциональных ошибок в последовательных
программах
91

92.

Обнаружение нефункциональных ошибок в последовательных
программах
92

93.

Обнаружение нефункциональных ошибок в последовательных
программах
93

94.

Обнаружение нефункциональных ошибок в последовательных
программах
94

95.

Обнаружение нефункциональных ошибок в последовательных
программах
95

96.

Обнаружение нефункциональных ошибок в последовательных
программах
96

97.

Обнаружение нефункциональных ошибок в последовательных
программах
97

98.

Обнаружение нефункциональных ошибок в последовательных
программах
98

99.

Обнаружение нефункциональных ошибок в последовательных
программах
99

100.

Обнаружение нефункциональных ошибок в последовательных
программах
10

101.

Обнаружение нефункциональных ошибок в последовательных
программах
10

102.

Обнаружение нефункциональных ошибок в последовательных
программах
10

103.

Обнаружение нефункциональных ошибок в последовательных
программах
10

104.

Обнаружение нефункциональных ошибок в последовательных
программах
10

105.

Обнаружение нефункциональных ошибок в последовательных
программах
10

106.

Обнаружение нефункциональных ошибок в последовательных
программах
10

107.

Обнаружение нефункциональных ошибок в последовательных
программах
10

108.

Обнаружение нефункциональных ошибок в последовательных
программах
10

109.

Обнаружение нефункциональных ошибок в последовательных
программах
10

110.

Обнаружение нефункциональных ошибок в последовательных
программах
11

111.

Обнаружение нефункциональных ошибок в последовательных
программах
11

112.

Обнаружение нефункциональных ошибок в последовательных
программах
11

113.

Обнаружение нефункциональных ошибок в последовательных
программах
11

114.

Обнаружение нефункциональных ошибок в последовательных
программах
11

115.

Обнаружение нефункциональных ошибок в последовательных
программах
11

116.

Обнаружение нефункциональных ошибок в последовательных
программах
11

117.

Обнаружение нефункциональных ошибок в последовательных
программах
11

118.

Обнаружение нефункциональных ошибок в последовательных
программах
11

119.

Обнаружение нефункциональных ошибок в последовательных
программах
11

120.

Обнаружение нефункциональных ошибок в последовательных
программах
12

121.

Обнаружение нефункциональных ошибок в последовательных
программах
12

122.

Обнаружение нефункциональных ошибок в последовательных
программах
12

123.

Обнаружение нефункциональных ошибок в последовательных
программах
12

124.

Обнаружение нефункциональных ошибок в последовательных
программах
12

125.

Обнаружение нефункциональных ошибок в последовательных
программах
12

126.

Обнаружение нефункциональных ошибок в последовательных
программах
12

127.

Обнаружение нефункциональных ошибок в последовательных
программах
12

128.

Обнаружение нефункциональных ошибок в последовательных
программах
12

129.

Обнаружение нефункциональных ошибок в последовательных
программах
12

130.

Обнаружение нефункциональных ошибок в последовательных
программах
13

131.

Обнаружение нефункциональных ошибок в последовательных
программах
13

132.

Обнаружение нефункциональных ошибок в последовательных
программах
13

133.

Обнаружение нефункциональных ошибок в последовательных
программах
13

134.

Обнаружение нефункциональных ошибок в последовательных
программах
13

135.

Обнаружение нефункциональных ошибок в последовательных
программах
13

136.

Обнаружение нефункциональных ошибок в последовательных
программах
13

137.

Обнаружение нефункциональных ошибок в последовательных
программах
13

138.

Обнаружение нефункциональных ошибок в последовательных
программах
13

139.

Обнаружение нефункциональных ошибок в последовательных
программах
13

140.

Обнаружение нефункциональных ошибок в последовательных
программах
Выводы по теме 3
В рамках данной темы были получены
знания в области обнаружения
программных дефектов различными
методами. Приведены примеры работы с
абстрактным синтаксическим деревом,
абстрактным семантическим графом и др.
Рассмотрены ключевые вопросы анализа
программ на основе состояний.
14

141.

Обнаружение нефункциональных ошибок в последовательных
программах
Вопросы для
самостоятельного изучения:
1.
2.
3.
4.
Программные средства для статического анализа;
Способы снижения ресурсоемкости;
Использование абстрактной интерпретации;
Анализ программ на основе шаблонов.
14

142.

Анализ отказоустойчивости программного кода
Тема №4
«Анализ отказоустойчивости программного кода»
Показатели надежности;
Жизненный цикл программной ошибки;
Модель Бернулли;
Модель Миллса;
Модель Шумана;
Модель Джелинского-Моранды;
Ошибки на путях выполнения программы.
14

143.

Анализ отказоустойчивости программного кода
14

144.

Анализ отказоустойчивости программного кода
14

145.

Анализ отказоустойчивости программного кода
14

146.

Анализ отказоустойчивости программного кода
14

147.

Анализ отказоустойчивости программного кода
14

148.

Анализ отказоустойчивости программного кода
14

149.

Анализ отказоустойчивости программного кода
14

150.

Анализ отказоустойчивости программного кода
15

151.

Анализ отказоустойчивости программного кода
15

152.

Анализ отказоустойчивости программного кода
15

153.

Анализ отказоустойчивости программного кода
15

154.

Анализ отказоустойчивости программного кода
15

155.

Анализ отказоустойчивости программного кода
15

156.

Анализ отказоустойчивости программного кода
15

157.

Анализ отказоустойчивости программного кода
15

158.

Анализ отказоустойчивости программного кода
15

159.

Анализ отказоустойчивости программного кода
15

160.

Анализ отказоустойчивости программного кода
16

161.

Анализ отказоустойчивости программного кода
16

162.

Анализ отказоустойчивости программного кода
16

163.

Анализ отказоустойчивости программного кода
16

164.

Анализ отказоустойчивости программного кода
16

165.

Анализ отказоустойчивости программного кода
16

166.

Анализ отказоустойчивости программного кода
16

167.

Анализ отказоустойчивости программного кода
16

168.

Анализ отказоустойчивости программного кода
16

169.

Анализ отказоустойчивости программного кода
16

170.

Анализ отказоустойчивости программного кода
17

171.

Анализ отказоустойчивости программного кода
17

172.

Анализ отказоустойчивости программного кода
17

173.

Анализ отказоустойчивости программного кода
17

174.

Анализ отказоустойчивости программного кода
17

175.

Анализ отказоустойчивости программного кода
17

176.

Анализ отказоустойчивости программного кода
17

177.

Анализ отказоустойчивости программного кода
17

178.

Анализ отказоустойчивости программного кода
17

179.

Анализ отказоустойчивости программного кода
17

180.

Анализ отказоустойчивости программного кода
18

181.

Анализ отказоустойчивости программного кода
18

182.

Анализ отказоустойчивости программного кода
18

183.

Анализ отказоустойчивости программного кода
18

184.

Анализ отказоустойчивости программного кода
18

185.

Анализ отказоустойчивости программного кода
18

186.

Анализ отказоустойчивости программного кода
18

187.

Анализ отказоустойчивости программного кода
Выводы по теме 4
В рамках данной темы были получены знания в
области оценки показателей надежности работы
программного кода. Рассмотрен жизненный цикл
программной ошибки и особенности каждого этапа
этого жизненного цикла. Даны базовые знания в
области различный моделей оценки надежности
программного кода.
187

188.

Анализ отказоустойчивости программного кода
Вопросы для
самостоятельного изучения:
1.
2.
3.
4.
5.
6.
Методы оценки на основе моделей сложности;
Архитектурные методы анализа;
Свойства динамических методов анализа кода;
Цепи Маркова;
Римская модель;
Эмпирические методы динамического анализа кода.
18

189.

Кафедра КБ-4 «Автоматизированные системы управления»
189

Динамический, статический и бинарный анализ

Сегодня есть две наиболее зрелые и востребованные технологии анализа кода – динамический анализ (DAST – Dynamic Application Security Testing) и статический анализ (SAST – Static Application Security Testing). Разновидностью SAST является бинарный анализ.

Динамический анализ – его также называют методом «Черного ящика» – представляет собой проверку программы на наличие уязвимостей непосредственно во время ее выполнения. У этого подхода есть свои преимущества. Во-первых, поскольку уязвимости находятся в исполняемой программе и обнаружение ошибки происходит с помощью ее эксплуатации, возникает меньше ложных срабатываний, чем при использовании статического анализа. Плюс для выполнения данного вида анализа не нужен исходный код. Но есть и слабые места, в частности, данным методом нельзя обнаружить все возможные уязвимости, в связи с чем существуют риски пропущенных уязвимостей. Не все уязвимости могут себя проявить при таком методе тестирования. Например, временная бомба или захардкоженные креды. Кроме того, метод требует максимально точного воспроизведения боевой среды при тестировании.

Статический анализ – метод «Белого ящика» – представляет собой тип тестирования, при котором, в отличие от динамического анализа, не происходит выполнения программы, а анализируется весь ее код. В результате мы имеем нахождение большего количества уязвимостей. Также метод выгодно отличает возможность внедрения в начальные стадии разработки: чем раньше обнаруживаем уязвимость, тем дешевле обходится ее устранение.

У метода есть два недостатка. Первый – наличие ложноположительных срабатываний. Как следствие – необходимость оценки, что перед тобой реальная уязвимость или ошибка сканера. Второй недостаток – необходимость наличия исходного кода программы, который не всегда доступен. В последнем случае помогает бинарный анализ – он позволяет с помощью технологий реверс-инжиниринга провести статический анализ кода, даже если у нас нет исходника. Когда в 2015 году мы выводили на рынок анализатор кода приложений Solar appScreener, эта функциональность уже была заложена в системе. Мы видели тогда и видим сейчас, что в реальной жизни это зачастую единственная возможность грамотно и полноценно выявить уязвимости в приложениях.

Например, нам нужно убедиться в том, что исходный код, который мы проверяли, – тот самый, который потом пойдет в продакшн. Помимо ситуаций, когда кто-либо намеренно вносит в код закладки, ряд уязвимостей может добавить и компилятор. И это отнюдь не экзотическая ситуация: компилятор тоже пишут люди, и он не застрахован от ошибок. В общем, нам нужно взять из продакшна исполняемый файл и проверить его на уязвимости.

Альтернативный вариант – прогнать приложение через динамический анализатор: перед нами черный ящик, мы не можем его открыть, но можем на него воздействовать – «пнуть, поднять, потрясти, уронить». И по результатам этого воздействия сделать выводы. При динамическом анализе на вход приложения подаются разные данные, в текстовые поля вводятся различные последовательности, в случае с веб-сайтом посылаются разнообразные команды, протоколы, пакеты. И по ответу от приложения мы делаем вывод, есть ли в нем уязвимости. DAST действительно хорош для веб-приложений, потому что можно повоздействовать на систему, защищенную при этом файрволом.

Однако DAST помогает обнаружить только определенный спектр уязвимостей. А, например, угрозы вроде временной бомбы, которая по триггеру времени запустит в систему вредонос, скрытую «учетку», небезопасный пароль и прочее динамическим анализом не обнаружить. Бинарный анализ же делает из черного ящика белый, позволяя в ходе статического анализа увидеть его содержимое.

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

True or False: как решить главную проблему автоматизированного анализа кода?

Ложные срабатывания – проблема любых систем, которые автоматически что-то анализируют и выдают результат. Очевидно, что она актуальна и для анализаторов кода. Чем больше ложных срабатываний, тем дороже использование инструмента для пользователя. Ведь на верификацию тратятся человеческие ресурсы – время.

Сегодня есть несколько путей развития технологий для минимизации ложных срабатываний. Один из самых хайповых – применение искусственного интеллекта, а точнее его подраздела – машинного обучения (МО). Какими способами можно искать уязвимости в коде с помощью МО?

Во-первых, можно попытаться обучить МО-анализатор вручную: написать множество примеров правильного и неправильного кода и научить анализатор искать такие ошибки. Минус подхода в том, что для обучения анализатора нам придется потратить много времени на подготовку подходящих примеров.

Есть еще вариант — пометить код реальных приложений с указанием фрагментов, в отношении которых анализатор должен выдавать предупреждение о наличии ошибки. В любом случае необходимо будет проделать большой объем работы, так как для обучения необходимы десятки тысяч примеров ошибок кода. Если же учесть, что существуют уязвимости (например, утечка памяти), которые могут содержаться в коде, написанном почти бесконечным числом вариаций, то необходимый для обучения объем примеров делает задачу фактически невыполнимой.

Во-вторых, можно не готовить примеры вручную, а обучать МО-анализатор на основе больших объемов открытого исходного кода. Можно отслеживать историю коммитов на GitHub и выявлять закономерности изменения или исправления программного кода. Однако проблема в том, что правки на GitHub вносятся довольно хаотично: например, пользователь не хочет тратить время на внесение каждой правки в отдельности – и он где-то вносит пару изменения, а где-то просто переписывает кусок кода. Тогда даже человек не сможет разобраться, связаны ли эти исправленные ошибки между собой.

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

Таким образом, в целом использование ИИ для анализа кода – очень трудозатратная и недешевая история при неочевидном результате.

Но есть и другой метод борьбы с ложными срабатываниями – математический.

Нечеткая логика: как это работает

Нечеткая логика – относительно новый раздел математики. Он является обобщением классической логики и теории множеств и базируется на понятии нечеткого множества, впервые введенного в 1965 году. Если в обычной логике у нас есть true или false, 0 или 1, то нечеткая логика оперирует градациями между true и false. Она может сказать, что событие верно на столько-то процентов и на столько-то неверно, – и это ближе к мышлению человека.

Представьте, что у вас есть стакан воды и нужно сказать, что вода холодная, если ее температура ниже 15 градусов, и теплая, если выше 15 градусов. Мы опускаем палец в стакан (допустим, там 16 градусов, но мы об этом не знаем). И мы не скажем: «Да, она точно теплая». На пограничных значениях мы будем внутренне колебаться: вроде теплая, но скорее холодная. Нечеткая логика помогает нам уйти от линейного мышления.

В обычном линейном мышлении, когда систему научили принимать решение, что это true или false, при выставлении математического порога (допустим, мы хотим меньше ложных срабатываний) приходится устанавливать для машины жёсткие фильтры принятия решений. Тогда она начнет выдавать меньше ложных срабатываний, но при этом начнет пропускать реальные уязвимости. Двигаем линейный фильтр в обратную сторону – машина перестает пропускать уязвимости, но при этом ложных срабатываний становится очень много.

Поэтому в своей системе мы реализовали механизм борьбы с уязвимостями на основе математического аппарата нечеткой логики – Fuzzy Logic Engine (FLE), который позволяет тонко настраивать линейные фильтры, балансируя между снижением ложных срабатываний и потерей точности выявления уязвимостей. Фильтры в системе позволяют, например, отображать лишь те уязвимости, в которых FLE полностью уверен. Кроме того, можно практически ювелирно настроить уровень уверенности системы в наличии уязвимости. С помощью шкалы Confidence можно, например, задать для уязвимостей критичного уровня более жесткие критерии, по которым система будет относить потенциальные уязвимости к реальным.

Для уязвимостей средней и низкой критичности можно задать более мягкие критерии оценки.

Чем больше языков, тем лучше

Языков программирования становится все больше, многие из новых быстро набирают популярность. Например, язык Rust, который позиционируется как безопасная замена С++ и сегодня часто используется для написания десктопных приложений и бэкэндов. Или Go (Golang), применяемый для создания высоконагруженных сервисов – площадок онлайн-торговли, ДБО, мессенджеры и т.п. Dart, предназначенный для написания веб и мобильных клиентов.

И нередко бывает так, что какая-то часть системы написана на языке, который можно проверить не всеми инструментами. Поэтому, если мы хотим, чтобы анализ кода был эффективным и удобным, важно, чтобы все языки были на борту. Пользователь не должен задаваться вопросом, на каких языках написано приложение, все ли языки поддерживает анализатор. Код должен загружаться в анализатор, который сам определит, какие языки содержатся в приложении, и все их проверит, ничего не пропуская. Именно по такому принципу мы реализуем Solar appScreener: в апреле прошлого года добавили поддержку Dart и продолжаем лидировать по количеству поддерживаемых языков – сейчас их 36.

Мы довольно гибко подходим к управлению командой и разработке новых фич. Некоторые вендоры не могут просто взять и быстро добавить новый язык в свой анализатор, потому что им нужно просчитать выгоду от реализации той или иной функции на других рынках. Много ли запросов на нее от наиболее приоритетных рынков, или лучше потратить ресурсы команды на создание другой функциональности? Это может отнимать много времени.

Технологии на перспективу

Ну а что же там, за горизонтом? Какие технологии могут быть реализованы в анализаторах кода уже в ближайшем будущем?
Сейчас на рынке анализа кода наблюдается растущий спрос на бинарный анализ сложных систем. Допустим, компания покупает софт стороннего вендора, устанавливает его в свою критическую информационную инфраструктуру, и ИБ-специалисты хотят понимать реальный уровень защищенности той или иной системы. В чем здесь отличие от уже существующих технологий? Современный бинарный анализ позволяет загрузить в анализатор и проанализировать лишь каждый исполняемый файл в отдельности. В случае со сложной многокомпонентной системой нужно отправить в анализатор целый зоопарк различных файлов, связанных друг с другом, – инсталляционные файлы, готовые файлы системы, библиотеки, исполняемые файлы и т.п. Это не просто файлы, а единое ПО, которое состоит из разных логических компонентов. Поэтому тут нужен сложнейший анализ, который очень тяжело реализовать. Пока подобная функция является экзотикой.

Весьма реалистичной выглядит перспектива применения интегрированных систем, в которых используются преимущества сразу всех передовых методов анализа – DAST, SAST, IAST, mAST, SCA (Software Composition Analysis). Последний представляет собой инвентаризацию библиотек, кода, предоставленного на анализ, и его сверку с базой данных, включающей перечень библиотек и содержащихся в них уязвимостей. Однако пока нет вендора, который свел бы все эти компоненты воедино, а отчеты, предоставляемые каждой системой, настолько разнятся, что привести их к общему знаменателю нереально. Поэтому создание интегрированной системы, которая объединит возможности разных видов анализа кода, с единой системой отчетности, выглядит многообещающе.

Стоит отметить и еще одну довольно занятную технологию для защиты приложений от уязвимостей – RASP (Runtime application self-protection). О ее перспективности однажды заявлял Gartner, однако пока технология самозащиты приложений кажется малоэффективной. Некоторые вендоры уже пытались ее реализовать, однако работает она только в частных случаях и применима далеко не ко всем языкам программирования. Её суть состоит в том, что в само защищаемое ПО добавляется в код, который позволяет приложению понимать, когда его атакуют, и блокировать атаку. Проблема кроется в том, что архитектура веб-приложений очень разная, поэтому такой подход к защите применим либо при индивидуальной разработке под каждое приложение и каждую новую его версию, либо в случае, если RASP-система допускает очень глубокую кастомизацию. Чтобы говорить о RASP как о полноценной замене анализу кода веб-приложений, нужно сделать определенные шаги в развитии технологий в целом и искусственного интеллекта в частности.

P.S. А если вдруг?..

А что, если придет квантовый компьютер и настанет эра квантовых вычислений – как в таком случае защититься, например, от уязвимостей, проэксплуатировать которые можно методом перебора? Вот эти все недостаточные размеры ключа шифрования, слабые алгоритмы хеширования, заданная в исходном коде соль и т.п.? Если такие технологии придут в массовое использование, то все, что сейчас считается безопасным – сложные пароли, алгоритмы шифрования – будет взламываться налету. Очевидно, необходимо будет разрабатывать совершенно другие подходы и к статическому анализу кода, и к динамическому. Как это будет, пока неизвестно, но очень интересно.


1


Исследование кодов программ Макаренков Д.Е. Лекция по дисциплине «Компьютерная разведка»


2


Учебные вопросы 1. Цели и задачи исследования программ 2. Методы и средства исследования кода программ 3. Общие сведения о языке ассемблера


3


Литература Рекомендованная по дисциплине Дополнительно: –Защита программного обеспечения от отладки и дизассемблирования: Учебное пособие // И.В. Аникин, В.И. Глова. Казань: КГТУ, 2003 г. –Панов А.С. Реверсинг и защита программ от взлома. СПб: BHV-Санкт-Петербург, 2006 г. –Отладчик SoftICE. Руководство пользователя. Numega Software, –К. Касперски. Образ мышления IDA PRO. М


4


Учебный вопрос 1 Цели и задачи исследования программ


5


Программа последовательность формализованных инструкций устройства управления ЭВМ, предназначенная для реализации определенного алгоритма. –Машинный код процессора –Псевдокод виртуальной среды исполнения –Скрипты –Тексты программ


6


Исследование программ Обратное проектирование (англ. reverse ingeneering ) процесс исследования и анализа машинного кода, нацеленный на понимание общих механизмов функционирования программы, а также на его перевод на более высокий уровень абстракции вплоть до восстановления текста программы на исходном языке программирования Громкие примеры: »IBM-PC BIOS »Процессор AMD am386 »Samba


7


Цели обратного проектирования Получение закрытых сведений, заложенных в программу –алгоритм работы программы –протоколы обмена данными –форматы данных –скрытые данные Обнаружение уязвимостей и недокументированных возможностей Модификация программы –отключение защитных механизмов –внедрение закладок Создание устройства или программы с аналогичными функциями


8


Задачи исследования Восстановление кода программы (или отдельных фрагментов) на языке программирования высокого уровня –Распаковка кода –Локализация нужного модуля –Идентификация кода и данных Анализ алгоритма –Определение структуры программы, назначение отдельных блоков Изучение структур данных


9


Учебный вопрос 2 Методы и средства исследования кода программ


10


Декомпиляция Трансляция исполняемого модуля в эквивалентный исходный код на языке программирования высокого уровня –Частный случай: дизассемблирование — перевод исполняемого модуля программы на язык ассемблера Удачность декомпиляции зависит от: –правильности интерпретации кода –объема и структурированности декомпилированного кода


11


Дизассемблер транслятор, преобразующий машинный код в программу на языке ассемблера. –Автоматические генерируют готовый листинг, который можно затем править в текстовом редакторе –Интерактивные позволяют изменять правила дизассемблирования в процессе работы


12


Выполнение в контролируемой среде Отладка — динамическое исследование –трассировка программы пошаговое выполнение программы с остановками на каждой команде или строке –отслеживание значений переменных в процессе выполнения программы –контрольные точки и условия останова –вмешательство в процесс выполнения


13


Эмуляция среды выполнения Эмуля́ция (англ. emulation) воспроизведение программными или аппаратными средствами либо их комбинацией работы других программ или устройств. –Виртуальная машина


14


Контроль памяти во время выполнения программы Поиск значений переменных в процессе выполнения программы Сравнение состояния переменных в разные моменты работы программы Установка необходимых значений переменных


15


Анализ потоков данных Изучение входных и выходных данных Прослушивание каналов передачи данных, накопление статистики, анализ –мониторы событий файловых операций обращений к реестру операций ввода-вывода –сетевые пакетные снифферы


16


Возможность защиты от исследования Команды однозначно интерпретируются процессором Данные могут быть перехвачены Среда исполнения может быть эмулирована Выводы: Защититься от исследования невозможно Но можно усложнить задачу –Защита от декомпиляции и отладки –Обфускация алгоритма и данных


17


Применение различных методов исследования Метод «черного ящика» –анализ реакции программы на различные входные данные Метод «прозрачного ящика» –изучение восстановленного кода Метод «серого ящика» –частичное восстановление кода


18


Локализация модулей Анализ изменений после ввода данных –Поиск в памяти введенных значений и контроль обращений программы к этим данным –Перехват вызовов функций ввода данных Ожидаемый вывод на экран –Поиск в памяти осмысленных последовательностей символов и контроль обращений программы к адресам, по которым хранятся эти последовательности –Перехват вызовов функций вывода данных


19


Учебный вопрос 3 Общие сведения о языке ассемблера


20


Ассемблер Язык программирования «низкого уровня» Мнемоническое обозначение машинных кодов –удобнее для восприятия человеком


21


Процессор для программ система адресации памяти набор регистров набор команд


22


Разный ассемблер? Разные процессоры: –разные регистры –разные наборы команд Соответственно — разные языки ассемблера


23


Синтаксис Типичный формат записи команд: [метка:] код_операции [операнды] [;комментарий]


24


Операнды Константы Регистры Метки Ссылки


25


Пример: Команда MOV MOV адресат, источник Источник : –число –регистр –адрес ячейки в оперативной памяти Адресат: –регистр –адрес ячейки в оперативной памяти


26


Регистры процессора x86 Назначение Кол-во Регистры данных общего назначения 4AX, BX, CX, DX Указатели 2SI, DI Индексные регистры 2SP, BP Сегментные 4CS, DS, SS, ES Регистр состояния 1FLAGS Управляющие (указатель команд)1IP


27


Разрядность регистров EAX 32 разряда AX 16 разрядов AH, ALпо 8 разрядов EAX AX AHAL


28


Регистр флагов Флаги: состояния управления системные


29


Организация памяти Линейная модель Сегментированная модель Физический адрес = (сегмент, смещение) Вариант 1 : Вариант 2 : Сегмент Смещение Сегмент Смещение


30


Система команд процессора Для Pentium4 более 300 команд Пересылки данных Арифметические Битовые (логические) Обработки строк Передачи управления Управления состоянием процессора MMX, SSE, SSE II


31


Команды пересылки данных пересылки данных общего назначения обмен данными с портами ввода/вывода работы с адресами и указателями пересылки флагов


32


Арифметические команды Сложения Вычитания Умножения Деления Преобразования типов Сравнения


33


Битовые операции Логические операции –AND, OR, XOR, NOT, TEST Сдвиги Циклические сдвиги


34


Команды обработки строк Пересылка Сравнение Сканирование Загрузка и сохранение элементов строки Могут автоматически повторяться


35


Команды передачи управления Команды безусловной передачи управления: –безусловного перехода; –вызова процедуры и возврата из процедуры; –вызова программных прерываний и возврата из программных прерываний. Команды условной передачи управления: –по результату сравнения; –по состоянию определенного флага; –по содержимому регистра ЕСХ/СХ. Команды управления циклом: –организации цикла со счетчиком ЕСХ/СХ; –организации цикла со счетчиком ЕСХ/СХ с возможностью досрочного выхода из цикла по дополнительному условию.


36


Команды управления процессором Управления флагами Синхронизации Холостой ход NOP


37


Режимы адресации Вид адресации Пример Регистроваяmov ax,bx Непосредственнаяmov ax,200 Прямаяmov ax,Table Косвенная регистроваяmov ax,[bx] Адресация по базеmov ax,[bx+3] Прямая с индексированиемmov ax,Table[di] Адресация по базе с индексированиемmov ax,Table[bx][di]


38


Вопросы?

Понравилась статья? Поделить с друзьями:
  • Испытывать нужду ошибка
  • Испугавшийся выстрела заяц показал стрекача ошибка
  • Исправьте словообразовательные ошибки разночинская интеллигенция
  • Исправьте словообразовательные ошибки мастерская шьет полушубочки
  • Исправьте словообразовательные ошибки весело гуляли свадьбу