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/IService.java | 102 ++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 app/src/main/java/moe/yuuta/ext/IService.java (limited to 'app/src/main/java/moe/yuuta/ext/IService.java') 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 -- cgit v1.2.3