Цель состоит в том, чтобы найти способ защитить код QML от плагиата. Это проблема, поскольку способ, которым QML был спроектирован и реализован, кажется необъяснимым образом незащищенным в этом отношении. Единственными QML-типами, которые в некоторой степени защищены, являются те, которые полностью реализованы в C ++.
В целом, похоже, что Qt сознательно экономит на защите кода QML, одной из очевидных причин-кандидатов будет принуждение людей к покупке безумно выразительной коммерческой лицензии, в которой есть компилятор QML.
Поэтому в отсутствие какого-либо стандартного метода защиты источников QML единственное решение, которое мне приходит в голову, — это контроль над разрешением типов QML. Существует несколько способов регистрации типов в QML:
Тем не менее, мне нужно вручную разрешить типы QML, так же, как вы можете создавать собственные QQuickImageProvider
который вводит строку URL-адреса и выводит изображение, мне нужен механизм QML для запроса строки с типом в моем поставщике пользовательских компонентов, который выводит готовый к созданию объектный компонент.
Это было бы легко, если бы использовался какой-либо пользовательский механизм создания экземпляров, но мне нужно, чтобы эти типы использовались в обычных источниках QML. В идеале это должен быть первый механизм, используемый для определения типа, прежде чем искать доступные пути импорта или даже внутренние зарегистрированные типы.
В качестве альтернативы было бы так же полезно, если бы существовал способ полностью определить модуль QML в C ++, без каких-либо внешних файлов QML, без qmldir
файл и тд.
В крайнем случае, и в идеале я бы не стал регистрировать типы QML (не C ++) во время выполнения, это также может быть полезно, но я бы предпочел иметь полный контроль над процессом разрешения.
Плагин QML не работает, так как он регистрирует типы C ++, и я хочу зарегистрировать типы QML, то есть QQmlComponent
создаются из строковых источников и ссылаются друг на друга.
Qt Quick Compiler — это надстройка для приложений Qt Quick, которая позволяет вам скомпилировать исходный код QML в окончательный двоичный файл. Как написано в описании, это поможет предотвратить плагиат, а также увеличит время запуска вашего приложения и предоставит другие преимущества.
Раньше это был закрытый исходный код, но вы можете получить альтернативную версию с открытым исходным кодом на https://github.com/qmlc/qmlc или вы можете дождитесь Qt 5.8 где он станет с открытым исходным кодом.
Это как можно ближе к защите исходного кода QML, даже если он еще не полностью оптимизирован
Начиная с Qt 5.11, решение на месте и быстро улучшается.
Вариант А) использовать компилятор qtquick
Вариант Б) использовать зашифрованные ресурсы:
скомпилировать ресурсы в отдельный файл:
rcc -binary your_resource.qrc -o extresources.rcc
зашифровать extresources.rcc к extresources.rcc.cr (например, с помощью gnupg)
создать новый файл ресурсов APP.rcc, только с файлом extresources.rcc.cr
при запуске загрузите «: /extresources.rcc.cr» и расшифруйте их в буфер (вам нужна криптографическая библиотека, такая как Libgcrypt … скрыть закрытый ключ для декомпиляторов, отладчиков и т. д.)
Q_CLEANUP_RESOURCE (АРР); (необязательно, очистите APP.rcc для экономии памяти)
Resource :: registerResource ((unsigned char *) myBuffer.constData ()))
// теперь у вас есть доступные расшифрованные ресурсы … например
engine.load (QUrl ( «QRC: /main.qml»))
Реальная реализация не тривиальна, но работает очень хорошо …
После недолгих поисков я нашел два направления, которые, возможно, стоит продолжить:
используя обычай QQmlAbstractUrlInterceptor
для механизма QML, который разрешает типы QML и возвращает QUrl
в случае «защищенных» типов перехватчик может добавить собственную схему. Использование кастома QNetworkAccessManager
чтобы перехватить этот URL, вызывает реализацию по умолчанию для незащищенных типов и для защищенных типов, расшифровывает данные и возвращает их в QNetworkReply
,
другое, более простое, но менее гибкое решение включает в себя только вторую часть предыдущего решения, и qmlRegisterType(const QUrl &url, ...)
функция для представления в качестве типов QML, избегая использования перехватчика.
Я буду публиковать обновления, как я исследую эти два. Обратите внимание, что это также не на 100% безопасно, так как сетевой ответ с самим дешифрованным кодом, по крайней мере, временно останется в ОЗУ, поэтому при достаточной компетентности все же можно будет получить доступ к коду, однако это не так тривиально, как принятие это прямо из двоичного файла приложения. Возможное направление, чтобы пойти еще дальше, было бы прибегнуть к обычаю QNetworkReply
который не содержит расшифрованных данных, но перегружает QIODevice
часть, чтобы действовать как средство доступа к зашифрованным данным, которые расшифровывают их по пути во время чтения.