Skip to content

Root/Shizuku: Fix not being able to bind the service interface after AGP updating AGP 8.0.2->8.1.2 - #705

Merged
d4rken merged 1 commit into
mainfrom
root_agp_upgrade_bind_ipc_reflection_fail
Oct 10, 2023
Merged

Root/Shizuku: Fix not being able to bind the service interface after AGP updating AGP 8.0.2->8.1.2#705
d4rken merged 1 commit into
mainfrom
root_agp_upgrade_bind_ipc_reflection_fail

Conversation

@d4rken

@d4rken d4rken commented Oct 10, 2023

Copy link
Copy Markdown
Member

Closes #689

Full stacktrace was:

E  getInterfaceFromBinder() failed: java.lang.NoSuchFieldException: No field DESCRIPTOR in class Leu/darken/sdmse/common/root/service/RootServiceConnection$Stub; (declaration of 'eu.darken.sdmse.common.root.service.RootServiceConnection$Stub' appears in /data/app/~~EMtqW8brkim4xhEVD5O_QA==/eu.darken.sdmse-DoVHI6JXBh7_Q7fsel3LcA==/base.apk!classes12.dex)
	at java.lang.Class.getDeclaredField(Native Method)
	at eu.darken.sdmse.common.ipc.BinderExtensionsKt.getInterface(BinderExtensions.kt:18)
	at eu.darken.sdmse.common.root.service.internal.RootHostLauncher$createConnection$1$ipcReceiver$1.onConnect(RootHostLauncher.kt:57)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver.doOnConnect(RootConnectionReceiver.kt:164)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver.access$doOnConnect(RootConnectionReceiver.kt:28)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver$receiver$1.onReceive$lambda$9$lambda$8$lambda$6(RootConnectionReceiver.kt:101)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver$receiver$1.$r8$lambda$HKc6gPCzGFkriQwJNV28QLf_Xag(Unknown Source:0)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver$receiver$1$$ExternalSyntheticLambda0.run(Unknown Source:2)
	at android.os.Handler.handleCallback(Handler.java:938)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loopOnce(Looper.java:226)
	at android.os.Looper.loop(Looper.java:313)
	at android.os.HandlerThread.run(HandlerThread.java:67)
E  FATAL EXCEPTION: javaroot:RootConnectionReceiver#7619a93c-df14-406d-82b3-cdf6f7238009
Process: eu.darken.sdmse, PID: 14319
eu.darken.sdmse.common.root.RootException: Failed to get user connection
	at eu.darken.sdmse.common.root.service.internal.RootHostLauncher$createConnection$1$ipcReceiver$1.onConnect(RootHostLauncher.kt:58)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver.doOnConnect(RootConnectionReceiver.kt:164)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver.access$doOnConnect(RootConnectionReceiver.kt:28)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver$receiver$1.onReceive$lambda$9$lambda$8$lambda$6(RootConnectionReceiver.kt:101)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver$receiver$1.$r8$lambda$HKc6gPCzGFkriQwJNV28QLf_Xag(Unknown Source:0)
	at eu.darken.sdmse.common.root.service.internal.RootConnectionReceiver$receiver$1$$ExternalSyntheticLambda0.run(Unknown Source:2)
	at android.os.Handler.handleCallback(Handler.java:938)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loopOnce(Looper.java:226)
	at android.os.Looper.loop(Looper.java:313)
	at android.os.HandlerThread.run(HandlerThread.java:67)

@d4rken d4rken added bug Something isn't working as expected Root ADB ADB/Shizuku related labels Oct 10, 2023
@d4rken

d4rken commented Oct 10, 2023

Copy link
Copy Markdown
Member Author

Before:

result = {Field[9]@32906} 
 0 = {Field@32907} "public static final int android.os.IBinder.DUMP_TRANSACTION"
 1 = {Field@32908} "public static final int android.os.IBinder.FIRST_CALL_TRANSACTION"
 2 = {Field@32909} "public static final int android.os.IBinder.FLAG_ONEWAY"
 3 = {Field@32910} "public static final int android.os.IBinder.INTERFACE_TRANSACTION"
 4 = {Field@32911} "public static final int android.os.IBinder.ISSYSTEMSERVER_TRANSACTION"
 5 = {Field@32912} "public static final int android.os.IBinder.LAST_CALL_TRANSACTION"
 6 = {Field@32913} "public static final int android.os.IBinder.LIKE_TRANSACTION"
 7 = {Field@32914} "public static final int android.os.IBinder.PING_TRANSACTION"
 8 = {Field@32915} "public static final int android.os.IBinder.TWEET_TRANSACTION"

After the AGP update:

result = {Field[10]@32890} 
 0 = {Field@32891} "public static final int android.os.IBinder.DUMP_TRANSACTION"
 1 = {Field@32892} "public static final int android.os.IBinder.FIRST_CALL_TRANSACTION"
 2 = {Field@32893} "public static final int android.os.IBinder.FLAG_ONEWAY"
 3 = {Field@32894} "public static final int android.os.IBinder.INTERFACE_TRANSACTION"
 4 = {Field@32895} "public static final int android.os.IBinder.ISSYSTEMSERVER_TRANSACTION"
 5 = {Field@32896} "public static final int android.os.IBinder.LAST_CALL_TRANSACTION"
 6 = {Field@32897} "public static final int android.os.IBinder.LIKE_TRANSACTION"
 7 = {Field@32898} "public static final int android.os.IBinder.PING_TRANSACTION"
 8 = {Field@32899} "public static final int android.os.IBinder.TWEET_TRANSACTION"
 9 = {Field@32900} "public static final java.lang.String eu.darken.sdmse.common.root.service.RootServiceConnection.DESCRIPTOR"

The AGP update changed AIDL generation:

Index: app-common-io/build/generated/aidl_source_output_dir/debug/out/eu/darken/sdmse/common/root/service/RootServiceConnection.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/app-common-io/build/generated/aidl_source_output_dir/debug/out/eu/darken/sdmse/common/root/service/RootServiceConnection.java b/app-common-io/build/generated/aidl_source_output_dir/debug/out/eu/darken/sdmse/common/root/service/RootServiceConnection.java
--- a/app-common-io/build/generated/aidl_source_output_dir/debug/out/eu/darken/sdmse/common/root/service/RootServiceConnection.java	
+++ b/app-common-io/build/generated/aidl_source_output_dir/debug/out/eu/darken/sdmse/common/root/service/RootServiceConnection.java	(date 1696953379599)
@@ -31,6 +31,7 @@
   /** Local-side IPC implementation stub class. */
   public static abstract class Stub extends android.os.Binder implements eu.darken.sdmse.common.root.service.RootServiceConnection
   {
+    private static final java.lang.String DESCRIPTOR = "eu.darken.sdmse.common.root.service.RootServiceConnection";
     /** Construct the stub at attach it to the interface. */
     public Stub()
     {
@@ -58,9 +59,6 @@
     @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
     {
       java.lang.String descriptor = DESCRIPTOR;
-      if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) {
-        data.enforceInterface(descriptor);
-      }
       switch (code)
       {
         case INTERFACE_TRANSACTION:
@@ -68,43 +66,43 @@
           reply.writeString(descriptor);
           return true;
         }
-      }
-      switch (code)
-      {
         case TRANSACTION_checkBase:
         {
+          data.enforceInterface(descriptor);
           java.lang.String _result = this.checkBase();
           reply.writeNoException();
           reply.writeString(_result);
-          break;
+          return true;
         }
         case TRANSACTION_getFileOps:
         {
+          data.enforceInterface(descriptor);
           eu.darken.sdmse.common.files.local.ipc.FileOpsConnection _result = this.getFileOps();
           reply.writeNoException();
-          reply.writeStrongInterface(_result);
-          break;
+          reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null)));
+          return true;
         }
         case TRANSACTION_getPkgOps:
         {
+          data.enforceInterface(descriptor);
           eu.darken.sdmse.common.pkgs.pkgops.ipc.PkgOpsConnection _result = this.getPkgOps();
           reply.writeNoException();
-          reply.writeStrongInterface(_result);
-          break;
+          reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null)));
+          return true;
         }
         case TRANSACTION_getShellOps:
         {
+          data.enforceInterface(descriptor);
           eu.darken.sdmse.common.shell.ipc.ShellOpsConnection _result = this.getShellOps();
           reply.writeNoException();
-          reply.writeStrongInterface(_result);
-          break;
+          reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null)));
+          return true;
         }
         default:
         {
           return super.onTransact(code, data, reply, flags);
         }
       }
-      return true;
     }
     private static class Proxy implements eu.darken.sdmse.common.root.service.RootServiceConnection
     {
@@ -129,6 +127,9 @@
         try {
           _data.writeInterfaceToken(DESCRIPTOR);
           boolean _status = mRemote.transact(Stub.TRANSACTION_checkBase, _data, _reply, 0);
+          if (!_status && getDefaultImpl() != null) {
+            return getDefaultImpl().checkBase();
+          }
           _reply.readException();
           _result = _reply.readString();
         }
@@ -146,6 +147,9 @@
         try {
           _data.writeInterfaceToken(DESCRIPTOR);
           boolean _status = mRemote.transact(Stub.TRANSACTION_getFileOps, _data, _reply, 0);
+          if (!_status && getDefaultImpl() != null) {
+            return getDefaultImpl().getFileOps();
+          }
           _reply.readException();
           _result = eu.darken.sdmse.common.files.local.ipc.FileOpsConnection.Stub.asInterface(_reply.readStrongBinder());
         }
@@ -163,6 +167,9 @@
         try {
           _data.writeInterfaceToken(DESCRIPTOR);
           boolean _status = mRemote.transact(Stub.TRANSACTION_getPkgOps, _data, _reply, 0);
+          if (!_status && getDefaultImpl() != null) {
+            return getDefaultImpl().getPkgOps();
+          }
           _reply.readException();
           _result = eu.darken.sdmse.common.pkgs.pkgops.ipc.PkgOpsConnection.Stub.asInterface(_reply.readStrongBinder());
         }
@@ -180,6 +187,9 @@
         try {
           _data.writeInterfaceToken(DESCRIPTOR);
           boolean _status = mRemote.transact(Stub.TRANSACTION_getShellOps, _data, _reply, 0);
+          if (!_status && getDefaultImpl() != null) {
+            return getDefaultImpl().getShellOps();
+          }
           _reply.readException();
           _result = eu.darken.sdmse.common.shell.ipc.ShellOpsConnection.Stub.asInterface(_reply.readStrongBinder());
         }
@@ -189,13 +199,29 @@
         }
         return _result;
       }
+      public static eu.darken.sdmse.common.root.service.RootServiceConnection sDefaultImpl;
     }
     static final int TRANSACTION_checkBase = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
     static final int TRANSACTION_getFileOps = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
     static final int TRANSACTION_getPkgOps = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
     static final int TRANSACTION_getShellOps = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
+    public static boolean setDefaultImpl(eu.darken.sdmse.common.root.service.RootServiceConnection impl) {
+      // Only one user of this interface can use this function
+      // at a time. This is a heuristic to detect if two different
+      // users in the same process use this function.
+      if (Stub.Proxy.sDefaultImpl != null) {
+        throw new IllegalStateException("setDefaultImpl() called twice");
+      }
+      if (impl != null) {
+        Stub.Proxy.sDefaultImpl = impl;
+        return true;
+      }
+      return false;
+    }
+    public static eu.darken.sdmse.common.root.service.RootServiceConnection getDefaultImpl() {
+      return Stub.Proxy.sDefaultImpl;
+    }
   }
-  public static final java.lang.String DESCRIPTOR = "eu.darken.sdmse.common.root.service.RootServiceConnection";
   public java.lang.String checkBase() throws android.os.RemoteException;
   public eu.darken.sdmse.common.files.local.ipc.FileOpsConnection getFileOps() throws android.os.RemoteException;
   public eu.darken.sdmse.common.pkgs.pkgops.ipc.PkgOpsConnection getPkgOps() throws android.os.RemoteException;

@d4rken
d4rken merged commit 59449ce into main Oct 10, 2023
@d4rken
d4rken deleted the root_agp_upgrade_bind_ipc_reflection_fail branch October 10, 2023 19:47
d4rken added a commit that referenced this pull request Oct 14, 2023
As guessed, was an R8 issue.

Before the AGP update (i.e. on 8.0.2) the DESCRIPTOR field was implicitly kept.
After moving to AGP 8.1.2 and fixing the reflection access (#705) works, but R8 will remove the field.

So this PR adds rules to keep the `DESCRIPTOR` field for Root and Shizuku.

Fixes #721
Fixes #722
d4rken added a commit that referenced this pull request Oct 14, 2023
As guessed, was an R8 issue.

Before the AGP update (i.e. on 8.0.2) the DESCRIPTOR field was implicitly kept.
After moving to AGP 8.1.2 and fixing the reflection access (#705) works, but R8 will remove the field.

So this PR adds rules to keep the `DESCRIPTOR` field for Root and Shizuku.

Fixes #721
Fixes #722
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ADB ADB/Shizuku related bug Something isn't working as expected Root

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Root/Shizuku does not work on bleeding edge build

1 participant