防止应用程序克隆者克隆Android应用程序

时间:2018-02-21 07:14:52

标签: android

创建了一个应用程序,该应用程序使用了以下代码段提取的设备的uniqueID

String deviceId = Settings.Secure.getString(getContentResolver(),
            Settings.Secure.ANDROID_ID);

当用户尝试通过app cloner克隆应用时,它会创建不同的deviceID并且不允许应用运行

有没有办法让我们的应用程序不可克隆 或

即使克隆了应用实例,任何可能的方法都有相同的deviceId吗?

有没有办法找出应用是否在克隆实例中运行?

2 个答案:

答案 0 :(得分:0)

像Cloner这样的应用程序通常会更改您的应用程序的程序包名称,以便您可以检索程序包名称并检查其是否更改。

if (!context.getPackageName().equals("your.package.name")){
    // close the app or do whatever
}

此外,它们通常会签名克隆的apk,因此签名可能与您的签名不同,您可以检查签名是否更改。我通常使用此功能:

@SuppressLint("PackageManagerGetSignatures")
public static int getCertificateValue(Context ctx){
    try {
        Signature[] signatures = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            try {
                signatures = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNING_CERTIFICATES).signingInfo.getApkContentsSigners();
            }catch (Throwable ignored){}
        }
        if (signatures == null){
            signatures = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
        }
        int value = 1;

        for (Signature signature : signatures) {
            value *= signature.hashCode();
        }
        return value;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return 0;
}

public static boolean checkCertificate(Context ctx, int trustedValue){
    return getCertificateValue(ctx) == trustedValue;
}

在释放应用程序调用{​​{1}}并写下该值以及包名称之前,请检查该值是否与您在运行时获得的值匹配。

PS:正如@ vladyslav-matviienko所说,黑客总是会找到一种方法,因此通过对硬编码的程序包名称和该值进行一些混淆来尝试使克隆更加困难。还请尝试在源代码中纠缠并散布这些逻辑。

答案 1 :(得分:0)

我在 proandroiddev 中发现了 Siddhant Panhalkar 的一个故事,经过一些细微的改动,它在 Mi 设备中完美运行我在 Mi 手机默认双应用和一些第三方中进行了检查来自 Playstore 的应用程序,它可以防止克隆(意味着克隆后无法正常工作)。

private const val APP_PACKAGE_DOT_COUNT = 3 // number of dots present in package name
private const val DUAL_APP_ID_999 = "999"
private const val DOT = '.'

fun CheckAppCloning(activity: Activity) {
    val path: String = activity.filesDir.getPath()
    if (path.contains(DUAL_APP_ID_999)) {
        killProcess(activity)
    } else {
        val count: Int = getDotCount(path)
        if (count > APP_PACKAGE_DOT_COUNT) {
            killProcess(activity)
        }
    }
}
private fun getDotCount(path: String): Int {
    var count = 0
    for (element in path) {
        if (count > APP_PACKAGE_DOT_COUNT) {
            break
        }
        if (element == DOT) {
            count++
        }
    }
    return count
}

private fun killProcess(context: Activity) {
    context.finish()
    android.os.Process.killProcess( android.os.Process.myPid())
}