В данной статье мы кратко расскажем о том, как можно защитить свою программу от взлома, не интегрируя стандартное решение от Google и предоставим пример рабочего кода. Интересно? Просим под кат!
В чём слабость Google Application Licensing?
Дело в том, что данный механизм хорошо известен разработчикам и его взлом не составляет большого труда. Всё что для этого нужно — скачать apktool, найти класс LicenseChecker и слегка подправить метод checkAccess.
Как реализовать свою собственную защиту?
Очевидно, что любую защиту можно сломать. Данный метод не является серебрянной пулей, но он имеет право на жизнь. Для проверки уникальности приложения есть смысл проверить сертификат, которым это приложение было подписано. Информацию о сертификате можно прочитать из PackageInfo:
PackageInfo info =getPackageManager().getPackageInfo(getPackageName(), 0); Signature[] signatures = info.signatures;
Нулевой элемент массива будет содержать необходимую информацию о ключе, которым было подписано приложение. Сохраните сам ключ, он вам понадобится совсем скоро.
Эти Простые Способы ПОМОГУТ Защитить твой Телефон от Взлома и Потери Всех Личных Данных !!!
Логично, что делать такую проверку в Java не имеет смысла, так как аналогичный приём с использованием apktool похоронит вашу защиту за несколько минут. Поэтому данную проверку стоит перенести на нейтив уровень.
const char* rsa = «PUT_YOUR_RSA_KEY_HERE»; jint verifyCertificate(JNIEnv *env, jobject obj, jobject cnt) < jclass cls = env->GetObjectClass(cnt); jmethodID mid = env->GetMethodID(cls, «getPackageManager», «()Landroid/content/pm/PackageManager;»); jmethodID pnid = env->GetMethodID(cls, «getPackageName», «()Ljava/lang/String;»); if (mid == 0 || pnid == 0) < return ERROR; >jobject pacMan_o = env->CallObjectMethod(cnt, mid); jclass pacMan = env->GetObjectClass(pacMan_o); jstring packName = (jstring) env->CallObjectMethod(cnt, pnid); /*flags = PackageManager.GET_SIGNATURES*/ int flags = 0x40; mid = env->GetMethodID(pacMan, «getPackageInfo», «(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;»); if (mid == 0) < return ERROR; >jobject pack_inf_o = (jobject) env->CallObjectMethod(pacMan_o, mid, packName, flags); jclass packinf = env->GetObjectClass(pack_inf_o); jfieldID fid; fid = env->GetFieldID(packinf, «signatures», «[Landroid/content/pm/Signature;»); jobjectArray signatures = (jobjectArray) env->GetObjectField(pack_inf_o, fid); jobject signature0 = env->GetObjectArrayElement(signatures, 0); mid = env->GetMethodID(env->GetObjectClass(signature0), «toByteArray», «()[B»); jbyteArray cert = (jbyteArray) env->CallObjectMethod(signature0, mid); if (cert == 0) < return ERROR; >jclass BAIS = env->FindClass(«java/io/ByteArrayInputStream»); if (BAIS == 0) < return ERROR; >mid = env->GetMethodID(BAIS, «», «([B)V»); if (mid == 0) < return ERROR; >jobject input = env->NewObject(BAIS, mid, cert); jclass CF = env->FindClass(«java/security/cert/CertificateFactory»); mid = env->GetStaticMethodID(CF, «getInstance», «(Ljava/lang/String;)Ljava/security/cert/CertificateFactory;»); jstring X509 = env->NewStringUTF(«X509″); jobject cf = env->CallStaticObjectMethod(CF, mid, X509); if (cf == 0) < return ERROR; >//»java/security/cert/X509Certificate» mid = env->GetMethodID(CF, «generateCertificate», «(Ljava/io/InputStream;)Ljava/security/cert/Certificate;»); if (mid == 0) < return ERROR; >jobject c = env->CallObjectMethod(cf, mid, input); if (c == 0) < return ERROR; >jclass X509Cert = env->FindClass(«java/security/cert/X509Certificate»); mid = env->GetMethodID(X509Cert, «getPublicKey», «()Ljava/security/PublicKey;»); jobject pk = env->CallObjectMethod(c, mid); if (pk == 0) < return ERROR; >mid = env->GetMethodID(env->GetObjectClass(pk), «toString», «()Ljava/lang/String;»); if (mid == 0) < return ERROR; >jstring all = (jstring) env->CallObjectMethod(pk, mid); const char * all_char = env->GetStringUTFChars(all, NULL); char * out = NULL; if (all_char != NULL) < char * startString = strstr(all_char, «modulus:»); char * end = strstr(all_char, «public exponent»); bool isJB = false; if (startString == NULL) < //4.1.x startString = strstr(all_char, «modulus=»); end = strstr(all_char, «,publicExponent»); isJB = true; >if (startString != NULL end != NULL) < int len; if (isJB) < startString += strlen(«modulus=»); len = end — startString; >else < startString += strlen(«modulus:»); len = end — startString — 5; /* -5 for new lines*/ >out = new char[len + 2]; strncpy(out, startString, len); out[len] = ‘