javiersantos / PiracyChecker

An Android library that prevents your app from being pirated / cracked using Google Play Licensing (LVL), APK signature protection and more. API 14+ required.
Apache License 2.0
1.55k stars 174 forks source link

Getting false positives on the Google Play license check #25

Open rosenpin opened 7 years ago

rosenpin commented 7 years ago

Hi, I just found out about this library a few days ago and it looked very promising, I really appreciate your effort to make other developers lives easier.

I tried implementing this library in a beta version of my app which I later released to the Play Store for beta testers, and it seems like I got several false positives from the library.

I made it so I get Firebase reports for when PiracyCheckerCallback returns dontAllow. I also had Firebase log the installer app package name when sending the report. After less than 30 minutes of the app being available to beta testers on Google Play I got already 2 reports for the following devices:

Manufacturer: Samsung Model: SM-J111M Board: Sc9830i Android API: 22 Android OS: 5.1.1 Brand: Samsung RAM: 919.67MB Orientation: Portrait

Installed from: com.android.vending Reason: This user is not using a licensed application from Google Play.

Manufacturer: Htc Model: Nexus 9 Board: Flounder Android API: 21 Android OS: 5.0.2 Brand: Google RAM: 1.79GB Orientation: Portrait

Probably an emulator for automatic crash reports (pre launch reports) Reason: This user is not using a licensed application from Google Play.

The second one is a Google emulator so it might be a different story, but I'm almost certain that the first report is genuine, and is from a valid user.

This is the code I used:

String[] lines = new String(arr).split(System.getProperty("line.separator")); //Getting the first line of the file that contains the Google Play Licensing and Signing certificate codes 
            new PiracyChecker(context)
                    .enableGooglePlayLicensing(lines[0])
                    .enableSigningCertificate(lines[1])
                    .enableDebugCheck()
                    //.enableUnauthorizedAppsCheck()
                    .callback(new PiracyCheckerCallback() {
                        @Override
                        public void allow() {

                        }

                        @Override
                        public void dontAllow(@NonNull PiracyCheckerError piracyCheckerError, @Nullable PirateApp pirateApp) {
                            if (prefs.enabled)
                                prefs.setBool(Prefs.KEYS.ENABLED.toString(), Constants.disabled);
                            FirebaseCrash.log(piracyCheckerError.toString());
                            FirebaseCrash.log(context.getPackageManager().getInstallerPackageName(context.getPackageName()));
                            nullObject.toString(); // make the app crash
                        }
                    })
                    .display(Display.ACTIVITY)
                    .start();

I saw in the README that you recommend not running the PiracyCheck in multiple instances

When using Google Play Licensing your should call .destroy() in the onDestroy() method of your Activity to avoid multiple instances of the service running. Have a look to the Wiki for a sample Activity with .destroy().

But in the current version of the app it might still happen, because I also check for license verification error from a service that may run simultaneously with the activity. Could that really be the source of the issue?

As I mentioned above, this seems to work for the most part, with the exception of this one user, which I doubt had the time to update and crack the app in less than 30 minutes, especially with the app being installed from Google Play, as the Firebase report says.

Looking forward to your response, I will try to analyse it further and any other information I find

Edit: I updated the app again, now I should get the license key used in the verification process through firebase, I just got another report:

Manufacturer: Meizu Model: PRO 5 Board: Pro5 Android API: 22 Android OS: 5.1 Brand: Meizu RAM: 3.63GB Orientation: Portrait App used to install com.android.vending Error: This user is not using a licensed application from Google Play.

I compared the license key I received from the report with my license key from the Play Store and they match

Edit2: OK, maybe I figured it out, previously I wasn't implementing the onError method, after implementing it I got many reports about it being triggered, is it possible that by default when an error occurs with the license verification, the dontAllow method is being called?

Any who this is the error message that I get:

OnErrorNot market managed error.

Will update as I get more information

Edit3: Never mind, seems like it didn't solve the issue, for some reason Google pre launch report Nexus 9 manages to reproduce this issue every time

Manufacturer: Htc Model: Nexus 9 Board: Flounder Android API: 21 Android OS: 5.0.2 Brand: Google RAM: 1.79GB Orientation: Portrait

Edit3: Ended up commenting out the .enableGooglePlayLicensing(lines[0]) line, for now I will rely on the app certificate verification

BigEnergys commented 7 years ago

plus

Vel-San commented 6 years ago

Plus.

zacharee commented 6 years ago

This seems to happen when the device has just booted. I have the checker running in my Application class, which runs as soon as any of my components are activated, and it looks like PiracyChecker checks before Google Play Services has actually started.

dipendrapkrl commented 6 years ago

@rosenpin do not depend on app certificate verification. Apps like App Cloner can easily make clones.