Pull to refresh

Comments 37

К примеру, если у вас игра, то можно добавить силы соперникам или сделать игрока более уязвимым. Также можно добавить случайные падения, к примеру в 10% случаев.

И получить тонну негативных отзывов в сети?
Это написано для примера. Каждый разработчик сам решает, что для него важнее и как бороться с пиратами.
Был я как-то на конференции GameDev разработчиков в Ciklum Minsk… Там рассказывалось про игру «Демократия», что защиты практически не было — был только одноглазый пират с повязкой на глазу, который бегал по полю и мешал игроку… Так вот, некоторым игрокам хватало ума отправлять письма с вопросами «Как убрать пирата?!». И в отзывах подобное писали. По-моему, самый правильный способ защиты. Ну это так.
А нестабильность работы можно спихнуть на кривость взлома.
А про силы соперников… Эта техника была актуально еще очень давно, я где-то читал про то, что в какой-то игре для Денди при изменении хэша логотипа враги становились в несколько раз сильнее, а некоторые так и вообще непроходимыми.
Чем плох такой достаточно оригинальный подход?
Подход отличный. Но статья о том как определить, что Android приложение было модифицировано, при этом усложнив жизнь потенциальным хакерам. Цель всей этой затеи — сделать так, чтобы купить приложение было дешевле, чем его взломать.
Имхо, конкретно такой подход плох именно негативом в отзывах. Нелегалов будет (возможно) достаточно много. А потенциальные покупатели Вашей игры могут читать такие отзывы не разбираясь, пиратская версия или нет.

Подход с пиратом — креативен и крут, плюсую=) Все-таки лучше визуально показать игроку, что что-то идет не так, попытаться давить на совесть. А нерегулярные падения считаю дурным тоном.
Дописал в статье, замечание про нерегулярные падения дельное.
А разве можно оставлять отзывы к программам, которые установлены не из маркета?
Так же было и в игре Game Dev Tycoon, когда твою игру взламывали пираты. Только разрабы в шутку сами залили «пиратскую» версию на трекеры :)
Хотелось бы дать рекомендацию типа встройте проверку на время — и требуйте обновления когда время прошло — это практически не заденет легалов. Однако как оказалось — проверка времени может считаться незаконной.
К примеру, если у вас игра, то можно добавить силы соперникам или сделать игрока более уязвимым. Также можно добавить случайные падения, к примеру в 10% случаев.

Взымать оплату по смс и выводить сообщение о том, какой пользователь плохой. =)
Логично, что делать такую проверку в Java не имеет смысла, так как аналогичный приём с использованием apktool похоронит вашу защиту за несколько минут. Поэтому данную проверку стоит перенести на нейтив уровень…
JNIEXPORT jint JNICALL Java_com_your_package_YourClass_getSomeValue(JNIEnv *env, jobject obj) {
if (isCertCorrect ) {
// всё по плану
} else {
// включаем фантазию тут

}

В этом случае поправить переход не менее элементарно, чем декомпилировать байт-код java. Вообще где-то тут лежала статья про отладку в delphi, в том числе там рассматривался и реверс. Вся описанная там теория применима и для андроида, а практика с поправкой на платформу и архитектуру процессора.

Хотелось бы больше фокусов и зрелищ ;) И не могли бы подсказать по поводу обфускаторов?
Лично мне проверка по сертификату кажется наиболее верным решением, но не должно быть единственным. Чем больше методов, тем больше головной боли у реверсера.
В этом случае поправить переход не менее элементарно, чем декомпилировать байт-код java.

Позвольте мне не согласиться. Проводить реверс инжениринг нативной библиотеки многим не под силу.
Хотелось бы больше фокусов и зрелищ ;) И не могли бы подсказать по поводу обфускаторов?

Если у вас есть что защищать и есть на это средства, рекомендую глянуть в сторону этой тулзы
Это не просто обфускатор, а целый фреймворк, позволяющий реагировать на различные действия со стороны хакера.
Просто надо не в java писать if, а из нативного кода бросать исключение. А нативный код не вызывать руками(init), а писать его в JNI_OnLoad.
Хорошо, допустим, у нас не игра, а бизнес-приложение, на SDK, не требующее NDK для своей работы. Допустим, я сделал нативную проверку сертификата. Что мешает модифицировать ту часть Java кода которая будет вызывать эту самую нативную проверку?
В таком случае, вам необходимо перенести часть своей логики на нативный уровень. Никаких проверок на Java уровне не должно быть, об этом написано в статье.
Например, софт, запускающийся в tomcat-е на разных платформах, например, под AIX-ом на HP-шном кластере. :)
Уточню — если разговор идет не про ондроед-платформу как частность, а про общий случай, когда нейтив использовать проблематично из-за разных платформ для запуска.
Это уже другая история. Тут только про Android. Логично, что нельзя считать то, чего нет.
Как вам такой вариант защиты без NDK?
— В raw или assets кладем текстовый файл, содержащий исходный код (часть функциональности) зашифрованный ключом разработчика
— Когда требуется, приложение пытается расшифровать и выполнить его, используя информацию о текущем сертификате которым подписано приложение.

Пример выполнения кода из текста здесь.

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

Взломать можно, но для этого потребуется сначала «вычислить» ключ разработчика, затем расшифровать текстовый файл и заново зашифровать уже свой ключом, которым будет подписываться взломанная версия программы.
А какой алгоритм использовать для шифровки? Если делать упор на секретность ключа, то как только его найдут — защита упала.
1. Симметричный, например DES
2. В роли ключа «сигнатура подписи + солью», генерировать его динамически из нескольких кусочков
Если это найдут и потратят время на взлом, значит, ваша программа уже достаточно популярна. Можно больше не заморачиваться на защите и просто выпустить открытую версию. Иначе затраты на защиту (и поддержание ее в актуальном состоянии) в конечном итоге могут превысить стоимость разработки.
Правильный подход
Я так делал еще в Винде на CBuilderе: Формы (*.dfm) держал в ресурсах в зашифрованном виде. Перед вызовом формы расшифровывал в памяти и грузил.
RSA ключ не желательно хранить в одной строке целиком. Будет лучше, если его собирать по кусочкам по ходу функции verifyCertificate()
Во-первых, никакой защиты в посте нет — никто менять ваш код не будет без особой необходимости, поэтому и с сертификатами никаких проблем не будет.

Во-вторых, я считаю, что тратить свое время и деньги на борьбу с ветряными мельницами не имеет смысла — приложения на варезники выкладывают не олухи, поэтому делать защиту «от дурака» бессмысленно. Писать полноценную систему защиты? Это должен быть основной ваш бизнесс, но в итоге тоже сломают (:

В-третьих, «защита» ваша настолько наивна, что вы бы постыдились такое писать — банальный grep по бинарику покажет серт. Имена ява функций в явном виде? Ох лол… Тут даже обсуждать нечего.
В-третьих, «защита» ваша настолько наивна, что вы бы постыдились такое писать — банальный grep по бинарику покажет серт. Имена ява функций в явном виде? Ох лол… Тут даже обсуждать нечего.

Почитайте коментарии, там указана ссылка на правильную тулзу. Опять же греп покажет сертификат, но всеравно надо иметь скил его заменить.
Если вы используете ява функции для получения критичных данных, то весь скилл состоит в подкладывании модифицированного ява класса из сорсов андроида. Работы на пару минут времени, увы.
Напишите статью, я думаю это будет интересно. Опять же, то что описано в статье — это базовый подход. Модифицируйте его, купите обфускатор и живите спокойно.
Опыт подсказывает, что это все бесполезно.
У меня есть противоположный опыт. Есть приложение, около миллиона активных пользователей. Защита реализована похожим методом + обфускатор нативной библиотеки. Уже больше года тишина. До этого версию с защитой от гугла взломали в день релиза.
пишите тут — ну что за детский сад?
раз минусанули — то видимо не пишите :) но мне в личку напишите плиз :) забавно, конечно…
Вместо PackageInfo info =getPackageManager().getPackageInfo(getPackageName(), 0);
возможно надо
info = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);

Без этого флага падает, лично у меня.
Sign up to leave a comment.

Articles