четверг, 17 февраля 2011 г.

ISSP \ Домен 09. Безопасность приложений. Часть 5

В этой части рассмотрены следующие вопросы:
  • Методы разработки программного обеспечения
  • Средства автоматизированной разработки программного обеспечения (CASE-средства)
  • Разработка прототипов
  • Методология безопасного проектирования
  • Методология безопасной разработки
  • Проверка на защищенность
  • Управление изменениями
  • Модель зрелости процессов разработки программного обеспечения (CMM)
  • Передача исходного кода программного обеспечения на хранение независимой третьей стороне


За многие годы были созданы различные Методы разработки программного обеспечения (SDM – System Development Methods), направленные на удовлетворение различных требований разработчиков и поставщиков. Обычно эти методы называют руководствами по разработке, которыми они на самом деле и являются, они помогают разработчикам на различных этапах создания программного обеспечения (анализ, проектирование, программирование, сопровождение). Существует множество таких методов, ниже представлены несколько из них:
  • Водопад (Waterfall). Классический метод, в котором процесс разработки выглядит как поток, последовательно проходящий отдельные этапы проекта разработки. Этот метод требует полного и успешного завершения предыдущего этапа, его формального анализа и документирования перед переходом к следующему этапу проекта. Возврата к предыдущим этапам не происходит. Результат появляется только в конце разработки.
  • Спираль (Spiral). Метод уделяет повышенное внимание анализу рисков, созданию прототипов и моделированию, выполняемым на различных этапах цикла разработки. Каждый виток спирали соответствует созданию фрагмента или версии программного обеспечения, после чего определяется его качество и планируются работы следующего витка спирали. Этот метод периодически возвращается к предыдущим этапам для уточнения целей и характеристик проекта. Метод сочетает в себе подходы методов прототипирования и водопада. Результат появляется, фактически, на каждом витке спирали, работы завершаются после того, как разработчик и заказчик придут к согласию относительно приемлемости полученного результата.
  • Структурное программирование (Structured Programming Development). Методология программирования, которая применяет иерархическую структуру логических блоков и методы процедурного программирования. Структурирование программы с использованием подпрограмм (процедур и функций) минимизирует применение команд произвольного перехода (таких как GOTO) и делает акцент на единых точках входа и выхода. Такой иерархический подход упрощает понимание и дальнейшее внесение изменений в программу. Структурное программирование позволяет совместно использовать модули, что улучшает использование памяти.
  • Итеративная разработка (Iterative Development). Метод, использующий циклический подход (Цикл Деминга - планирование-реализация-проверка-корректировка) к разработке программного обеспечения, при котором работы производятся параллельно с непрерывным анализом полученных результатов и корректировкой предыдущих этапов работы. В отличие от традиционных моделей, итеративная разработка фокусируется на планировании контрольных точек проекта (milestones) на основе ресурсов и времени, постоянной оценке соответствия текущего состояния проекта первоначальным целям. Итеративная разработка позволяет динамически оценивать состояние проекта в целом и вносить необходимые поправки для повышения эффективности реализации проекта.
  • Модифицированная модель прототипирования (MPM – Modified Prototype Model). Метод, специально созданный, чтобы противостоять сложностям при разработке веб-приложений. Модифицированная модель прототипирования позволяет разработчикам быстро перевести требования клиента в отображаемый на экране прототип. Прототипы обычно используются разработчиками и заказчиками, когда они не уверены в характеристиках окончательного продукта. Использование прототипов позволяет уточнить окончательный продукт и сделать технические требования менее туманными.
  • Экспериментальная модель (Exploratory Model). Метод, используемый в случаях, когда отсутствуют четко определенные цели проекта. Вместо концентрации на подробных задачах, экспериментальная модель использует набор спецификаций, заключающих в себе сведения о работе окончательного продукта. Тестирование является важной частью экспериментальной разработки, поскольку оно позволяет убедиться, что текущий этап проекта соответствует вероятным сценариям реализации.
  • Совместная разработка (JAD – Joint Analysis Development). Метод, который позволяет разработчикам напрямую взаимодействовать с пользователями в процессе разработки, а также акцентирует внимание на совместной (командной) работе разработчиков и специалистов, которые хорошо разбираются в методологии и проектировании.
  • Быстрая разработка приложений (RAD – Rapid Application Development). Метод определения требований пользователей (с помощью прототипов) и быстрой разработки систем. Применяется циклический подход к разработке - каждая новая версия продукта основывается на оценке предыдущей версии заказчиком. Минимизация времени разработки достигается за счет переноса в новый продукт уже готовых модулей и добавления необходимой функциональности. Метод RAD может использоваться для решения срочных задач. 
  • Модель повторного использования (Reuse Model). Модель, в которой для разработки программного обеспечения используются уже существующие компоненты. Эта модель лучше всего подходит к реализации проектов, основанных на объектно-ориентированном программировании. Поскольку в этой модели программы не разрабатываются «с нуля», это значительно снижает стоимость и время разработки.
  • Чистая комната (Cleanroom). Подход, который пытается предотвратить возможные неточности и ошибки, следуя структурированным и формализованным методам разработки и тестирования. Этот подход используется для разработки высококачественных и критичных приложений, которые будут проходить строгий процесс сертификации.
  • Компонентно-ориентированная разработка (Component-Based Development). Модель, которая использует независимые и стандартизованные модули (компоненты), из которых собираются работоспособные программы. Каждый стандартный модуль содержит функциональный алгоритм или набор команд, а также интерфейс для взаимодействия с другими модулями. Примером таких модулей могут быть объекты, которые применяются в объектно-ориентированном программировании. Разработка на основе компонентов обеспечивает возможность повторного использования и расширения функциональности программ. Компонентно-ориентированная разработка широко используется в современном программировании, этот метод позволяет значительно снизить стоимость разработки программного обеспечения.
  • Экстремальное программирование (Extreme Programming). Методология, которая обычно применяется в ситуациях, требующих быстрой адаптации под изменяющиеся требования заказчика. Экстремальное программирование придает особое значение обратной связи от заказчика для оценки результатов проекта. Принципы создания программного обеспечения при использовании экстремального программирования отбрасывают традиционное долгосрочное планирование, выполняемое для возможности повторного использования кода, и вместо этого фокусируется на создании простого кода, оптимизированного только для этого проекта. Экстремальное программирование исходит из предпосылки, что требования заказчика вероятнее всего существенно изменятся в рамках жизненного цикла проекта, и концентрируется на процессе разработки, чтобы подстроиться под эти изменения.

Автоматизированная разработка программного обеспечения (CASE – Computer-aided software engineering) - это набор инструментов («CASE-средств») и методов разработки и управления программным обеспечением, используемых программистами, разработчиками, менеджерами проектов и аналитиками, помогающих ускорить разработку программ, обеспечить их высокое качество, простоту сопровождения и минимизировать число ошибок. CASE-средства автоматизируют многие задачи (в т.ч. управленческие, административные и технические), ранее выполнявшиеся вручную.

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

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

Если предоставляемая CASE-средством автоматизация охватывает весь жизненный цикл продукта, такие средства называют инструментами комплексной автоматизированной разработки программного обеспечения (I-CASE – Integrated CASE).


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

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

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

Если создание прототипа в виде программы оказывается непрактичным, могут быть разработаны бумажные прототипы, в которых взаимодействие, запросы, виды экранов и схемы программной логики изображены на бумаге. Бумажные прототипы также могут разрабатываться для заказчиков и/или разработчиков. На отдельных листах могут быть изображены виды экрана, а также схемы действий, которые происходят «за кадром».


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

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

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

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


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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

1. Оформить официальный запрос на изменение
2. Проанализировать запрос
    a) Разработать стратегию реализации
    b) Рассчитать стоимость реализации
    c) Проанализировать все последствия для безопасности
3. Зарегистрировать запрос на изменение
4. Передать запрос на изменение для утверждения
5. Разработать изменение
    a) Переписать код части продукта, добавить или исключить требуемую изменением функциональность
    b) Связать эти изменения в коде с официальным запросом на изменение
    c) Передать программное обеспечение для тестирования и подтверждения качества
    d) Повторять, пока не будет обеспечено надлежащее качество
    e) Произвести изменение версии
6. Отчитаться о результатах руководству

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


Модель зрелости процессов разработки программного обеспечения (CMM – Capability Maturity Model) описывает процедуры, принципы и приемы, которые лежат в основе зрелости процесса разработки программного обеспечения. Эта модель была разработана, чтобы помочь производителям программного обеспечения улучшить свои процессы разработки, предоставив эволюционный путь развития для достижения упорядоченных и повторяемых методов, которые повышают качество программного обеспечения, уменьшают жизненный цикл разработки, позволяют лучше управлять проектами, создавать контрольные точки и своевременно достигать их, использовать проактивный подход, вместо менее эффективного реактивного подхода.

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

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

В модели CMM используются пять уровней зрелости:
  • Начальный (Initial). Решения в рамках процесса разработки принимаются в зависимости от обстоятельств, либо этот процесс полностью хаотичен. Компания не использует эффективные процедуры управления проектами и не занимается планированием. Результаты такого процесса разработки непредсказуемы и полностью зависят от способностей отдельных сотрудников, качество не гарантируется.
  • Повторяемый (Repeatable). Созданы и задокументированы формальные процедуры управления проектами, управления изменениями и обеспечения качества. Компания может повторять накопленный ранее успешный опыт в каждом проекте. Результаты более предсказуемы, но все еще зависят от способностей отдельных сотрудников. У компании нет определенной формальной модели процессов.
  • Определенный (Defined). Описаны и внедрены формальные процедуры, которые объединены в общий процесс разработки программного обеспечения, повторяемый в каждом проекте. Появляется возможность точной оценки сроков и себестоимости реализации продукта. Результат предсказуем и не зависит от способностей отдельных сотрудников. Компания идет по пути постоянного совершенствования процессов.
  • Управляемый (Managed). Описаны и внедрены формальные процессы сбора и анализа количественных показателей, в том числе, показателей качества. Определены и применяются метрики, позволяющие измерить эффективность процессов разработки. Метрики учитываются в программе совершенствования процессов. Осуществляется более точное планирование. Результат полностью предсказуем.
  • Оптимизированный (Optimizing). Компания выделяет бюджет и планирует непрерывное совершенствование процессов. Степень улучшения процессов и их эффективность может оцениваться количественно.

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

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

2 комментария:

eagle комментирует...

- Почему нужно делать прототипы. Как донести свою идею до инвестора без лишних затрат. http://www.techdays.ru/videos/3325.html

eagle комментирует...

- Методология разработки безопасного ПО (SDL) и результаты ее применения в Microsoft. http://www.techdays.ru/videos/1532.html
- Обзор Security Development Lifecycle (SDL) - чем он может помочь разработчику. http://www.techdays.ru/videos/1232.html