2016-01-15 7 views
5

Цель состоит в том, чтобы придумать способ защитить ваш QML-код от плагиата. Это проблема, поскольку путь QML был разработан и реализован, кажется необъяснимо незащищенным в этом отношении. Единственные типы QML, которые несколько защищены, - это те, которые полностью реализованы на C++.Защита исходного кода QML от плагиата

  • файлов ресурсов Qt не поддерживают какую-то степень защиты
  • даже если сжать файл ресурсов, извлечение данных из него еще довольно тривиальна для любого с умеренным опытом
  • QML файлы, хранящиеся на файл система практически существует для принятия
  • То же самое относится к любым удаленным файлам QML, помимо добавления зависимости от интернет-соединения, легко обнюхать доступ к сети и получать файлы QML через свои URL-адреса
  • QML doesn ' t предоставляют, казалось бы, любые публичные API, чтобы позволить пользователям достаточно контроля над разрешением типа QML, чтобы защитить свой код

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

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

  • регистра в исполняемом файле приложение
  • регистра в плагине
  • регистра через модуль QML

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

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

В качестве альтернативы, было бы также полезно, если бы был способ полностью определить QML-модуль полностью на C++ без каких-либо внешних файлов QML без файла qmldir и так далее.

В крайнем случае, и, в идеале, я не согласен с регистрацией типов QML (не C++), это также может быть полезно, но я бы предпочел иметь полный контроль над процессом разрешения ,

Плагин QML не выполняет трюк, так как он регистрирует типы C++, и я хочу зарегистрировать типы QML, то есть QQmlComponent s, созданные из источников строк и ссылающихся друг на друга.

+0

Итак, вы хотите загрузить компонент из символьной строки в памяти, содержащей некоторый исходный код QML? Это функция 'QQmlComponent :: setData'. – Velkan

+0

@Velkan - далеко от него. Я хочу зарегистрировать компоненты как типы QML для использования в декларативном QML-коде. Или более точно, я хочу иметь 'SomeType {...}' в QML и иметь ручное управление, чтобы связать «SomeType» с компонентом QML. – dtech

+0

Возможно, 'Loader {sourceComponent: someType1; ... (свойства элемента)} 'и измените' sourceComponent' на то, чтобы указывать на правый компонент. Изменение значения 'SomeType {}' не выглядит многообещающим, потому что идентификатор типа определяется во время компиляции QML (http://www.kdab.com/qml-engine-internals-part-1-qml-file -loading /). – Velkan

ответ

0

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

  • с использованием пользовательских QQmlAbstractUrlInterceptor для двигателя QML, который разрешает типы QML и returs в QUrl, в случае «защищенный» типы, перехватчик может предварять специальную схему. Использование пользовательского QNetworkAccessManager для перехвата этого URL-адреса, вызывает реализацию по умолчанию для незащищенных типов и для защищенных типов расшифровывает данные и возвращает их в QNetworkReply.

  • другое, более простое, но менее гибкое решение включает только вторую часть предыдущего решения и функцию qmlRegisterType(const QUrl &url, ...), чтобы выставлять как типы QML, избегая использования перехватчика.

Опубликуйте обновления, когда я исследую эти два вопроса. Обратите внимание, что это не на 100% безопасно, так как ответ сети с расшифрованным кодом сам по крайней мере временно останется в ОЗУ, поэтому, учитывая достаточную компетентность, все равно можно будет получить код, однако это не так тривиально, как принятие он непосредственно из двоичного приложения. Возможным направлением для дальнейшего продвижения было бы обратиться к производителю QNetworkReply, который не содержит дешифрованные данные, но перегружает часть QIODevice, чтобы действовать в качестве доступа к зашифрованным данным, которые расшифровывают его по пути во время чтения.

1

(идеальные) Решение: Прекомпиляция это

в Qt Quick Compiler является разработка дополнения для Qt Quick приложений, который позволяет компилировать исходный код QML в конечный двоичный файл. As it's description says, это поможет предотвратить плагиат, а также увеличит время запуска вашего приложения и предоставит другие преимущества.

Это был закрытый источник, но вы можете получить альтернативную версию с открытым исходным кодом на https://github.com/qmlc/qmlc или можете wait until Qt 5.8 where it will become opensource.

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

+0

Слишком рудиментарный на этом этапе, ошибки и ограничения. Надеюсь, к тому времени, когда 5,8 закончится, это улучшится. – dtech

+1

Да, но решение официально на месте. И, будучи open source, он только улучшится. Кроме того, я предоставил ссылку на другой бесплатный компилятор. Это лучший вариант AFAIK. –

+0

Надеюсь, к тому моменту, когда компилятор будет полностью интегрирован в Qt, он устранит некоторые из ограничений, в частности невозможность загрузить файлы QML из сети и смешивать их с компилируемыми файлами QML, что делает его бесполезным для меня. – dtech

0

Вариант А) использовать QtQuick компилятор

Варианта B) использовать зашифрованные ресурсы:

  1. компиляция ресурсы в отделенный файл: RCC -binary your_resource.qrc -o extresources.rcc

  2. шифровать extresources.rcc к extresources.rcc.cr (например, с помощью GnuPG)

  3. создать новый файл ресурсов APP.rcc, только с extresources.rcc.cr файла

  4. при запуске, нагрузки ": /extresources.rcc.cr" и расшифровать их в буфер (вам нужна криптографическая библиотека, такая как Libgcrypt ... скрыть секретный ключ для декомпиляторов и отладчиков и т. д.)

  5. Q_CLEANUP_RESOURCE (APP); (опционально, очистить APP.rcc для сохранения памяти)

  6. Ресурс :: registerResource ((unsigned char *) myBuffer.constData()))

// теперь у вас есть доступные ресурсы расшифрованные ... например

engine.load (QUrl ("QRC: /main.qml"))

Реальная реализация не является тривиальной, но работает очень хорошо ...