Спорите с подрядчиком об учётной системе, настольной программе или веб-сервисе, и написаны они на C#. В суде такой спор сводится к тому же вопросу, что и любой другой спор о разработке: соответствует ли сделанное техническому заданию. Но здесь подступиться к ответу проще, чем в большинстве других языков, и причина техническая. Программы для платформы .NET, на которой работает C#, обычно не переводят в машинный код процессора: они хранятся в промежуточном представлении — его называют промежуточным языком, сокращённо IL, — из которого специальные средства восстанавливают текст, очень близкий к исходному: с именами классов, методов и полей, с сохранённой структурой типов. Исключение есть, и его проверяют первым делом — по самой сборке, а не со слов сторон. Программу на .NET можно опубликовать уже переведённой в машинный код, и режимов таких два. При первом машинный код добавляют к промежуточному представлению, и текст восстанавливается в полном обычном объёме. При втором, доступном начиная с .NET 7, промежуточного представления в файле не остаётся вовсе — тогда восстановление невозможно так же, как в C++. Различают их по содержимому файла, и вывод «объекта нет» делают по отсутствию промежуточного представления, а не по одному тому, что в файле есть машинный код. Поэтому вопрос «а есть ли вообще исходный код» здесь почти никогда не бывает тупиком. Экспертиза исходного кода на C# — специализированное направление экспертизы процесса разработки программного обеспечения. В итоге вы получаете заключение с описанием объектов, методов и ограничений; какое доказательственное значение оно получит, оценивает суд.
Если спор уже начался, сохраните то, что удаляют первым. Собранные файлы программы — их называют сборками — обычно остаются целы: они установлены у вас и работают. Быстрее исчезает другое: доступ к хранилищу исходных текстов, записи сервера сборки, содержимое площадки, где программа развёрнута. Что именно сохранять, разобрано ниже, в разделе «Что сохранить, пока сборки и история на месте».
Начать можно с разговора, и он бесплатный: назовите систему, опишите спор и перечислите, что у вас на руках. Пока ничего собирать и никуда загружать не нужно — порядок передачи материалов мы предложим отдельно, когда станет понятно, какие из них вообще потребуются.
С какими спорами приходят по программам на C#
Обращаются, когда разногласия упираются в проверяемое: в состав переданного, в поведение программы при названных условиях и в зафиксированный ход работ. До начала работы определите, о какой версии, площадке и периоде идёт речь, — без этого у исследования нет предмета.
Типичные ситуации выглядят так:
- подрядчик сдал учётную или складскую систему, настольную программу на WinForms или WPF либо веб-сервис на ASP.NET, а заказчик считает техническое задание невыполненным;
- исходный код передали, но собрать из него работающую программу не получается: не хватает файлов проекта, пакетов или настроек;
- переданные сборки закрыты обфускатором, и заказчик не может ни доработать систему, ни сменить исполнителя;
- программа падает, зависает или со временем занимает всю доступную память, и стороны спорят, дефект это или условия эксплуатации;
- заказчик утверждает, что подрядчик выдал за свою разработку чужой код или пакет, условия которого нарушил;
- спорят о переносе системы с прежней платформы .NET Framework на современную и о том, входил ли этот перенос в работы;
- требуется установить, к какому периоду относится спорная версия и что изменилось между выпусками.
Если спор идёт об обмене с учётной системой предприятия, начните со страницы экспертизы 1С: там объекты и следы другие.
Почему по .NET исходный текст почти всегда восстановим
Разница с языками, которые переводят программу прямо в машинный код, принципиальная, и на ней держится всё дальнейшее. Программу на C++ переводят в машинный код необратимо. Программу на C# компилируют в промежуточное представление IL, которое сохраняет имена и структуру: средства вроде ILSpy, dnSpy и dotPeek читают собранный файл и выдают текст на C#, местами почти совпадающий с исходным. Такое восстановление называют декомпиляцией, а сами средства — декомпиляторами.
Что это значит для спора. Заказчик без исходников не остаётся без предмета: по установленной у него программе эксперт устанавливает состав классов и методов, обращения к базе и внешним системам, использованные пакеты, тексты сообщений и значительную часть логики. Утверждение «мы не можем ничего проверить, потому что нам не отдали код» здесь обычно не подтверждается.
О потерях эксперт говорит прямо, и они известны заранее: комментарии и авторские пояснения не сохраняются никогда; имена локальных переменных исчезают, если рядом нет отладочных данных; в самой сборке не хранится исходное разбиение по файлам — средство восстановления раскладывает типы по собственному правилу, и части, написанные в одном файле, оказываются в разных; но если сохранены файлы отладочных данных — отдельные или встроенные в сборку, — исходные пути и принадлежность методов файлам восстанавливаются из них. Конструкции, которые компилятор разворачивает — асинхронные методы, перечислители, вложенные функции, — современные средства обычно собирают обратно, но не всегда: на отдельных сочетаниях восстановление срывается и выдаёт развёрнутую форму, а эксперт помечает такие места. Поэтому восстановленный текст не тождествен переданному исходному коду, и подменять им объект исследования нельзя: в заключении всегда указывают, что именно исследовалось — исходные тексты или результат восстановления.
Обфускация: зачем её ставят и что она значит для спора
Ровно потому, что исходный текст .NET восстанавливается легко, разработчики массово применяют средства, которые это затрудняют. Их называют обфускаторами, распространённые — Dotfuscator, ConfuserEx и подобные. Они переименовывают классы и методы в бессмысленные наборы знаков, прячут текстовые строки, запутывают порядок выполнения. Есть и более тяжёлые средства — упаковщики и преобразователи кода в собственное представление: после них привычные способы восстановления сразу не работают, сборку сначала приводят в обычный вид отдельными средствами, и удаётся это не всегда. Какое средство защиты применено и удалось ли его снять — отдельный факт, который эксперт устанавливает до всего остального и указывает в заключении.
Простое переименование меняет трудоёмкость и точность, но не результат: состав пакетов, обращения к системе и внешним сервисам, структура данных устанавливаются и по такой сборке. Спрятанные строки восстанавливаются наблюдением за работой программы, а не чтением, и это отдельный труд. А вот назначение конкретного метода приходится выводить из его поведения, и такой вывод эксперт помечает как предположительный.
Уже сам факт защиты в споре нередко весит больше, чем содержимое сборок. Если заказчик рассчитывал получить сопровождаемую систему, а получил закрытые сборки без исходников, это проверяемое обстоятельство: эксперт устанавливает, какие сборки обработаны, каким средством и какая доля кода закрыта. Правовую оценку — нарушены ли этим обязательства подрядчика — даёт суд.
Что сохранить, пока сборки и история на месте
Копируйте и передавайте только то, что принадлежит вам или к чему у вас есть законное право доступа; чужие системы исследуют по определению суда или иного уполномоченного органа. Если доступ к хранилищу исходных текстов есть только у подрядчика, с которым вы спорите, действовать самостоятельно не нужно: письменно потребуйте передать материалы по договору и зафиксируйте отказ или молчание. Чужое получают через суд по возбуждённому делу — ходатайством об истребовании доказательства, в котором называют, что именно требуется, какие обстоятельства этим подтверждаются и почему получить его самостоятельно нельзя.
Разумный минимум выглядит так:
- сохраните каталог установленной программы целиком, вместе с файлами настроек и вспомогательными сборками — именно он чаще всего оказывается единственным бесспорным объектом;
- если доступ к хранилищу исходных текстов у вас есть, снимите архивом его полную копию со всей историей, ветками и метками — чаще всего это Git;
- заберите файлы отладочных данных, если они лежат рядом со сборками: в .NET их называют PDB, и с ними восстановление точнее;
- сохраните записи сервера сборки за спорный период: когда, из чего и с какими настройками выпускались версии;
- выгрузите базу данных и настройки площадки, где программа развёрнута, — журналы веб-сервера или службы, конфигурацию;
- для каждого архива посчитайте контрольную сумму и сохраните её отдельно от него — например, в письме самому себе. Это короткая строка, вычисленная из содержимого файла: поменяется в архиве хоть один знак — поменяется и она, поэтому записанная сегодня сумма завтра докажет, что архив тот самый. Команда зависит от того, где лежит архив: в Windows через PowerShell —
Get-FileHash архив.zip -Algorithm SHA256, через обычную командную строку —certutil -hashfile архив.zip SHA256; на сервере под Linux —sha256sum архив.zip, в macOS —shasum -a 256 архив.zip; - напишите служебную записку на полстраницы: какие архивы получены, с какого сервера, в какой день, под чьей учётной записью и кто при этом был. Через год это единственное, что объяснит происхождение файлов.
Выполнять это должен тот, у кого есть доступ к серверу и хранилищу, — ваш системный администратор или сотрудник, ведущий инфраструктуру. Если такого человека нет или вы не уверены, с чего начать, позвоните по номеру 8 (800) 333-24-09: подскажем порядок под вашу ситуацию, это бесплатно.
Пока состояние не зафиксировано, не переустанавливайте программу, не обновляйте её на спорной площадке, не удаляйте старые версии и ветки, не очищайте журналы. Копия, снятая своими силами, доказывает меньше, чем кажется: другая сторона вправе сказать, что архив собран уже после спора. Усиливают её посчитанные сразу контрольные суммы и обеспечение доказательств. Путей три, и они не взаимозаменяемы: до обращения в суд доказательство закрепляет нотариус; в арбитражном процессе суд вправе обеспечить доказательство и до предъявления иска — по заявлению, которое рассматривается по правилам о предварительных обеспечительных мерах; по уже возбуждённому делу подают ходатайство об обеспечении доказательств.
Сборка .NET повторяема — и это меняет доказывание
Здесь .NET выигрывает у большинства языков. В большинстве из них одинаковый исходный текст даёт разные собранные файлы, и побайтовое сравнение ничего не доказывает. В современном .NET сборка по умолчанию детерминирована: при одинаковых входных данных и настройках результат совпадает вплоть до байта, и это свойство заявлено самой платформой.
Работает это при одном условии: исходный текст у вас есть — передан подрядчиком или истребован через суд. Если на руках одни сборки, собирать нечего, и спор решается другим путём, описанным выше: составом классов и методов, обращениями к базе, текстами сообщений, восстановленными из самой программы. Тогда переходите сразу к следующему разделу.
Когда исходники есть, вопрос «получается ли из переданного текста именно эта программа» решается здесь строже, чем где-либо. Эксперт восстанавливает окружение — версию набора средств разработки, состав пакетов, настройки проекта, — причём восстанавливает по сведениям внутри самих спорных файлов и файлов отладочных данных, а не только со слов стороны, и собирает переданный текст.
Критерий вывода формулируют до сборки, а не по её итогу. Совпадение полученного файла со спорным — сильный довод в пользу того, что программа собрана из переданного текста; и когда повторяемость подтверждена, сравнивать можно побайтово. Расхождение само по себе обратного не доказывает: часть его объясняется другой версией средств, другим составом пакетов, включёнными в файл сведениями о времени сборки и подписью, поставленной после неё. Каждое такое объяснение эксперт обязан проверить и показать, а не предположить. Если объяснить расхождение нечем, вывод отрицательный; если окружение восстановить не удалось, вопрос остаётся без ответа, и это тоже итог работы.
Но с оговоркой. Детерминированность — свойство современных версий платформы; у старых проектов на .NET Framework её может не быть. И даже в современной сборке в файл попадают пути к исходным текстам, поэтому у эксперта, собирающего код в своём каталоге, побайтового совпадения без специальных настроек не выйдет — эти настройки задают заранее и указывают в заключении. Поэтому первым делом проверяют, повторяем ли результат вообще, и двух одинаковых прогонов для этого мало: текст собирают дважды в намеренно разных условиях — в другом каталоге, под другой учётной записью, по возможности на другой машине. Совпало — сравнение со спорным файлом можно вести по байтам. Разошлось — сравнивают по содержанию: составу типов и методов, строкам, обращениям к внешним сборкам.
Версию платформы вам определять не нужно, и спрашивать её у подрядчика, с которым вы спорите, тем более: она записана в самих файлах программы. Назовите систему и год разработки или пришлите перечень файлов из каталога программы — прочитаем на бесплатном разборе.
Подпись сборки и строгое имя: что они доказывают
У сборок .NET есть два разных механизма подтверждения происхождения, и путать их не следует.
Первый — строгое имя: сборка подписывается ключом разработчика, и в неё попадает открытая часть этого ключа. Механизм задумывался как способ различать сборки с одинаковыми именами, а не как защита: подпись снимается и ставится заново другим ключом, а современные версии платформы её при запуске вообще не проверяют. Поэтому вывод по строгому имени возможен только один и только при наличии эталона: отпечаток ключа в спорной сборке совпадает или не совпадает с отпечатком в сборке, происхождение которой известно. Второй механизм — цифровая подпись файла средствами операционной системы, с сертификатом издателя; она проверяется системой и позволяет установить, кому выдан сертификат и не изменялся ли файл после подписания. А вот дата подписания из подписи сама по себе не следует: время в ней ставит по часам своего компьютера тот, кто подписывал. Проверяемым фактом дата становится только при отметке времени независимой службы — эксперт смотрит, есть ли она, кто её выдал и был ли сертификат действителен на тот момент. Без отметки времени вывод о дате по подписи не делают.
В обоих случаях у вывода есть предел. Даже действительная подпись не говорит об авторстве кода: ключ передают подрядчику, он бывает общим у нескольких проектов, а неподписанная сборка — обычное дело для внутренней разработки. Поэтому подпись работает как один признак в совокупности, а не как самостоятельное доказательство. Если ключ подписи оказался в переданных вам материалах, его следует заменить: обладатель ключа может подписать чужую сборку от вашего имени.
Пакеты NuGet и условия их использования
Готовые библиотеки в .NET подключают пакетами, и их состав восстанавливается надёжнее, чем в большинстве языков. Ссылки на пакеты хранятся прямо в файле проекта, а при включённой блокировке версий — ещё и в отдельном файле, закрепляющем точный набор вместе с косвенными зависимостями. У старых проектов на .NET Framework их ищут в отдельном файле packages.config рядом с проектом — если его не прислали, состав пакетов придётся выводить по самой программе. Если исходников нет, состав определяют по самой программе: подключённые сборки видны в её служебных сведениях, а у многих пакетов есть узнаваемые имена и номера версий.
Каталог загруженных пакетов — не работа подрядчика, и при подсчёте объёма его вычитают. Но подбор библиотек и поддержание их версий — тоже труд, и он оценивается отдельно от числа строк.
Условия использования пакета записаны в его лицензионном документе — MIT, Apache, BSD, GPL, LGPL и других; встречаются и коммерческие библиотеки с оплатой по числу разработчиков. Эксперт устанавливает факты: какой пакет какой версии подключён, каким документом сопровождается и что в этом документе написано; текст приводится в заключении. Толкование условий и вывод о том, нарушены ли они, — вопрос права, и решает его суд.
.NET Framework и современный .NET: спор о переносе
Отдельная и частая тема. Долгое время программы для Windows писали под платформу .NET Framework; ей на смену пришла новая, кроссплатформенная линейка, а поддержка старой ограничена. Из этого вырастают два типа споров.
Первый: заказчик считает, что подрядчик обязан был сделать систему на современной платформе, а получил её на устаревшей. Здесь эксперт устанавливает факт — под какую платформу и версию собрана программа, — а вопрос о том, следовало ли из договора требование к платформе, решается по документам. Если требование в задании названо, несоответствие проверяемо; если не названо, вывод о «неправильном выборе» становится оценочным, и эксперт его не делает.
Второй: перенос заказан, выполнен, и стороны спорят о его полноте. Здесь работа предметнее: эксперт сравнивает состав функций до и после переноса, проверяет, какие части остались на прежней платформе, какие внешние компоненты не имеют замены, и воспроизводит заявленные сценарии на обеих версиях. Типичные находки — не переписанные фрагменты, работающие через прослойку совместимости, и функции, которые после переноса ведут себя иначе из-за смены поведения библиотек.
Отказы, зависания и рост потребления памяти
Материал для таких вопросов специфический: программа должна оставить след, и в .NET следов обычно больше, чем в других средах.
При необработанной ошибке среда выполнения записывает сведения о месте отказа: цепочку вызовов с именами методов, а при сохранённых отладочных данных — и номера строк. Эти сведения попадают в журнал приложения, в журнал событий Windows или в файл снимка памяти, если его сохранение включено. По ним восстанавливают, где именно произошёл отказ и с какими данными работала программа. Место, где отказ проявился, при этом не всегда совпадает с местом дефекта — как и в других средах, эксперт проверяет альтернативные объяснения: неверные входные данные, недоступность внешней системы, нехватку ресурсов, действия других программ.
Зависание исследуют иначе, чем отказ: пока программа не отвечает, снимают снимок её состояния и смотрят, чем заняты потоки — ждут ли они ответа базы или внешней системы, встали ли на общей блокировке или заблокировали друг друга взаимным ожиданием. Один снимок показывает картину, два-три подряд отвечают на вопрос, стоит она или движется медленно, — а это разные обстоятельства, и в заключении их не смешивают.
Рост потребления памяти исследуют воспроизведением на стенде — отдельном компьютере, настроенном как рабочий, — со снятием снимков состояния памяти в разные моменты и сравнением между ними. В .NET память освобождается автоматически, поэтому классическая утечка встречается реже, а типичная причина другая: объекты остаются связанными с долгоживущим обработчиком событий, кешем или статическим полем и потому не освобождаются. Но дело этим не исчерпывается: память может расходоваться вне управляемой области — соединениями, файлами, графическими ресурсами, которые не закрывают, — и такой рост сравнение снимков не покажет. Поэтому наблюдают и за общим потреблением процесса, а расхождение между ним и объёмом управляемых объектов само по себе указывает, где искать. Вывод о том, что дефект есть, сопровождают указанием, при каком сценарии он воспроизведён, и оценкой того, наступают ли последствия при заявленном в задании режиме эксплуатации.
Где у решения на .NET прячется логика помимо кода
Заключения чаще всего портит одно: эксперт смотрит только код. У корпоративных решений значительная часть поведения задаётся вне программы.
Смотреть нужно как минимум сюда:
- файлы настроек приложения и веб-сервиса: строки подключения к базе, адреса внешних систем, включённые и выключенные возможности;
- переменные окружения и параметры запуска службы: в современном .NET они перекрывают записанное в файлах, поэтому один файл настроек без них картины не даёт;
- саму базу данных: справочники, правила расчёта, права доступа, хранимые процедуры — на SQL Server значительная часть логики нередко живёт именно там;
- настройки площадки: параметры веб-сервера IIS или службы Windows, расписания фоновых задач, учётные записи, от имени которых всё работает;
- обмен с внешними системами: адреса, форматы, журналы обеих сторон;
- файлы, загруженные пользователями, и шаблоны документов, если система их формирует.
Одного каталога с программой обычно мало, и объём материалов лучше согласовать заранее — иначе исследование упрётся в вопрос, ответ на который лежит в настройке, а не в коде.
Сравнение двух кодовых баз: почему по .NET это работает лучше
Спор о заимствовании по .NET разбирают полнее, чем по большинству языков, и снова из-за восстановимости кода. Сравнивать можно не только исходные тексты, но и собранные файлы — а значит, у эксперта есть объект даже тогда, когда одна из сторон исходники не отдала.
Сравнение ведут по промежуточному представлению, а не по восстановленному тексту: восстановление зависит от средства и его версии, и два инструмента дадут разный текст из одного и того же файла. Промежуточный код от этого не зависит и потому пригоден для сопоставления. Сравнивают состав типов и их членов, структуру и порядок операций внутри методов, тексты сообщений, схему данных.
Как и в других языках, из сравнения сначала вычитают общее основание — но перечень вычитаемого задают в тех же единицах, в которых ведут сравнение, иначе вычитание не срабатывает. В промежуточном представлении это код подключённых пакетов; то, что среда разработки создаёт сама, — описания форм, модели данных, обёртки; стандартные конструкции языка; и, что важнее всего, код, который дописывает сам компилятор: развёрнутые асинхронные методы и перечислители, классы для замыканий, хранилища автоматических свойств, служебные члены. Этот слой у двух независимо написанных программ совпадает просто потому, что его создал один и тот же компилятор, и без его вычитания процент совпадения получается бессмысленно высоким. По той же причине версию компилятора и настройки сборки либо уравнивают, либо учитывают при оценке: они сами порождают и совпадения, и расхождения. Значимыми считают совпадения, которые общим основанием не объясняются, и каждое проверяют вручную. Развёрнуто эта задача разобрана на странице экспертизы плагиата исходного кода.
Как датируют спорную версию
Вопрос «когда это было написано» возникает почти в каждом споре о сроках, и надёжного одиночного источника для него не существует ни в одном языке. По .NET источников больше обычного, но каждый со своими пределами.
Что даёт На что при этом опираются::
- история в хранилище исходных текстов — самый содержательный источник, но даты в ней задаются свободно штатными средствами, поэтому её подтверждают другими;
- записи сервера сборки: когда, из чего и с какими настройками выпускалась каждая версия, — их подделать сложнее, потому что они ведутся отдельной системой;
- сведения о версии внутри самих файлов программы и время их создания на площадке — но файловые метки переписываются копированием и переустановкой, поэтому сами по себе они доказывают мало;
- отметка времени в цифровой подписи сборки, если она есть: это единственный источник даты, не зависящий от часов того, кто подписывал;
- журналы установки и обновления на сервере заказчика, резервные копии за прошлые периоды;
- переписка сторон с вложениями, акты и задачи в системе учёта.
Совпадение независимых источников позволяет говорить о периоде обоснованно; расхождение эксперт обязан показать, а не сгладить. Если спор именно о сроках и хронологии работ, его разбирает экспертиза сроков и хронологии разработки.
Когда спор выходит за пределы C#
Крупные системы редко пишут на одном языке: серверная часть на C# обрастает интерфейсом в браузере, обменом с учётной системой и вспомогательными сервисами. Границу исследования лучше провести до постановки вопросов.
Обычно её проводят так:
- спор о самой программе на C#, её сборках, базе и развёртывании: это и есть предмет настоящего направления;
- претензия к тому, что происходит в браузере пользователя, а не на сервере: экспертиза кода на JavaScript;
- спор о серверной части, написанной на другой платформе: экспертиза кода на Java;
- спор о сайте или интернет-магазине: экспертиза кода на PHP;
- спор о программе для оборудования или о расчётном ядре: экспертиза кода на C++;
- спор о воспроизводимости расчёта в обработке данных: экспертиза кода на Python.
Ссылки на соседние направления — не предложение заказать несколько экспертиз. Все они ведутся одной организацией, и, когда задач в споре несколько, их обычно ставят вопросами в одном исследовании: это дешевле и быстрее нескольких отдельных заключений. Знать язык заранее не обязательно — его называют в техническом задании и в актах, а по составу файлов эксперт определяет его сам.
Какие обстоятельства устанавливают по программе на C#
Что именно устанавливать, определяет поставленный вопрос. Но перечень возможного по .NET шире, чем по языкам, которые переводят программу прямо в машинный код, и полезно знать его заранее — хотя бы для того, чтобы не просить эксперта о невозможном и не упустить достижимое.
- сохранено ли в спорных файлах промежуточное представление — от этого зависит, есть ли объект для восстановления вообще;
- та ли это программа: собирается ли из переданных исходников то, что установлено у заказчика, и в чём расходится;
- выполнено ли каждое проверяемое требование задания — с указанием объекта и способа, которым это проверялось;
- состав подключённых пакетов, их версии и то, какими лицензионными документами они сопровождаются;
- применялась ли обфускация, к каким сборкам и в каком объёме;
- под какую платформу и версию собрана программа, чем подписана и когда;
- причина отказа, зависания или роста потребления памяти при воспроизведённом сценарии;
- совпадения между двумя кодовыми базами за вычетом пакетов, шаблонного и сгенерированного кода;
- чем спорная версия отличается от предыдущей и что изменилось между ними;
- когда выпущена спорная версия — по совпадению нескольких независимых источников;
- сколько кода написано подрядчиком за вычетом пакетов и сгенерированных файлов — величина техническая, стоимость по ней не выводится.
За пределами перечня остаётся то, что решает суд: добросовестность сторон, толкование договора, существенность недостатка, размер убытков. Технический вывод даёт для этого основание, но не заменяет его. Спор о деньгах выделяют в самостоятельный вопрос — им занимается экспертиза объёма и стоимости работ, при необходимости вместе с экономистом.
Как проверяют соответствие заданию по коду и по работающей системе
По .NET у эксперта редко бывает один объект: почти всегда есть и работающая система, и сборки, а нередко и исходные тексты. Поэтому проверку каждого требования привязывают к тому объекту, на котором оно вообще проверяемо, и пишут об этом в заключении.
У каждого требования свой объект. Требования, сформулированные в терминах устройства программы — «модуль расчёта должен быть выделен», «обмен должен идти через очередь», — проверяют по коду: по исходному тексту, если он передан, иначе по восстановленному из сборок, и разница между этими двумя случаями оговаривается прямо. Требования о поведении проверяют на стенде: поднимают ту же версию платформы, разворачивают копию базы и подставляют заглушки вместо внешних сервисов. Требования, которые без данных заказчика или без живых сервисов не воспроизводятся, проверяют на его площадке — по сценарию, согласованному заранее, в согласованное время и силами его сотрудников. Односторонней такая проверка быть не должна: по судебной экспертизе лица, участвующие в деле, вправе присутствовать при её производстве, а порядок и время работ на площадке определяет назначивший орган. Возражение другой стороны само по себе результат не отменяет — допустимость и вес такого эксперимента оценивает суд, но проверка, поставленная на оборудовании одной стороны без её извещения, эту оценку почти наверняка не выдержит. Поэтому доступ согласуют через суд, а ход и результат протоколируют.
Результат по каждому требованию записывают одинаково: реализовано, реализовано частично, не реализовано либо не проверяется на представленных объектах, — с указанием объекта, способа и полученного результата. Последний исход по .NET встречается реже, чем там, где программа переведена прямо в машинный код, но встречается: чаще всего тогда, когда требование завязано на внешнюю систему, доступ к которой не предоставлен. Существенность недостатка и его влияние на приёмку оценивает суд. Если спор целиком о соответствии заданию и язык значения не имеет, задачу закрывает экспертиза соответствия работ техническому заданию.
Что просят прислать по спору о системе на .NET
Набор материалов по этому направлению шире, чем по языкам, где всё умещается в один каталог с кодом: у корпоративной системы объект распределён между исходниками, сборками, базой и площадкой.
Программа: исходники, сборки, пакеты
Первая часть — то, из чего программа получается и во что превращается:
- исходные тексты вместе с файлами проектов и решения — с ними разбор идёт короче и точнее всего, а контрольная сборка возможна только по ним; если их нет, работают по сборкам, и это отдельно оговаривается в заключении;
- хранилище исходных текстов с полной историей, ветками и метками, если оно велось;
- сборки спорной версии и, если сохранились, предыдущих — по ним сравнивают, что изменилось между выпусками;
- файлы отладочных данных, лежащие рядом со сборками: с ними восстановление точнее, а разбор отказа превращается в чтение;
- ссылки на пакеты в файлах проектов, файл блокировки версий и, для развёрнутого приложения, список зависимостей, который создаётся при публикации;
- сведения о наборе средств разработки: версия платформы, целевая версия, параметры сборки.
Площадка: где система живёт и что она о себе оставила
Вторая часть — то, без чего первая объясняет не всё:
- файлы настроек приложения и площадки, включая параметры веб-сервера IIS или службы Windows;
- выгрузка базы данных: справочники, правила, права доступа, хранимые процедуры;
- журналы приложения и журнал событий Windows за спорный период, снимки памяти при отказах;
- журналы обмена с внешними системами — с обеих сторон, если это возможно;
- записи сервера сборки: когда, из чего и с какими параметрами выпускалась каждая версия;
- техническое задание с приложениями, договор, акты, переписка сторон, задачи в системе учёта, документы на коммерческие компоненты.
Чего не хватает по вашему спору, скажем после первичного разбора: набор зависит от вопросов, и тащить всё подряд не нужно.
Как передать материалы и не раскрыть доступы
Здесь у .NET своя особенность: секреты лежат не в коде, а рядом с ним. В файлах настроек почти всегда обнаруживаются строка подключения к базе с паролем, ключи внешних сервисов и учётные данные служебных записей, а вместе со сборками может уехать ключ, которым они подписаны.
Сначала о самом порядке. Пересылать что-либо до разговора не нужно: сперва мы определяем по описанию спора, какие материалы вообще потребуются, и только потом договариваемся о передаче. Идёт она по защищённому каналу и ограниченному кругу лиц: архивы шифруют, пароль передают отдельно от них, состав переданного и контрольные суммы фиксируют актом приёмки. Носители с боевыми настройками по обычной почте и через мессенджеры не пересылают.
Здесь важно не путать две вещи. Файлы программы и настроек передают в том виде, в каком они работают: удалять из них пароли нельзя, потому что это изменит исследуемый объект, и другая сторона справедливо на это укажет. А объём выгрузки базы — вопрос не изменения объекта, а выбора объектов: таблицы, к спору не относящиеся, в исследование просто не включают, и это согласуют заранее. Если персональные данные клиентов всё же попадают в выгрузку, объём определяют по вопросам, а не по принципу «пусть будет», и лишнее обезличивают там, где это не мешает исследованию. Основание передачи при этом разное. По судебной экспертизе материалы идут через назначивший орган в рамках производства по делу. Вне судебного производства такого основания само по себе не возникает: письменное поручение обработки эксперту — с перечнем разрешённых действий, целями и обязанностью соблюдать конфиденциальность и требования к защите — описывает, как обрабатывать, но не заменяет основания, по которому данные вообще передаются. Годится ли для вашего случая согласие субъектов, иное предусмотренное законом основание или передача только обезличенных данных, определяют вместе с юристом до выгрузки.
После передачи меняют всё, что открывает доступ: пароль к базе, ключи сервисов, ключ подписи сборок, пароли служебных учётных записей. Это отдельная работа для вашей ИТ-службы, и её планируют заранее — смена пароля к боевой базе и ключей внешних сервисов затрагивает работающую систему. Прежние значения остаются в архиве как часть объекта, но перестают что-либо открывать. Возврат или уничтожение переданного, а также срок хранения фиксируют в договоре до начала работы — не после.
Отдельно о разглашении. Соглашение о конфиденциальности связывает эксперта, но не участников дела: материалы, поступившие в суд, доступны сторонам, и закрытое заседание этого не отменяет — оно закрывает зал от посторонних, а не дело от оппонента. Если раскрытие исходных текстов противнику для вас неприемлемо, обсудите со своим юристом другие пути: ограничить объём передаваемого вопросами, просить об исследовании на вашей территории без вывоза носителей, поставить вопрос о неразглашении перед судом до передачи. Решение принимает суд, но поставить вопрос нужно заранее.
Как идёт работа: от приёмки материалов до выводов
Порядок построен так, чтобы каждый шаг мог повторить другой специалист, а спорные места были видны читателю заключения.
- Приёмка: записывают состав материалов и контрольные суммы, описывают происхождение каждой копии.
- Опознание объектов: что перед экспертом — исходные тексты, сборки или и то и другое; сохранено ли в сборках промежуточное представление; какая версия платформы, какие пакеты, есть ли обфускация и подпись.
- Восстановление окружения и двойная контрольная сборка: сначала проверяют, повторяем ли результат вообще, и только потом сопоставляют его со спорными файлами.
- Разбор кода: по исходному тексту либо по восстановленному, с указанием, что именно исследовалось, каким средством восстановления и какой его версии.
- Проверка требований — каждое своим способом, с записью условий, при которых получен результат.
- Проверка альтернативных объяснений: настройки, данные, внешние системы, действия третьих лиц.
- Формулирование выводов в пределах поставленных вопросов и перечисление ограничений.
Ограничения по .NET называют всегда, даже когда они не помешали: обфускация, отсутствие отладочных данных, невозможность поднять внешнюю систему, отказ в доступе к площадке. Читатель заключения должен видеть не только то, что установлено, но и то, на чём это установлено.
Как формулируют вопросы по программе на C#
У вопроса по .NET есть особенность, которой нет у других языков: у эксперта может быть несколько разных объектов, и вопрос должен называть тот, о котором идёт речь. «Программа заказчика» — не объект; объект — конкретный архив с контрольной суммой либо конкретный набор сборок с указанием, откуда они взяты. Второе, что должно быть в вопросе, — проверяемый критерий: пункт технического задания, требование договора или документация.
Полезно разделять вопросы по предмету: происхождение кода, соответствие заданию, применение обфускации и причина отказа — это четыре разных исследования, и в одном вопросе их не смешивают. Стоит предусмотреть и ответ «на представленных материалах не проверяется». При судебной экспертизе окончательный круг вопросов определяет суд, а в иных предусмотренных законом процедурах — орган или лицо, назначившие экспертизу; эксперт отвечает в пределах специальных знаний и представленных материалов и при неясности вопроса сообщает об этом назначившему органу. Помощь с формулировками возможна до назначения; подробные перечни под конкретные задачи собраны на страницах экспертизы качества исходного кода и экспертизы плагиата исходного кода. По спорам о программах на C# чаще всего ставят такие вопросы:
- Является ли содержимое архива с контрольной суммой SHA-256 … исходным текстом программы, представленной сборками …; возможно ли собрать из него работоспособную программу и каких компонентов для этого недостаёт?
- Соответствует ли программа, представленная сборками …, требованиям пунктов … технического задания (приложение № … к договору от …)?
- Применялись ли к сборкам, представленным файлами …, средства, затрудняющие изучение программного кода; если да, какие сборки и какая доля содержащегося в них кода ими обработаны?
- Какие сторонние программные пакеты и каких версий использованы в программе … и какими лицензионными документами они сопровождаются?
- Какова причина отказа программы …, зафиксированного в журнале … при сценарии, описанном в …?
- Имеются ли в сборках … и … совпадения программного кода, не объясняемые использованием общих пакетов, стандартных конструкций языка и кода, создаваемого средой разработки?
Форматы работы: от разбора до рецензии
До обращения в суд и после назначения экспертизы возможности разные, и выбирать формат стоит по стадии спора.
До иска и параллельно с ним доступны внесудебное исследование по договору с вами и письменная консультация по материалам — второе дешевле и быстрее, потому что отвечает не на все вопросы, а на один: что вообще удастся установить по тому, что у вас есть. Судебную экспертизу назначает суд или орган расследования, и здесь эксперта предупреждают об уголовной ответственности за заведомо ложное заключение, а материалы поступают через назначивший орган. Если по делу уже есть чужое заключение, его разбирают рецензированием — подробнее на странице рецензии на заключение о процессе разработки. Сама рецензия заключение не отменяет: она нужна как обоснование ходатайства. По делу заявляют о вызове эксперта для пояснений, о назначении дополнительной экспертизы, если заключение неполно или неясно, либо повторной — если возникли сомнения в обоснованности заключения или в выводах экспертов есть противоречия. Заранее установленной силы у заключения нет: суд оценивает его наряду с остальными доказательствами. Отдельный формат — участие специалиста в заседании, когда нужно пояснить суду уже проведённое исследование.
Что меняется после назначения судебной экспертизы: назначенный эксперт перестаёт быть доступен стороне напрямую. Он не принимает от неё материалы, не даёт частных оценок по существу поручения, а доступ к площадке и любые новые сведения получает через суд. Если специалист раньше работал для одной из сторон, это раскрывают при рассмотрении его кандидатуры; решение о назначении и об отводе принимает назначивший орган.
Из чего складываются стоимость и срок
Расчёт складывается из трёх позиций. Первая — состояние объекта.
Разница между «есть исходные тексты», «есть только сборки» и «сборки закрыты обфускатором» — это разница в трудоёмкости в разы: в первом случае эксперт читает код, во втором сначала восстанавливает его и сверяет с поведением, в третьем ещё и выводит назначение методов по их работе. Второе обстоятельство — окружение: программа на C# почти никогда не работает в одиночку, и стенд с нужной версией платформы, копией базы и заглушками внешних сервисов готовится отдельно, иногда дольше, чем идёт сам разбор. Третье — нужен ли выезд: проверки на работающей системе заказчика согласуются по времени, порядку и участникам, и это отдельная позиция.
Остальное считают как везде: размер спорного контура, число проверяемых требований, количество поставленных вопросов, необходимость смежных специалистов. Ориентир для судебной экспертизы — от 100 000 ₽, ориентировочный срок — 10 рабочих дней; и то и другое уточняют после просмотра материалов, а если задача выходит за эти рамки, мы скажем об этом сразу, а не в процессе.
Отдельно о том, что будет, если ответом окажется «на представленных материалах не проверяется». Такой исход возможен, он тоже результат работы: эксперт указывает, какого объекта или каких условий не хватило, и этот вывод оплачивается наравне с любым другим. Поэтому объём работ определяют после первичного разбора, а по телефону только назначают встречу — он бесплатный и как раз показывает, что по имеющимся материалам установить реально, а что нет. Выезд, стенд с внешними системами и участие в заседании — отдельные позиции сметы; их называют до начала работы, а не задним числом.
Чтобы получить расчёт, архивы собирать не надо. Хватит описания спора, названия системы и перечня того, что у вас на руках: договор, задание, переписка, доступы. Позвоните по номеру 8 (800) 333-24-09 или оставьте заявку — скажем, относится ли задача к нашей компетенции, какое направление её закрывает, что стоит сохранить сегодня и каких данных не хватает для расчёта.
Проведение экспертизы по уголовному делу
Судебная экспертиза по уголовному делу производится государственными судебными экспертами и иными экспертами из числа лиц, обладающих специальными знаниями.
Негосударственными судебно-экспертными учреждениями постановление Пленума Верховного Суда Российской Федерации от 21 декабря 2010 г. № 28 «О судебной экспертизе по уголовным делам» признаёт некоммерческие организации, созданные в соответствии с Гражданским кодексом Российской Федерации и Федеральным законом «О некоммерческих организациях» и осуществляющие судебно-экспертную деятельность в соответствии с принятыми ими уставами.
По сведениям организации, проведение судебных экспертиз предусмотрено её уставом (см. действующую редакцию в разделе «Документы организации»). Это само по себе не означает автоматического поручения любой экспертизы. Возможность поручить конкретное исследование определяет назначающий орган с учётом предмета дела, квалификации эксперта, оснований для отвода и действующего перечня экспертиз, выполняемых только государственными судебно-экспертными организациями.