iamr0s / Dhizuku-API

API of Dhizuku.
MIT License
99 stars 12 forks source link

Caught a RuntimeException from the binder stub implementation. #12

Closed sbmatch closed 3 months ago

sbmatch commented 3 months ago

环境: dhizuku-api 版本: 2.5.3 问题: 绑定的上用户服务但是ibinder ping不通

DhizukuUserService工厂类

public class DhizukuUserServiceFactory implements AbstractIUserServiceFactory {

    private static DhizukuUserServiceFactory dhizukuUserServiceFactory;
    private OnUserServiceCallbackListener callbackListener;
    private final static String TAG = DhizukuUserServiceFactory.class.getSimpleName();

    public DhizukuUserServiceFactory() {
        Log.i(TAG, "************* Dhizuku 用户服务工厂************");
    }

    public static DhizukuUserServiceFactory get() {
        if (dhizukuUserServiceFactory == null) dhizukuUserServiceFactory = new DhizukuUserServiceFactory();
        return dhizukuUserServiceFactory;
    }

    private final IBinder.DeathRecipient deathRecipient = () -> {
        ToastUtils.toast(TAG +": 服务死亡");
    };

    private final DhizukuUserServiceArgs dhizukuUserServiceArgs = new DhizukuUserServiceArgs(new ComponentName(ContextUtils.getContext(), DhizukuUserServiceImpl.class));
    private final ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {

            if (callbackListener != null && service != null && service.pingBinder()) {
                Log.i(TAG, " Dhizuku 用户服务已连接");
                callbackListener.onUserServiceReady(service);
                try {
                    service.linkToDeath(deathRecipient, 0);
                } catch (RemoteException e) {
                    throw new RuntimeException(e);
                }

            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e("Dhizuku", name + " 断开连接");
        }
    };

    public void setOnCallbackListener(OnUserServiceCallbackListener mOnCallbackListener) {
        Log.i(TAG, "设置回调监听器: "+mOnCallbackListener);
        this.callbackListener = mOnCallbackListener;
    }

    @Override
    public void bindUserService() {
        Log.i(TAG, "**********尝试绑定用户服务*************");
        Dhizuku.bindUserService(dhizukuUserServiceArgs, connection);
    }

    @Override
    public void unbindUserService() {
        Log.i(TAG, "**********尝试解绑用户服务*************");
        Dhizuku.unbindUserService(connection);
    }
}

异常日志

2024-08-25 12:18:32.680 22919-22919 DhizukuUse...iceFactory ma.DeviceOptimizeHelper              I  设置回调监听器: com.sbmatch.deviceopt.MainActivity@225ef1d
2024-08-25 12:18:32.682 22919-22919 DhizukuUse...iceFactory ma.DeviceOptimizeHelper              I  **********尝试绑定用户服务*************
2024-08-25 12:18:34.213 22919-22919 BpBinder                ma.DeviceOptimizeHelper              W  PerfMonitor binderTransact: time=1529ms
                                                                                                    interface=com.rosan.dhizuku.aidl.IDhizuku code=13
2024-08-25 12:18:34.213 22919-22919 MessageMonitor          ma.DeviceOptimizeHelper              W  PerfMonitor: Slow Operation: Activity
                                                                                                    ma.DeviceOptimizeHelper/com.sbmatch.deviceopt.MainActivity onCreate took
                                                                                                    1641ms
2024-08-25 12:18:34.214 22919-22936 Binder                  ma.DeviceOptimizeHelper              W  Caught a RuntimeException from the binder stub implementation.
                                                                                                    java.lang.NullPointerException: Attempt to invoke interface method 'void
                                                                                                    android.os.IBinder.linkToDeath(android.os.IBinder$DeathRecipient, int)' on a
                                                                                                    null object reference
                                                                                                        at
                                                                                                    com.rosan.dhizuku.api.DhizukuServiceConnections$1.connected(DhizukuServiceConnections.java:25)
                                                                                                        at
                                                                                                    com.rosan.dhizuku.aidl.IDhizukuUserServiceConnection$Stub.onTransact(IDhizukuUserServiceConnection.java:70)
                                                                                                        at android.os.Binder.execTransactInternal(Binder.java:1351)
                                                                                                        at android.os.Binder.execTransact(Binder.java:1282)
iamr0s commented 3 months ago

必须基于AIDL实现一个 IInterface,比如IUserService.aidl

随后在通过java或kotlin实现 UserService.java

iamr0s commented 3 months ago

因为Dhizuku的所有底层实现都是基于AIDL IBinder机制实现的,如果还是不行,请附上整个工程项目文件到此。

iamr0s commented 3 months ago

你也可以参考 雹 Hail 旧实现 AIDL Impl

sbmatch commented 3 months ago

因为Dhizuku的所有底层实现都是基于AIDL IBinder机制实现的,如果还是不行,请附上整个工程项目文件到此。

demo项目

sbmatch commented 3 months ago

无聊,所以尝试使用拥有512个线程的线程暴力尝试绑定10万次直到绑定成功

  private void bindServiceWithRetry() {
        threadPool.execute(() -> {
            final int MAX_RETRY_COUNT = 100000;
            int retryCount = 0;
            while (retryCount < MAX_RETRY_COUNT && remoteServiceBinder == null) {
                try {
                    Dhizuku.bindUserService(dhizukuUserServiceArgs, connection);
                    retryCount++;
                    MMKV.defaultMMKV().putInt("rebindCount", retryCount);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

崩溃日志

           java.util.ConcurrentModificationException
                                                                                                        at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1029)
                                                                                                        at java.util.ArrayList$Itr.next(ArrayList.java:982)
                                                                                                        at com.rosan.dhizuku.api.DhizukuServiceConnection.lambda$onServiceConnected$0$com-rosan-dhizuku-api-DhizukuServiceConnection(DhizukuServiceConnection.java:19)
                                                                                                        at com.rosan.dhizuku.api.DhizukuServiceConnection$$ExternalSyntheticLambda0.run(Unknown Source:6)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:958)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at android.os.Looper.loopOnce(Looper.java:224)
                                                                                                        at android.os.Looper.loop(Looper.java:318)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:8772)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:561)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
sbmatch commented 3 months ago

在headler.post执行bind 造成dhizuku崩溃

FATAL EXCEPTION: DefaultDispatcher-worker-4
Process: com.rosan.dhizuku, PID: 18973
android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: app.uid (code 2067 SQLITE_CONSTRAINT_UNIQUE)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:961)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:790)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:89)
    at F1.j.a(SourceFile:3)
    at U1.b.d(SourceFile:68)
    at U1.d.call(SourceFile:266)
    at B1.f.o(SourceFile:6)
    at o2.a.q(SourceFile:9)
    at E2.F.run(SourceFile:113)
    at A1.k.run(SourceFile:137)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1251)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:668)
    at java.lang.Thread.run(Thread.java:1012)
    Suppressed: J2.g: [n0{Cancelling}@6db9bd1, Dispatchers.IO]
sbmatch commented 3 months ago

问题已经解决, 我在我的dpm类中增加了新的构造方法用于从已激活的设备所有者应用程序中创建上下文并获取devicepolicymanager, 就像这样

public class DevicePolicyManager { private IInterface manager; private static DevicePolicyManager devicePolicyManager; private android.app.admin.DevicePolicyManager dpm; private static ComponentName adminComponent;

public DevicePolicyManager(IInterface manager){
    this.manager = manager;
}

private DevicePolicyManager(String targetPackage){
    android.app.admin.DevicePolicyManager dpm2 = (android.app.admin.DevicePolicyManager) ContextUtil.createPackageContext(targetPackage).getSystemService(Context.DEVICE_POLICY_SERVICE);
    IInterface anInterface = (IInterface) ReflectUtil.getObjectField(dpm2, "mService");
    switch (targetPackage){
        case "com.rosan.dhizuku":
            if (anInterface instanceof DhizukuBinderWrapper)  dpm = dpm2;
            ReflectUtil.setObjectField(dpm2, "mService", IDevicePolicyManager.Stub.asInterface(Dhizuku.binderWrapper(anInterface.asBinder())));
            dpm = dpm2;
            break;
    }

}
public static DevicePolicyManager getByDeviceOwner(){
    if (devicePolicyManager == null) {
        devicePolicyManager = new DevicePolicyManager(getDeviceOwnerComponent().getPackageName());
        adminComponent = getDeviceOwnerComponent();
    }
    return devicePolicyManager;
}

} ..... 省略若干代码