Привет всем.
У нас в приложении есть несколько разделов приложения которые продаются как фичи и мы планируем сохранять информацию о том какие части приложения доступы в секции UserData. Т.е. при генерации серийника у нас будет записываться типа "Part_1, Part_2", типа можно пользовать часть 1 и 2 только.
Преположим, у нас есть 3 защищенные части.
Первый ключ разблочивает части 1 и 2, второй часть 3.
Когда пользователь использует часть 1 или 2 мы загружаем через VMProtectSetSerialNumber первый, когда ему нужна часть 3, мы вызываем VMProtectSetSerialNumber для части 3, а когда опять часть 1, то снова активируем первый ключ.
В связи с этим вопросы:
1. Правильно ли я понял идею с использованием UserData для разделения какой ключ для чего?
2. Не будет ли проблем с тем что так меняются ключи?
3. Как должна быть защищена секция, которая читает данные из UserData и принимает решения какие части приложения доступны, а какие нет?
Разные серийные номера для разных частей приложения
Re: Разные серийные номера для разных частей приложения
Я не понял зачем вам несколько серийников. Пользователь купил фичи 1 и 2 - записали в серийник "1,2". Докупил фичу "3" - выдали ему новый серийник с "1,2,3".
Re: Разные серийные номера для разных частей приложения
У разных серийников будет разное время жизни. Некоторые серийники вообще бессрочные, а некоторые для триалов с ограничением работы в пару недель.
-
- Posts: 14
- Joined: Tue Mar 17, 2020 8:47 am
Re: Разные серийные номера для разных частей приложения
как сказано выше, используй "пользовательские данные" в серийном ключе. А в свою очередь этот серийник может быть триалом, бессрочным и т.д.ivan_3 wrote:У разных серийников будет разное время жизни. Некоторые серийники вообще бессрочные, а некоторые для триалов с ограничением работы в пару недель.
Re: Разные серийные номера для разных частей приложения
Обычно в программе используется только один серийник (так гораздо удобнее для конечного пользователя), а все остальные опции зашиваются в UserData. При вашей схеме мне например совершенно непонятно как серийники вообще попадают в программу (они у вас там где-то списком лежат?). Вот у вас запускается программа. Нужно проверить доступ к пунктам меню "1", "2" и "3". Вы начинаете перебирать все доступные серийники и анализировать UserData? Прикол начнется когда у вас к существующему списку начнут добавляться серийники, имеющие "более высокий приоритет" - это когда например у вас в списке серийников есть триал на "3", а пользователь потом купил фичу "3" и этот серийник попал в общий список - как при этом будет вести себя программа, если триальный серийник попадет в "конец списка"?У разных серийников будет разное время жизни. Некоторые серийники вообще бессрочные, а некоторые для триалов с ограничением работы в пару недель.
Ну и самое плохое у данной схемы - вы не сможете "безопасно" определить (без повторного перебора всех доступных серийников) внутри выполнения фичи "3" - действительно ли она доступна пользователю или это просто хакер руками сделал доступен соответствующий пункт меню. При использовании одного серийника это можно было бы достаточно "просто" проанализировать с помощью VMProtect и накрыть этот код виртуализацией:
Code: Select all
void feature3()
{
if (VMProtectGetSerialNumberSate() != SERIAL_STATE_SUCCESS)
throw std::runtime_error("This feature isn't available");
VMProtectSerialNumberData vmp_data;
if (!VMProtectGetSerialNumberData(vmp_data, sizeof(vmp_data))
throw std::runtime_error("This feature isn't available");
if (! (vmp_data.UserData contains "feature_3"))
throw std::runtime_error("This feature isn't available");
// your code here
}
Re: Разные серийные номера для разных частей приложения
Полностью с вами согласен что очень, так сказать, неправильное решение с переключением серийников, но у нас на разные фичи у серийников разный срок действия.
Одним серийником мы ведь такое сделать не сможем?
У нас есть 3 вида фичей:
1. платные с подпиской - у них серийники будут по 3 месяца и потом продляться если пользователь дальше платит
2. триальные - ну это пару недель чтобы пользователь мог "поиграться" с фичей
3. бесплатные - у них нет ограничения по времени
Одним серийником мы ведь такое сделать не сможем?
Серийники генерит наш самописный сервер и приложение само их скачивает и активирует в автоматическом режиме. Для пользователя все махинации с серийником выглядят прозрачно. От пользователя максимум что нужно это авторизоваться и далее он просто пользуется приложением. Если нужен триал на какую-то фичу, то просто сервер сгенерит триальный серийник, а приложение его скачает и активирует в нужный момент.При вашей схеме мне например совершенно непонятно как серийники вообще попадают в программу (они у вас там где-то списком лежат?).
Да, есть список серийников и у серийнков есть флаги (которые отдает сервер) для чего подходит данный серийник. Т.е. мы можем выбрать нужный серийник без необходимости вызова для каждого VMProtectSetSerialNumber.Прикол начнется когда у вас к существующему списку начнут добавляться серийники, имеющие "более высокий приоритет" - это когда например у вас в списке серийников есть триал на "3", а пользователь потом купил фичу "3" и этот серийник попал в общий список - как при этом будет вести себя программа, если триальный серийник попадет в "конец списка"?
У нас есть 3 вида фичей:
1. платные с подпиской - у них серийники будут по 3 месяца и потом продляться если пользователь дальше платит
2. триальные - ну это пару недель чтобы пользователь мог "поиграться" с фичей
3. бесплатные - у них нет ограничения по времени
Я думал так сделать:Ну и самое плохое у данной схемы - вы не сможете "безопасно" определить (без повторного перебора всех доступных серийников) внутри выполнения фичи "3" - действительно ли она доступна пользователю или это просто хакер руками сделал доступен соответствующий пункт меню
Code: Select all
struct Serial {
bool to_feature_1;
bool to_feature_2;
std::vector<char> data;
};
std::vector<Serial> serials;
void Feature1() {
for (const auto& next : serials) {
if (next.to_feature_1) {
if (VMProtectSetSerialNumber(next.data().c_str()) == SERIAL_STATE_SUCCESS) {
VMProtectSerialNumberData vmp_data;
if (VMProtectGetSerialNumberData(vmp_data, sizeof(vmp_data))) {
if (vmp_data.UserData contains "feature_1")) {
// correct serial found
return;
}
}
}
}
}
// correct serial not found
}
-
- Posts: 14
- Joined: Tue Mar 17, 2020 8:47 am
Re: Разные серийные номера для разных частей приложения
Самый простой способ
в UserData указать Номер_Функции=Когда_закончится;
Пример: 1=2020-10-10;2=2020-08-10
либо выдавай ключа до ближайшей даты окончания любой платной функции (1, 2, 3), а там уже будет запрос к серверу за новым ключём, а сервер уже сам решит какой ключ отдавать с каким функционалом, либо триалку. Собственно зачем логику работы с разными серийниками переносить в код программы, когда за это может отвечать сервер. И выдавать суточную лицензию с разрешённым функционалом
в UserData указать Номер_Функции=Когда_закончится;
Пример: 1=2020-10-10;2=2020-08-10
либо выдавай ключа до ближайшей даты окончания любой платной функции (1, 2, 3), а там уже будет запрос к серверу за новым ключём, а сервер уже сам решит какой ключ отдавать с каким функционалом, либо триалку. Собственно зачем логику работы с разными серийниками переносить в код программы, когда за это может отвечать сервер. И выдавать суточную лицензию с разрешённым функционалом