我知道这个话题已经被打开了很多次,我学到了很多,但我偶然发现了一个我真的需要建议的问题。
我正在使用带有混淆的 LVL。我更改了默认的 LVL ALOT,以便反 LVL 不会破坏它。然而,幸运补丁一键破解!我试图查看新损坏的 APK。是的,它简单地称为我的“允许方法”。
我的问题是,是否有人可以推荐一种方法来防止 Lucky Patcher 破坏它?我知道我不能让它防弹,但我希望它至少对于一键式软件来说不是那么容易。
我知道这个话题已经被打开了很多次,我学到了很多,但我偶然发现了一个我真的需要建议的问题。
我正在使用带有混淆的 LVL。我更改了默认的 LVL ALOT,以便反 LVL 不会破坏它。然而,幸运补丁一键破解!我试图查看新损坏的 APK。是的,它简单地称为我的“允许方法”。
我的问题是,是否有人可以推荐一种方法来防止 Lucky Patcher 破坏它?我知道我不能让它防弹,但我希望它至少对于一键式软件来说不是那么容易。
检查您的证书的代码:
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,因为调试证书与发布证书不同。将您的证书输出到您的 Logcat 中:
signatures[0].toCharsString();
请记住,当您返回调试模式时,证书再次不同。为避免调试问题,请使用下一行跳过验证:
if ((context.getApplicationContext().getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE) != 0)
return;
接下来是幸运的修补程序检查器。我反编译了 Lucky Patcher 的所有版本,我发现它的创建者在所有版本之间使用了 2 个包名。所以你只需要跟踪新版本并不断添加未来的包名称。
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;
}
在当前版本 (6.4.6) 中,Lucky Patcher 生成非常短的令牌。例如,真正的购买令牌:
felihnbdiljiajicjhdpcgbb.AO-J1OyQgD6gEBTUHhduDpATg3hLkTYSWyVZUvFwe4KzT3r-O7o5kdt_PbG7sSUuoC1l6dtqsYZW0ZuoEkVUOq5TMi8LO1MvDwdx5Kr7vIHCVBDcjCl3CKP4UigtKmXotCUd6znJ0KfW
那就是幸运令牌:
kvfmqjhewuojbsfiwqngqqmc
非常直接的解决方案是检查令牌的字符串长度
@Override public void onIabPurchaseFinished(IabResult result, Purchase info) {
if (info.getToken().length < 25) {
Log.wtf("PIRATE", "PIRATE DETECTED");
return;
}
}
实现一个在某些操作下被调用的函数,该函数检查设备中是否安装了 LuckyPatcher 包。
如果找到,则退出您的应用程序。不管有没有付费,都不允许使用,差评胜过千千万万的盗版。或者,您可以显示一条消息,指出已找到 LuckyPatcher 并且该应用程序无法运行。
如果您的应用程序被 LuckyPatcher 修补,这意味着它已经入侵了您的 LVL 实现,那么由于 LuckyPatcher 包检测,至少您的应用程序不会执行。
一种方法是检查是否安装了幸运补丁程序,如果是,则向用户显示一条消息,然后终止您的进程。如果用户拥有它,则意味着他正试图破解您的软件或其他开发人员的软件。所以最好不要允许在安装了它的手机中使用你的应用程序。打击盗版。
每当 Lucky Patcher 创建一个修改后的 APK 文件时,它总是以不同的包名称结束,因为您不能以相同的包名称运行两个应用程序。
这是一个简单的解决方案,用于检查您的代码是否在错误的包名称下运行:
PackageManager pm = getPackageManager();
try {
PackageInfo packageInfo = pm.getPackageInfo("YOUR_PACKAGE_NAME",PackageManager.GET_ACTIVITIES);
} catch (PackageManager.NameNotFoundException e){
finish();
//If you get here, your code is running under a different package name... Kill the process!
}
我只是调用finish();
我的应用程序,但无法破坏它,但最好android.os.Process.killProcess(android.os.Process.myPid());
按照@PerracoLabs 的建议使用。