Ответ 1
Код для проверки сертификата
public void checkSignature(final Context context)
{
try
{
Signature[] signatures = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
if (signatures[0].toCharsString() != <YOUR CERTIFICATE STRING GOES HERE>)
{
// Kill the process without warning. If someone changed the certificate
// is better not to give a hint about why the app stopped working
android.os.Process.killProcess(android.os.Process.myPid());
}
}
catch (NameNotFoundException ex)
{
// Must never fail, so if it does, means someone played with the apk, so kill the process
android.os.Process.killProcess(android.os.Process.myPid());
}
}
И как найти, какой именно ваш сертификат, тоже прост. Вы должны создать APK в режиме деблокирования, поскольку сертификат отладки всегда отличается от выпуска. Выведите свою строку сертификата во временное текстовое окно, чтобы скопировать ее, или в текстовый файл со следующим вызовом. ВАЖНО: НЕ ВЫПОЛНИТЕ его логарифм, поскольку строка слишком велика, и лог-код не отобразит все это и вырезает последний char символы:
signatures[0].toCharsString();
example: YourTextView.setText(signatures[0].toCharsString());
Теперь помните, что когда вы вернетесь в режим отладки, сертификат снова будет другим, и иногда может быть различным в каждой сборке, поэтому вы получите отладочный ад. Тогда лучше использовать следующую строку, чтобы упростить ее разработку и разместить ее прямо перед вызовом тестирования сертификата:
if ((context.getApplicationContext().getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0)
{
return;
}
Поэтому не вызывайте этот код сертификации, если в режиме отладки
И теперь счастливый патч-чекер
Этот код проверяет его существование. Я декомпилировал все версии Lucky Patcher, и я узнал, что его создатель использовал 2 имени пакета между всеми realeases. Таким образом, вам нужно только отслеживать новые версии и продолжать добавлять будущие имена пакетов патчи к функциям проверки.
Также рекомендуется шифровать строки имен пакетов вместо того, чтобы просто их кодировать, как в примере, поэтому удачный патчер не выходит с новой версией, которая просто заменяет строки, исправляющие их. Позволяет затруднить использование крекеров.
private boolean checkLuckyPatcher()
{
if (packageExists("com.dimonvideo.luckypatcher"))
{
return true;
}
if (packageExists("com.chelpus.lackypatch"))
{
return true;
}
if (packageExists("com.android.vending.billing.InAppBillingService.LACK"))
{
return true;
}
return false;
}
private boolean packageExists(final String packageName)
{
try
{
ApplicationInfo info = this.getPackageManager().getApplicationInfo(packageName, 0);
if (info == null)
{
// No need really to test for null, if the package does not
// exist it will really rise an exception. but in case Google
// changes the API in the future lets be safe and test it
return false;
}
return true;
}
catch (Exception ex)
{
// If we get here only means the Package does not exist
}
return false;
}