From 373bda9f0219ecd3f1069bf5fe0637c61dc87787 Mon Sep 17 00:00:00 2001 From: YuutaW <17158086+Trumeet@users.noreply.github.com> Date: Thu, 28 Feb 2019 20:32:26 -0800 Subject: feat(app): hide and obfuscate license checking codes as much as we can Signed-off-by: YuutaW <17158086+Trumeet@users.noreply.github.com> --- app/src/main/java/moe/yuuta/ext/ConnCallback.java | 9 ++ .../main/java/moe/yuuta/ext/IPCResultListener.java | 15 +++ .../main/java/moe/yuuta/ext/IResultListener.java | 102 +++++++++++++++++++++ app/src/main/java/moe/yuuta/ext/IService.java | 102 +++++++++++++++++++++ .../main/java/moe/yuuta/ext/LicServiceConn.java | 23 +++++ .../main/java/moe/yuuta/ext/ResultCallback.java | 6 ++ app/src/main/java/moe/yuuta/ext/package-info.java | 4 + .../java/moe/yuuta/gplicense/LicenseChecker.java | 38 +++++--- .../java/moe/yuuta/gplicense/LicenseValidator.java | 2 +- .../moe/yuuta/gplicense/ServerManagedPolicy.java | 2 +- .../gplicense/ipc/ILicenseResultListener.java | 101 -------------------- .../moe/yuuta/gplicense/ipc/ILicensingService.java | 101 -------------------- .../main/java/moe/yuuta/workmode/MainActivity.kt | 4 +- app/src/main/java/moe/yuuta/workmode/gpl/GPL.kt | 47 ++++++++++ .../main/java/moe/yuuta/workmode/gpl/GPLicenser.kt | 45 --------- 15 files changed, 335 insertions(+), 266 deletions(-) create mode 100644 app/src/main/java/moe/yuuta/ext/ConnCallback.java create mode 100644 app/src/main/java/moe/yuuta/ext/IPCResultListener.java create mode 100644 app/src/main/java/moe/yuuta/ext/IResultListener.java create mode 100644 app/src/main/java/moe/yuuta/ext/IService.java create mode 100644 app/src/main/java/moe/yuuta/ext/LicServiceConn.java create mode 100644 app/src/main/java/moe/yuuta/ext/ResultCallback.java create mode 100644 app/src/main/java/moe/yuuta/ext/package-info.java delete mode 100644 app/src/main/java/moe/yuuta/gplicense/ipc/ILicenseResultListener.java delete mode 100644 app/src/main/java/moe/yuuta/gplicense/ipc/ILicensingService.java create mode 100644 app/src/main/java/moe/yuuta/workmode/gpl/GPL.kt delete mode 100644 app/src/main/java/moe/yuuta/workmode/gpl/GPLicenser.kt (limited to 'app/src') diff --git a/app/src/main/java/moe/yuuta/ext/ConnCallback.java b/app/src/main/java/moe/yuuta/ext/ConnCallback.java new file mode 100644 index 0000000..13af66d --- /dev/null +++ b/app/src/main/java/moe/yuuta/ext/ConnCallback.java @@ -0,0 +1,9 @@ +package moe.yuuta.ext; + +import android.content.ComponentName; +import android.os.IBinder; + +public interface ConnCallback { + void onServiceConnected(ComponentName name, IBinder service); + void onServiceDisconnected(ComponentName name); +} diff --git a/app/src/main/java/moe/yuuta/ext/IPCResultListener.java b/app/src/main/java/moe/yuuta/ext/IPCResultListener.java new file mode 100644 index 0000000..bf0045b --- /dev/null +++ b/app/src/main/java/moe/yuuta/ext/IPCResultListener.java @@ -0,0 +1,15 @@ +package moe.yuuta.ext; + +public class IPCResultListener extends IResultListener.Stub { + private final ResultCallback mCallback; + + public IPCResultListener(ResultCallback mCallback) { + this.mCallback = mCallback; + } + + @Override + public void exec(final int responseCode, final String signedData, + final String signature) { + mCallback.verifyLicense(responseCode, signedData, signature); + } +} diff --git a/app/src/main/java/moe/yuuta/ext/IResultListener.java b/app/src/main/java/moe/yuuta/ext/IResultListener.java new file mode 100644 index 0000000..706b34a --- /dev/null +++ b/app/src/main/java/moe/yuuta/ext/IResultListener.java @@ -0,0 +1,102 @@ +package moe.yuuta.ext; + +import android.os.Binder; +import android.os.IBinder; +import android.os.IInterface; +import android.os.Parcel; +import android.os.RemoteException; + +import androidx.annotation.NonNull; + +import moe.yuuta.gplicense.util.Base64; +import moe.yuuta.gplicense.util.Base64DecoderException; + +public interface IResultListener extends IInterface { + abstract class Stub extends Binder implements IResultListener { + private static final String DESCRIPTOR; + + static { + try { + // Base64 encoded - + // com.android.vending.licensing.ILicenseResultListener + DESCRIPTOR = new String(Base64.decode( + "Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2VSZXN1bHRMaXN0ZW5lcg==")); + } catch (Base64DecoderException e) { + throw new RuntimeException(e); + } + } + + protected Stub() { + this.attachInterface(this, DESCRIPTOR); + } + + static IResultListener asInterface(IBinder obj) { + if ((obj == null)) { + return null; + } + IInterface iin = obj.queryLocalInterface(DESCRIPTOR); + if (iin instanceof IResultListener) { + return (IResultListener) iin; + } + return new Stub.Proxy(obj); + } + + @Override + public IBinder asBinder() { + return this; + } + + @Override + public boolean onTransact(int code, @NonNull Parcel data, Parcel reply, int flags) throws RemoteException { + switch (code) { + case INTERFACE_TRANSACTION: { + reply.writeString(DESCRIPTOR); + return true; + } + case TRANSACTION: { + data.enforceInterface(DESCRIPTOR); + int responseCode = data.readInt(); + String signedData = data.readString(); + String signature = data.readString(); + this.exec(responseCode, signedData, signature); + return true; + } + default: { + return super.onTransact(code, data, reply, flags); + } + } + } + + private static class Proxy implements IResultListener { + private IBinder mRemote; + + Proxy(IBinder remote) { + mRemote = remote; + } + + @Override + public IBinder asBinder() { + return mRemote; + } + + @Override + public void exec(int responseCode, String signedData, String signature) throws RemoteException { + Parcel args = Parcel.obtain(); + try { + args.writeInterfaceToken(DESCRIPTOR); + args.writeInt(responseCode); + args.writeString(signedData); + args.writeString(signature); + mRemote.transact(TRANSACTION, args, null, IBinder.FLAG_ONEWAY); + } finally { + args.recycle(); + } + } + } + + static final int TRANSACTION = IBinder.FIRST_CALL_TRANSACTION; + } + + // verifyLicense + void exec(int responseCode, String signedData, String signature) throws RemoteException; +} \ No newline at end of file diff --git a/app/src/main/java/moe/yuuta/ext/IService.java b/app/src/main/java/moe/yuuta/ext/IService.java new file mode 100644 index 0000000..ea0b136 --- /dev/null +++ b/app/src/main/java/moe/yuuta/ext/IService.java @@ -0,0 +1,102 @@ +package moe.yuuta.ext; + +import android.os.Binder; +import android.os.IBinder; +import android.os.IInterface; +import android.os.Parcel; +import android.os.RemoteException; + +import androidx.annotation.NonNull; + +import moe.yuuta.gplicense.util.Base64; +import moe.yuuta.gplicense.util.Base64DecoderException; + +public interface IService extends IInterface { + abstract class Stub extends Binder implements IService { + private static final String DESCRIPTOR; + + static { + try { + // Base64 encoded - + // com.android.vending.licensing.ILicensingService + DESCRIPTOR = new String(Base64.decode( + "Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U=")); + } catch (Base64DecoderException e) { + throw new RuntimeException(e); + } + } + + public Stub() { + this.attachInterface(this, DESCRIPTOR); + } + + public static IService asInterface(IBinder obj) { + if ((obj == null)) { + return null; + } + IInterface iin = obj.queryLocalInterface(DESCRIPTOR); + if (iin instanceof IService) { + return (IService) iin; + } + return new IService.Stub.Proxy(obj); + } + + @Override + public IBinder asBinder() { + return this; + } + + @Override + public boolean onTransact(int code, @NonNull Parcel data, Parcel reply, int flags) throws RemoteException { + switch (code) { + case INTERFACE_TRANSACTION: { + reply.writeString(DESCRIPTOR); + return true; + } + case TRANSACTION_checkLicense: { + data.enforceInterface(DESCRIPTOR); + long nonce = data.readLong(); + String packageName = data.readString(); + IResultListener listener = IResultListener.Stub.asInterface(data.readStrongBinder()); + this.exec(nonce, packageName, listener); + return true; + } + default: { + return super.onTransact(code, data, reply, flags); + } + } + } + + private static class Proxy implements IService { + private IBinder mRemote; + + Proxy(IBinder remote) { + mRemote = remote; + } + + @Override + public IBinder asBinder() { + return mRemote; + } + + @Override + public void exec(long nonce, String packageName, IResultListener listener) throws RemoteException { + Parcel args = Parcel.obtain(); + try { + args.writeInterfaceToken(DESCRIPTOR); + args.writeLong(nonce); + args.writeString(packageName); + args.writeStrongBinder(listener != null ? listener.asBinder() : null); + mRemote.transact(TRANSACTION_checkLicense, args, null, IBinder.FLAG_ONEWAY); + } finally { + args.recycle(); + } + } + } + + static final int TRANSACTION_checkLicense = IBinder.FIRST_CALL_TRANSACTION; + } + + // checkLicense + void exec(long nonce, String packageName, IResultListener listener) throws RemoteException; +} \ No newline at end of file diff --git a/app/src/main/java/moe/yuuta/ext/LicServiceConn.java b/app/src/main/java/moe/yuuta/ext/LicServiceConn.java new file mode 100644 index 0000000..f0ad766 --- /dev/null +++ b/app/src/main/java/moe/yuuta/ext/LicServiceConn.java @@ -0,0 +1,23 @@ +package moe.yuuta.ext; + +import android.content.ComponentName; +import android.content.ServiceConnection; +import android.os.IBinder; + +public class LicServiceConn implements ServiceConnection { + private final ConnCallback mCallback; + + public LicServiceConn(ConnCallback mCallback) { + this.mCallback = mCallback; + } + + @Override + public synchronized void onServiceConnected(ComponentName name, IBinder service) { + mCallback.onServiceConnected(name, service); + } + + @Override + public synchronized void onServiceDisconnected(ComponentName name) { + mCallback.onServiceDisconnected(name); + } +} diff --git a/app/src/main/java/moe/yuuta/ext/ResultCallback.java b/app/src/main/java/moe/yuuta/ext/ResultCallback.java new file mode 100644 index 0000000..4feafba --- /dev/null +++ b/app/src/main/java/moe/yuuta/ext/ResultCallback.java @@ -0,0 +1,6 @@ +package moe.yuuta.ext; + +public interface ResultCallback { + void verifyLicense(final int responseCode, final String signedData, + final String signature); +} diff --git a/app/src/main/java/moe/yuuta/ext/package-info.java b/app/src/main/java/moe/yuuta/ext/package-info.java new file mode 100644 index 0000000..128e042 --- /dev/null +++ b/app/src/main/java/moe/yuuta/ext/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes which cannot be processed by ProGuard are moved to here to keep LicenseChecker processed. + */ +package moe.yuuta.ext; \ No newline at end of file diff --git a/app/src/main/java/moe/yuuta/gplicense/LicenseChecker.java b/app/src/main/java/moe/yuuta/gplicense/LicenseChecker.java index 92986b8..7d4cfa8 100644 --- a/app/src/main/java/moe/yuuta/gplicense/LicenseChecker.java +++ b/app/src/main/java/moe/yuuta/gplicense/LicenseChecker.java @@ -4,7 +4,6 @@ import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.ServiceConnection; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Handler; import android.os.HandlerThread; @@ -27,8 +26,11 @@ import java.util.LinkedList; import java.util.Queue; import java.util.Set; -import moe.yuuta.gplicense.ipc.ILicenseResultListener; -import moe.yuuta.gplicense.ipc.ILicensingService; +import moe.yuuta.ext.ConnCallback; +import moe.yuuta.ext.IPCResultListener; +import moe.yuuta.ext.IService; +import moe.yuuta.ext.LicServiceConn; +import moe.yuuta.ext.ResultCallback; import moe.yuuta.gplicense.util.Base64; import moe.yuuta.gplicense.util.Base64DecoderException; import moe.yuuta.workmode.BuildConfig; @@ -44,7 +46,7 @@ import moe.yuuta.workmode.BuildConfig; * Must also provide the Base64-encoded RSA public key associated with your developer account. The * public key is obtainable from the publisher site. */ -public class LicenseChecker implements ServiceConnection { +public class LicenseChecker implements ConnCallback { private static final Logger logger = XLog.tag("LCK").build(); private static final String KEY_FACTORY_ALGORITHM = "RSA"; @@ -55,7 +57,7 @@ public class LicenseChecker implements ServiceConnection { private static final SecureRandom RANDOM = new SecureRandom(); private static final boolean DEBUG_LICENSE_ERROR = BuildConfig.DEBUG; - private ILicensingService mService; + private IService mService; private PublicKey mPublicKey; private final Context mContext; @@ -70,6 +72,8 @@ public class LicenseChecker implements ServiceConnection { private final Set mChecksInProgress = new HashSet(); private final Queue mPendingChecks = new LinkedList(); + private LicServiceConn mConn; + /** * @param context a Context * @param policy implementation of Policy @@ -118,7 +122,7 @@ public class LicenseChecker implements ServiceConnection { * recommend obfuscating the string that is passed into bindService using another method of your * own devising. *

- * source string: "com.android.vending.licensing.ILicensingService" + * source string: "com.android.vending.licensing.IService" *

* * @param callback @@ -127,7 +131,7 @@ public class LicenseChecker implements ServiceConnection { // If we have a valid recent LICENSED response, we can skip asking // Market. if (mPolicy.allowAccess()) { - logger.i("Using cached license response"); + logger.i("Using cached response"); callback.allow(Policy.LICENSED); } else { LicenseValidator validator = new LicenseValidator(mPolicy, new NullDeviceLimiter(), @@ -136,12 +140,13 @@ public class LicenseChecker implements ServiceConnection { if (mService == null) { logger.i("Binding to service."); try { + mConn = new LicServiceConn(this); boolean bindResult = mContext .bindService( new Intent( new String( // Base64 encoded - - // com.android.vending.licensing.ILicensingService + // com.android.vending.licensing.IService // Consider encoding this in another way in your // code to improve security Base64.decode( @@ -163,7 +168,7 @@ public class LicenseChecker implements ServiceConnection { // com.android.vending Base64.decode( "Y29tLmFuZHJvaWQudmVuZGluZw=="))), - this, // ServiceConnection. + mConn, // ServiceConnection. Context.BIND_AUTO_CREATE); if (bindResult) { mPendingChecks.offer(validator); @@ -188,12 +193,12 @@ public class LicenseChecker implements ServiceConnection { while ((validator = mPendingChecks.poll()) != null) { try { logger.i("Executing on service for " + validator.getPackageName()); - mService.checkLicense( + mService.exec( validator.getNonce(), validator.getPackageName(), - new ResultListener(validator)); + new IPCResultListener(new ResultListener(validator))); mChecksInProgress.add(validator); } catch (RemoteException e) { - logger.w("RemoteException in checkLicense call.", e); + logger.w("RemoteException in exec call.", e); handleServiceConnectionError(validator); } } @@ -206,7 +211,7 @@ public class LicenseChecker implements ServiceConnection { } } - private class ResultListener extends ILicenseResultListener.Stub { + private class ResultListener implements ResultCallback { private final LicenseValidator mValidator; private Runnable mOnTimeout; @@ -226,6 +231,7 @@ public class LicenseChecker implements ServiceConnection { // Runs in IPC thread pool. Post it to the Handler, so we can guarantee // either this or the timeout runs. + @Override public void verifyLicense(final int responseCode, final String signedData, final String signature) { mHandler.post(() -> { @@ -280,11 +286,13 @@ public class LicenseChecker implements ServiceConnection { } } + @Override public synchronized void onServiceConnected(ComponentName name, IBinder service) { - mService = ILicensingService.Stub.asInterface(service); + mService = IService.Stub.asInterface(service); runChecks(); } + @Override public synchronized void onServiceDisconnected(ComponentName name) { // Called when the connection with the service has been // unexpectedly disconnected. That is, Market crashed. @@ -311,7 +319,7 @@ public class LicenseChecker implements ServiceConnection { private void cleanupService() { if (mService != null) { try { - mContext.unbindService(this); + mContext.unbindService(mConn); } catch (IllegalArgumentException e) { // Somehow we've already been unbound. This is a non-fatal // error. diff --git a/app/src/main/java/moe/yuuta/gplicense/LicenseValidator.java b/app/src/main/java/moe/yuuta/gplicense/LicenseValidator.java index 142f350..d34d614 100644 --- a/app/src/main/java/moe/yuuta/gplicense/LicenseValidator.java +++ b/app/src/main/java/moe/yuuta/gplicense/LicenseValidator.java @@ -184,7 +184,7 @@ class LicenseValidator { handleApplicationError(LicenseCheckerCallback.ERROR_NOT_MARKET_MANAGED); break; default: - logger.e("Unknown response code for license check."); + logger.e("Unknown response code for checking."); handleInvalidResponse(); } } diff --git a/app/src/main/java/moe/yuuta/gplicense/ServerManagedPolicy.java b/app/src/main/java/moe/yuuta/gplicense/ServerManagedPolicy.java index 8355cb8..fcc3451 100644 --- a/app/src/main/java/moe/yuuta/gplicense/ServerManagedPolicy.java +++ b/app/src/main/java/moe/yuuta/gplicense/ServerManagedPolicy.java @@ -159,7 +159,7 @@ public class ServerManagedPolicy implements Policy { lValidityTimestamp = Long.parseLong(validityTimestamp); } catch (NumberFormatException e) { // No response or not parsable, expire in one minute. - logger.w("License validity timestamp (VT) missing, caching for a minute"); + logger.w("Validity timestamp (VT) missing, caching for a minute"); lValidityTimestamp = System.currentTimeMillis() + MILLIS_PER_MINUTE; validityTimestamp = Long.toString(lValidityTimestamp); } diff --git a/app/src/main/java/moe/yuuta/gplicense/ipc/ILicenseResultListener.java b/app/src/main/java/moe/yuuta/gplicense/ipc/ILicenseResultListener.java deleted file mode 100644 index a7683b6..0000000 --- a/app/src/main/java/moe/yuuta/gplicense/ipc/ILicenseResultListener.java +++ /dev/null @@ -1,101 +0,0 @@ -package moe.yuuta.gplicense.ipc; - -import android.os.Binder; -import android.os.IBinder; -import android.os.IInterface; -import android.os.Parcel; -import android.os.RemoteException; - -import androidx.annotation.NonNull; - -import moe.yuuta.gplicense.util.Base64; -import moe.yuuta.gplicense.util.Base64DecoderException; - -public interface ILicenseResultListener extends IInterface { - abstract class Stub extends Binder implements ILicenseResultListener { - private static final String DESCRIPTOR; - - static { - try { - // Base64 encoded - - // com.android.vending.licensing.ILicenseResultListener - DESCRIPTOR = new String(Base64.decode( - "Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2VSZXN1bHRMaXN0ZW5lcg==")); - } catch (Base64DecoderException e) { - throw new RuntimeException(e); - } - } - - protected Stub() { - this.attachInterface(this, DESCRIPTOR); - } - - static ILicenseResultListener asInterface(IBinder obj) { - if ((obj == null)) { - return null; - } - IInterface iin = obj.queryLocalInterface(DESCRIPTOR); - if (iin instanceof ILicenseResultListener) { - return (ILicenseResultListener) iin; - } - return new Stub.Proxy(obj); - } - - @Override - public IBinder asBinder() { - return this; - } - - @Override - public boolean onTransact(int code, @NonNull Parcel data, Parcel reply, int flags) throws RemoteException { - switch (code) { - case INTERFACE_TRANSACTION: { - reply.writeString(DESCRIPTOR); - return true; - } - case TRANSACTION_verifyLicense: { - data.enforceInterface(DESCRIPTOR); - int responseCode = data.readInt(); - String signedData = data.readString(); - String signature = data.readString(); - this.verifyLicense(responseCode, signedData, signature); - return true; - } - default: { - return super.onTransact(code, data, reply, flags); - } - } - } - - private static class Proxy implements ILicenseResultListener { - private IBinder mRemote; - - Proxy(IBinder remote) { - mRemote = remote; - } - - @Override - public IBinder asBinder() { - return mRemote; - } - - @Override - public void verifyLicense(int responseCode, String signedData, String signature) throws RemoteException { - Parcel args = Parcel.obtain(); - try { - args.writeInterfaceToken(DESCRIPTOR); - args.writeInt(responseCode); - args.writeString(signedData); - args.writeString(signature); - mRemote.transact(TRANSACTION_verifyLicense, args, null, IBinder.FLAG_ONEWAY); - } finally { - args.recycle(); - } - } - } - - static final int TRANSACTION_verifyLicense = IBinder.FIRST_CALL_TRANSACTION; - } - - void verifyLicense(int responseCode, String signedData, String signature) throws RemoteException; -} \ No newline at end of file diff --git a/app/src/main/java/moe/yuuta/gplicense/ipc/ILicensingService.java b/app/src/main/java/moe/yuuta/gplicense/ipc/ILicensingService.java deleted file mode 100644 index 14e27f4..0000000 --- a/app/src/main/java/moe/yuuta/gplicense/ipc/ILicensingService.java +++ /dev/null @@ -1,101 +0,0 @@ -package moe.yuuta.gplicense.ipc; - -import android.os.Binder; -import android.os.IBinder; -import android.os.IInterface; -import android.os.Parcel; -import android.os.RemoteException; - -import androidx.annotation.NonNull; - -import moe.yuuta.gplicense.util.Base64; -import moe.yuuta.gplicense.util.Base64DecoderException; - -public interface ILicensingService extends IInterface { - abstract class Stub extends Binder implements ILicensingService { - private static final String DESCRIPTOR; - - static { - try { - // Base64 encoded - - // com.android.vending.licensing.ILicensingService - DESCRIPTOR = new String(Base64.decode( - "Y29tLmFuZHJvaWQudmVuZGluZy5saWNlbnNpbmcuSUxpY2Vuc2luZ1NlcnZpY2U=")); - } catch (Base64DecoderException e) { - throw new RuntimeException(e); - } - } - - public Stub() { - this.attachInterface(this, DESCRIPTOR); - } - - public static ILicensingService asInterface(IBinder obj) { - if ((obj == null)) { - return null; - } - IInterface iin = obj.queryLocalInterface(DESCRIPTOR); - if (iin instanceof ILicensingService) { - return (ILicensingService) iin; - } - return new ILicensingService.Stub.Proxy(obj); - } - - @Override - public IBinder asBinder() { - return this; - } - - @Override - public boolean onTransact(int code, @NonNull Parcel data, Parcel reply, int flags) throws RemoteException { - switch (code) { - case INTERFACE_TRANSACTION: { - reply.writeString(DESCRIPTOR); - return true; - } - case TRANSACTION_checkLicense: { - data.enforceInterface(DESCRIPTOR); - long nonce = data.readLong(); - String packageName = data.readString(); - ILicenseResultListener listener = ILicenseResultListener.Stub.asInterface(data.readStrongBinder()); - this.checkLicense(nonce, packageName, listener); - return true; - } - default: { - return super.onTransact(code, data, reply, flags); - } - } - } - - private static class Proxy implements ILicensingService { - private IBinder mRemote; - - Proxy(IBinder remote) { - mRemote = remote; - } - - @Override - public IBinder asBinder() { - return mRemote; - } - - @Override - public void checkLicense(long nonce, String packageName, ILicenseResultListener listener) throws RemoteException { - Parcel args = Parcel.obtain(); - try { - args.writeInterfaceToken(DESCRIPTOR); - args.writeLong(nonce); - args.writeString(packageName); - args.writeStrongBinder(listener != null ? listener.asBinder() : null); - mRemote.transact(TRANSACTION_checkLicense, args, null, IBinder.FLAG_ONEWAY); - } finally { - args.recycle(); - } - } - } - - static final int TRANSACTION_checkLicense = IBinder.FIRST_CALL_TRANSACTION; - } - - void checkLicense(long nonce, String packageName, ILicenseResultListener listener) throws RemoteException; -} \ No newline at end of file diff --git a/app/src/main/java/moe/yuuta/workmode/MainActivity.kt b/app/src/main/java/moe/yuuta/workmode/MainActivity.kt index b09e38e..792e948 100644 --- a/app/src/main/java/moe/yuuta/workmode/MainActivity.kt +++ b/app/src/main/java/moe/yuuta/workmode/MainActivity.kt @@ -29,7 +29,7 @@ import moe.yuuta.gplicense.LicenseCheckerCallback import moe.yuuta.gplicense.Policy import moe.yuuta.workmode.access.AccessorStarter import moe.yuuta.workmode.async.* -import moe.yuuta.workmode.gpl.GPLicenser +import moe.yuuta.workmode.gpl.GPL import moe.yuuta.workmode.suspend.AsyncSuspender import moe.yuuta.workmode.suspend.SuspendTile import moe.yuuta.workmode.suspend.data.ListMode @@ -78,7 +78,7 @@ class MainActivity : AppCompatActivity(), SwitchBar.OnSwitchChangeListener, View filter.addAction(AccessorStarter.ACTION_UPDATE_UI_PROGRESS) registerReceiver(mUIUpdateReceiver, filter) scheduleUpdateChecking() - lifecycle.addObserver(GPLicenser(this, lifecycle, this)) + lifecycle.addObserver(GPL(this, lifecycle, this)) setProgressUI(false) } diff --git a/app/src/main/java/moe/yuuta/workmode/gpl/GPL.kt b/app/src/main/java/moe/yuuta/workmode/gpl/GPL.kt new file mode 100644 index 0000000..3824f19 --- /dev/null +++ b/app/src/main/java/moe/yuuta/workmode/gpl/GPL.kt @@ -0,0 +1,47 @@ +package moe.yuuta.workmode.gpl + +import android.annotation.SuppressLint +import android.content.Context +import android.provider.Settings +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent +import moe.yuuta.gplicense.AESObfuscator +import moe.yuuta.gplicense.LicenseChecker +import moe.yuuta.gplicense.LicenseCheckerCallback +import moe.yuuta.gplicense.ServerManagedPolicy +import moe.yuuta.workmode.BuildConfig + +// #Anti-Crack +// Google Play Licenser +class GPL( + private val context: Context, + private val lifecycle: Lifecycle, + private val callback: LicenseCheckerCallback +) : LifecycleObserver { + private val SALT = byteArrayOf( + -90, 83, 80, -91, -37, -57, 74, -69, 52, 89, + -9, -5, -77, -71, -36, -79, -11, 37, -69, 88 + ) + + private lateinit var instance: LicenseChecker + + @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) + fun start() { + @SuppressLint("HardwareIds") val android_id = Settings.Secure.getString(context.contentResolver, + Settings.Secure.ANDROID_ID) + instance = LicenseChecker( + context, + ServerManagedPolicy(context, AESObfuscator(SALT, BuildConfig.APPLICATION_ID, android_id)), + BuildConfig.GOOGLE_PLAY_LICENSING_KEY + ) + instance.checkAccess(callback) + } + + @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) + fun destroy() { + if (::instance.isInitialized) { + instance.onDestroy() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/moe/yuuta/workmode/gpl/GPLicenser.kt b/app/src/main/java/moe/yuuta/workmode/gpl/GPLicenser.kt deleted file mode 100644 index fdcad9a..0000000 --- a/app/src/main/java/moe/yuuta/workmode/gpl/GPLicenser.kt +++ /dev/null @@ -1,45 +0,0 @@ -package moe.yuuta.workmode.gpl - -import android.annotation.SuppressLint -import android.content.Context -import android.provider.Settings -import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleObserver -import androidx.lifecycle.OnLifecycleEvent -import moe.yuuta.gplicense.AESObfuscator -import moe.yuuta.gplicense.LicenseChecker -import moe.yuuta.gplicense.LicenseCheckerCallback -import moe.yuuta.gplicense.ServerManagedPolicy -import moe.yuuta.workmode.BuildConfig - -class GPLicenser( - private val context: Context, - private val lifecycle: Lifecycle, - private val callback: LicenseCheckerCallback -) : LifecycleObserver { - private val SALT = byteArrayOf( - -90, 83, 80, -91, -37, -57, 74, -69, 52, 89, - -9, -5, -77, -71, -36, -79, -11, 37, -69, 88 - ) - - private lateinit var checker: LicenseChecker - - @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) - fun start() { - @SuppressLint("HardwareIds") val android_id = Settings.Secure.getString(context.contentResolver, - Settings.Secure.ANDROID_ID) - checker = LicenseChecker( - context, - ServerManagedPolicy(context, AESObfuscator(SALT, BuildConfig.APPLICATION_ID, android_id)), - BuildConfig.GOOGLE_PLAY_LICENSING_KEY - ) - checker.checkAccess(callback) - } - - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - fun destroy() { - if (::checker.isInitialized) { - checker.onDestroy() - } - } -} \ No newline at end of file -- cgit v1.2.3