Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник 239.docx
Скачиваний:
18
Добавлен:
30.04.2022
Размер:
559.77 Кб
Скачать

4.5. Подходы к исследованию сложных программных комплексов

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

  • размер программ, выраженный числом команд и программных модулей в комплексе;

  • количество обрабатываемых переменных и объем памяти для размещения базы данных;

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

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

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

  • сложности структуры комплекса (или группы программ и связей между модулями по передачам управления и обмену информацией), определяемой числом связей при взаимодействии модулей, структурой и регулярностью межмодульных связей;

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

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

  • при классификации программ на основе количественных критериев для выбора рациональных методов и средств обеспечения их технологической безопасности;

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

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

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

  • обработки исходных текстов и характеристик оттранслированных программ, а также расчета абсолютных и относительных численных характеристик объема модулей программ, числа используемых переменных и констант;

  • структурного контроля программы, расчета числа маршрутов и циклов, а также количества передач управления в ациклических маршрутах;

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

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

  • диспетчерские программы (верхний уровень иерархии);

  • функциональные модули, выполняющие основные задачи обработки информации и принятия решений (средние уровни иерархии);

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

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

Количественная оценка сложности программы при помощи управляющего графа вычисляется как сумма V=e-n+2p, где e – число дуг, n - число вершин, p - число связных компонент графа. Оценкой сложности можно пользоваться и при проектировании программ: если сложность превосходит некоторое критическое значение, то программу целесообразно разбить на более мелкие модули для упрощения ее понимания и отладки. В качестве критической сложности обычно принимают значение 10 единиц.

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

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

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

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

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

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

Алгоритм А

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

А2. В графе программы ищется структурированная конструкция. Если такой нет, то выполняется переход к шагу А4.

А3. В дереве образуется вершина структурированной конструкции. Эта конструкция сворачивается в вершину, тип которой указывается. Выполняется переход к шагу А2.

А4. Если в графе осталась только одна вершина, то работа алгоритма заканчивается.

А5. В графе выделяется неструктурируемая конструкция и в структурном дереве образуется вершина соответствующего типа. Конструкция в графе сворачивается, после чего выполняется переход к шагу А2.

Построение структурного дерева выполняется от элементов, представляющих вершины управляющего графа, к элементу, представляющему всю программу целиком. Используя понятие структурного дерева программы, можно рассчитать существенную сложность программы EV: S(V(i)-1), где NS - множество вершин неструктурируемого типа в структурном дереве; V(i) - топологическая сложность конструкции, соответствующей i-й вершине дерева.

Вычисление V(i) производится на шаге А5 алгоритма по формуле V(i)=e(i)-n(i)+2, где e(i) - количество дуг, а n(i) - количество вершин рассматриваемой конструкции.

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

Характеристики иерархической структуры и взаимосвязей модулей между собой в процессе решения задач КУП определяются на основе:

  • анализа блок-схемы комплекса с выделением глобальных переменных, используемых в программах;

  • формирования групп программ, обращающихся к анализируемой программе, к заданной зоне глобальных переменных или к конкретной переменной;

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

В процессе анализа блок-схемы комплекса программ определяется количество уровней иерархии структуры комплекса (r), распределение числа программ по уровням P1(r) и распределение среднего количества команд в программах различных уровней P2(r).

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

Взаимосвязь модулей комплекса программ между собой характеризуются распределением числа вызываемых программ P3(r) и распределением числа программ, обращающихся к анализируемой программе - P4(r). Подсчет сложности взаимодействия модулей выполняется с учетом всех управляющих и информационных связей путем интегрирования характеристик модулей. Для каждого i-го модуля число путей входа в него или число модулей, откуда он вызывается, характеризуется величиной aij входных управляющих связей. Аналогично число выходных управляющих связей можно представить как число модулей bij, вызываемых из данного. Наименьшая связность реализуется, когда i-й модуль сопрягается только с одним j-м программным модулем и имеет одну входную (aij=1) и одну выходную (bij=1) связи. В этом случае модуль не вызывает другие модули, а только возвращает управление после завершения своей функции. В результате i-тый модуль находится на нижнем уровне в данной ветви комплекса программ, так как он не вызывает других модулей.

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

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

Информационные связи между модулями анализировать сложнее, чем управляющие. Это обусловлено тем, что возможны, с одной стороны, информационные связи между модулями, непосредственно не связанными по управлению, а с другой стороны - тем, что каждая информационная связь может характеризоваться различным числом и типом переменных, участвующих в обмене. В первом приближении информационная связь i-того и j-того модулей может быть оценена количеством глобальных и обменных переменных с одинаковыми именами, используемых в планируемой паре модулей. Степень зависимости каждого модуля от остальных можно характеризовать количеством типов (индекс k) переменных aij на входе, необходимых для нормального функционирования данного модуля: .

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

Переменные, которые используются i-ым модулем не модифицируясь, является только входными и не учитываются как выходные связи.

Таким образом, количественно охарактеризовать информационные связи i-того модуля можно следующим образом: =Ai+Bi.

Полное количество информационных связей в группе программ равно сумме связей модулей =Ai+Bi.

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

Обычно каждая глобальная переменная используется двумя или более программами, а модифицируется чаще всего одной, т.е. Вk=3-4. С точки зрения обеспечения технологической безопасности программ необходима тщательная проверка условий модификации переменных, так как именно в эти моменты может изменяться режим работы программы за счет использования значений глобальной переменной в качестве управляющих элементов.

Обменные переменные обеспечивают взаимодействие только двух программ и сложность их связей по каждой переменной минимальная (Вk=2). Кроме того, обменные переменные упрощают связи за счет обеспечения информационного взаимодействия модулей, непосредственно связанных по управлению.

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

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

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

Алгоритм Б

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

Б2. Отмечаются все входы и выходы управляющего графа и фиксируется первый вход.

Б3. Если все входы рассмотрены, то выполняется переход к шагу Б9, иначе выполняется переход к шагу Б4.

Б4. Строится очередной путь, причем первой вершиной пути назначается зафиксированный вход.

Б5. Если текущая вершина пути не выходная, то необходимо перейти к шагу Б6, в противном случае - к шагу Б4 (путь построен).

Б6. Если у последней вершины пути выходят необработанные дуги, то выполняется переход к шагу Б7, в противном случае - к шагу Б8.

Б7. В текущий путь включается необработанная дуга с началом в последней (текущей) вершине пути. Если таких дуг несколько, то выполняется переход к шагу Б5.

Б8. Строится кратчайший путь из последней (текущей) вершины до ближайшей вершины допустимого множества, в которое включаются выходные вершины графа, если в текущем пути уже есть хотя бы одна дуга, а также все вершины, из которых выходят некоторые дуги, если ни одна из вершин не пройдена дважды. Если такой кратчайший путь существует, то он присоединяется к текущему пути, после чего делается переход к шагу Б5. В противном случае фиксируется следующий вход, если это возможно, и делается переход к шагу Б3.

Б9. Участкам пути, входящим в макровершины, присваиваются весовые коэффициенты в соответствии с весами макровершин. Для каждого полного пути определяется весовой коэффициент пути, равный сумме весов входящих в него участков.

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

Необходимо сделать некоторые пояснения к алгоритму Б:

  • при построении кратчайшего пути до ближайшей вершины из допустимого множества используется модификация известного алгоритма Дейкстры (достаточно сравнивать вершину с минимальной временной пометкой на принадлежность допустимому множеству);

  • при выполнении шага Б8 ограничения на допустимое множество накладываются в соответствии с двумя соображениями: во-первых, желательно получить не слишком длинные пути, так как весьма вероятно, что они окажутся нереализуемыми, а во-вторых, желательно получить как можно больше путей, однако при этом необходимо контролировать выполнение условия, чтобы число путей не превысило топологическую сложность рассматриваемого участка программы (топологическая сложность определяется при построении структурного дерева программы по алгоритму Б);

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

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]