diff --git a/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPApplicationService.aidl b/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPApplicationService.aidl index 5ca70569..a08db967 100644 --- a/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPApplicationService.aidl +++ b/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPApplicationService.aidl @@ -1,8 +1,6 @@ package io.github.lsposed.lspd.service; interface ILSPApplicationService { - void registerHeartBeat(IBinder handle) = 1; - IBinder requestModuleBinder() = 2; IBinder requestManagerBinder() = 3; diff --git a/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPosedService.aidl b/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPosedService.aidl index a692df13..fef85f66 100644 --- a/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPosedService.aidl +++ b/core/src/main/aidl/io/github/lsposed/lspd/service/ILSPosedService.aidl @@ -3,7 +3,7 @@ package io.github.lsposed.lspd.service; import io.github.lsposed.lspd.service.ILSPApplicationService; interface ILSPosedService { - ILSPApplicationService requestApplicationService(int uid, int pid, String processName) = 1; + ILSPApplicationService requestApplicationService(int uid, int pid, String processName, IBinder heartBeat) = 1; oneway void dispatchPackageChanged(in Intent intent) = 2; } \ No newline at end of file diff --git a/core/src/main/cpp/main/src/service.cpp b/core/src/main/cpp/main/src/service.cpp index f1d52846..f747a7d9 100644 --- a/core/src/main/cpp/main/src/service.cpp +++ b/core/src/main/cpp/main/src/service.cpp @@ -84,6 +84,10 @@ namespace lspd { transact_method_ = env->GetMethodID(ibinder_class, "transact", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z"); + binder_class_ = env->FindClass("android/os/Binder"); + if (binder_class_) binder_class_ = (jclass)env->NewGlobalRef(binder_class_); + binder_ctor_ = env->GetMethodID(binder_class_, "", "()V"); + // Parcel parcel_class_ = env->FindClass("android/os/Parcel"); if (parcel_class_) parcel_class_ = (jclass) env->NewGlobalRef(parcel_class_); @@ -93,7 +97,9 @@ namespace lspd { "(Ljava/lang/String;)V"); write_int_method_ = env->GetMethodID(parcel_class_, "writeInt", "(I)V"); write_string_method_ = env->GetMethodID(parcel_class_, "writeString", - "(Ljava/lang/String;)V"); + "(Ljava/lang/String;)V"); + write_strong_binder_method_ = env->GetMethodID(parcel_class_, "writeStrongBinder", + "(Landroid/os/IBinder;)V"); read_exception_method_ = env->GetMethodID(parcel_class_, "readException", "()V"); read_strong_binder_method_ = env->GetMethodID(parcel_class_, "readStrongBinder", "()Landroid/os/IBinder;"); @@ -126,7 +132,7 @@ namespace lspd { ScopedLocalRef binderClass(env, env->FindClass("android/os/Binder")); exec_transact_backup_methodID_ = JNI_GetMethodID(env, binderClass.get(), "execTransact", - "(IJJI)Z"); + "(IJJI)Z"); auto set_table_override = reinterpret_cast(DobbySymbolResolver(nullptr, "_ZN3art9JNIEnvExt16SetTableOverrideEPK18JNINativeInterface")); @@ -159,6 +165,8 @@ namespace lspd { return nullptr; } + auto heart_beat_binder = JNI_NewObject(env, binder_class_, binder_ctor_); + auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_); auto reply = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_); @@ -166,6 +174,7 @@ namespace lspd { JNI_CallVoidMethod(env, data, write_interface_token_method_, descriptor); JNI_CallVoidMethod(env, data, write_int_method_, BRIDGE_ACTION_GET_BINDER); JNI_CallVoidMethod(env, data, write_string_method_, nice_name); + JNI_CallVoidMethod(env, data, write_strong_binder_method_, heart_beat_binder); auto res = JNI_CallBooleanMethod(env, bridgeService, transact_method_, BRIDGE_TRANSACTION_CODE, @@ -181,20 +190,38 @@ namespace lspd { } JNI_CallVoidMethod(env, data, recycleMethod_); JNI_CallVoidMethod(env, reply, recycleMethod_); + if (service) { + env->NewGlobalRef(heart_beat_binder); + } else { + env->DeleteLocalRef(heart_beat_binder); + } return service; } jobject Service::RequestBinderForSystemServer(JNIEnv *env) { + if (UNLIKELY(!initialized_)) { + LOGE("Service not initialized"); + return nullptr; + } auto bridgeServiceName = env->NewStringUTF(SYSTEM_SERVER_BRIDGE_SERVICE_NAME.data()); auto binder = JNI_CallStaticObjectMethod(env, service_manager_class_, - get_service_method_, bridgeServiceName); - if(!binder) { + get_service_method_, bridgeServiceName); + if (!binder) { LOGD("Fail to get binder for system server"); return nullptr; } - auto method = JNI_GetStaticMethodID(env, bridge_service_class_, "getApplicationServiceForSystemServer", "(Landroid/os/IBinder;)Landroid/os/IBinder;"); - auto app_binder = JNI_CallStaticObjectMethod(env, bridge_service_class_, method, binder); + auto method = JNI_GetStaticMethodID(env, bridge_service_class_, + "getApplicationServiceForSystemServer", + "(Landroid/os/IBinder;Landroid/os/IBinder;)Landroid/os/IBinder;"); + auto heart_beat_binder = JNI_NewObject(env, binder_class_, binder_ctor_); + auto app_binder = JNI_CallStaticObjectMethod(env, bridge_service_class_, method, binder, + heart_beat_binder); + if (app_binder) { + env->NewGlobalRef(heart_beat_binder); + } else { + env->DeleteLocalRef(heart_beat_binder); + } return app_binder; } } \ No newline at end of file diff --git a/core/src/main/cpp/main/src/service.h b/core/src/main/cpp/main/src/service.h index dbd9cb2b..b9a810d9 100644 --- a/core/src/main/cpp/main/src/service.h +++ b/core/src/main/cpp/main/src/service.h @@ -74,6 +74,9 @@ namespace lspd { jclass bridge_service_class_ = nullptr; jmethodID exec_transact_replace_methodID_ = nullptr; + jclass binder_class_ = nullptr; + jmethodID binder_ctor_ = nullptr; + jclass service_manager_class_ = nullptr; jmethodID get_service_method_ = nullptr; @@ -87,6 +90,7 @@ namespace lspd { jmethodID write_string_method_ = nullptr; jmethodID read_exception_method_ = nullptr; jmethodID read_strong_binder_method_ = nullptr; + jmethodID write_strong_binder_method_ = nullptr; jclass deadObjectExceptionClass_ = nullptr; diff --git a/core/src/main/java/io/github/lsposed/lspd/config/LSPApplicationServiceClient.java b/core/src/main/java/io/github/lsposed/lspd/config/LSPApplicationServiceClient.java index ad306dc1..c43df6e7 100644 --- a/core/src/main/java/io/github/lsposed/lspd/config/LSPApplicationServiceClient.java +++ b/core/src/main/java/io/github/lsposed/lspd/config/LSPApplicationServiceClient.java @@ -60,18 +60,6 @@ public class LSPApplicationServiceClient implements ILSPApplicationService { } } - @Override - public void registerHeartBeat(IBinder handle) { - if (service == null || serviceBinder == null) { - Utils.logE("Register Failed: service is null"); - } - try { - service.registerHeartBeat(handle); - } catch (RemoteException e) { - Utils.logE("register heart beat failed", e); - } - } - @Override public IBinder requestModuleBinder() { try { diff --git a/core/src/main/java/io/github/lsposed/lspd/core/Main.java b/core/src/main/java/io/github/lsposed/lspd/core/Main.java index 9297a3eb..1ed07206 100644 --- a/core/src/main/java/io/github/lsposed/lspd/core/Main.java +++ b/core/src/main/java/io/github/lsposed/lspd/core/Main.java @@ -39,11 +39,9 @@ import static io.github.lsposed.lspd.config.LSPApplicationServiceClient.serviceC @Keep public class Main { private static final AtomicReference lspdImplRef = new AtomicReference<>(null); - private static final Binder heartBeatBinder = new Binder(); public static void forkAndSpecializePost(String appDataDir, String niceName, IBinder binder) { LSPApplicationServiceClient.Init(binder, niceName); - serviceClient.registerHeartBeat(heartBeatBinder); final int variant = serviceClient.getVariant(); Impl lspd = getImpl(variant); if (lspd == null || !lspd.isInitialized()) { @@ -55,7 +53,6 @@ public class Main { public static void forkSystemServerPost(IBinder binder) { LSPApplicationServiceClient.Init(binder, "android"); - serviceClient.registerHeartBeat(heartBeatBinder); final int variant = serviceClient.getVariant(); Impl lspd = getImpl(variant); if (lspd == null || !lspd.isInitialized()) { diff --git a/core/src/main/java/io/github/lsposed/lspd/service/BridgeService.java b/core/src/main/java/io/github/lsposed/lspd/service/BridgeService.java index 690ed903..7555f178 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/BridgeService.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/BridgeService.java @@ -255,7 +255,8 @@ public class BridgeService { IBinder binder = null; try { String processName = data.readString(); - binder = service.requestApplicationService(Binder.getCallingUid(), Binder.getCallingPid(), processName).asBinder(); + IBinder heartBeat = data.readStrongBinder(); + binder = service.requestApplicationService(Binder.getCallingUid(), Binder.getCallingPid(), processName, heartBeat).asBinder(); } catch (RemoteException e) { Log.e(TAG, Log.getStackTraceString(e)); } @@ -311,17 +312,18 @@ public class BridgeService { } @Keep - public static IBinder getApplicationServiceForSystemServer(IBinder binder) { - if (binder == null) return null; + public static IBinder getApplicationServiceForSystemServer(IBinder binder, IBinder heartBeat) { + if (binder == null || heartBeat == null) return null; try { ILSPosedService service = ILSPosedService.Stub.asInterface(binder); - ILSPApplicationService applicationService = service.requestApplicationService(Process.myUid(), Process.myPid(), "android"); + ILSPApplicationService applicationService = service.requestApplicationService(Process.myUid(), Process.myPid(), "android", heartBeat); if (applicationService != null) return applicationService.asBinder(); } catch (Throwable e) { Log.e(TAG, Log.getStackTraceString(e)); } return null; } + private static void tryGetActivityManagerServiceInstance() { try { Log.e(TAG, "Trying to get the ams"); diff --git a/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java b/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java index 1259b8ce..c1e24aa3 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/ConfigManager.java @@ -150,6 +150,7 @@ public class ConfigManager { // for system server, cache is not yet ready, we need to query database for it public boolean shouldSkipSystemServer() { try (Cursor cursor = db.query("scope INNER JOIN modules ON scope.mid = modules.mid", new String[]{"modules.mid"}, "app_pkg_name=? AND enabled=1", new String[]{"android"}, null, null, null)) { + Log.e(TAG, "ZHEER2"); return cursor == null || !cursor.moveToNext(); } } @@ -422,6 +423,7 @@ public class ConfigManager { db.beginTransaction(); db.delete("scope", "mid = ?", new String[]{String.valueOf(mid)}); for (Application app : scopes) { + if (app.packageName.equals("android") && app.userId != 0) continue; ContentValues values = new ContentValues(); values.put("mid", mid); values.put("app_pkg_name", app.packageName); diff --git a/core/src/main/java/io/github/lsposed/lspd/service/LSPApplicationService.java b/core/src/main/java/io/github/lsposed/lspd/service/LSPApplicationService.java index 7207fc8b..53b17d07 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/LSPApplicationService.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/LSPApplicationService.java @@ -36,22 +36,24 @@ public class LSPApplicationService extends ILSPApplicationService.Stub { private final static Set> cache = ConcurrentHashMap.newKeySet(); private final static Set handles = ConcurrentHashMap.newKeySet(); - @Override - public void registerHeartBeat(IBinder handle) throws RemoteException { - handles.add(handle); - int uid = Binder.getCallingUid(); - int pid = Binder.getCallingPid(); - - cache.add(new Pair<>(uid, pid)); - handle.linkToDeath(new DeathRecipient() { - @Override - public void binderDied() { - Log.d(TAG, "pid=" + pid + " uid=" + uid + " is dead."); - cache.remove(new Pair<>(uid, pid)); - handles.remove(handle); - handle.unlinkToDeath(this, 0); - } - }, 0); + public boolean registerHeartBeat(int uid, int pid, IBinder handle) { + try { + handle.linkToDeath(new DeathRecipient() { + @Override + public void binderDied() { + Log.d(TAG, "pid=" + pid + " uid=" + uid + " is dead."); + cache.remove(new Pair<>(uid, pid)); + handles.remove(handle); + handle.unlinkToDeath(this, 0); + } + }, 0); + handles.add(handle); + cache.add(new Pair<>(uid, pid)); + return true; + } catch (RemoteException e) { + Log.e(TAG, Log.getStackTraceString(e)); + return false; + } } @Override diff --git a/core/src/main/java/io/github/lsposed/lspd/service/LSPosedService.java b/core/src/main/java/io/github/lsposed/lspd/service/LSPosedService.java index 7961e61f..7951e436 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/LSPosedService.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/LSPosedService.java @@ -24,6 +24,7 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Binder; +import android.os.IBinder; import android.os.RemoteException; import android.util.Log; @@ -35,16 +36,17 @@ import static io.github.lsposed.lspd.service.ServiceManager.TAG; public class LSPosedService extends ILSPosedService.Stub { @Override - public ILSPApplicationService requestApplicationService(int uid, int pid, String processName) { + public ILSPApplicationService requestApplicationService(int uid, int pid, String processName, IBinder heartBeat) { if (Binder.getCallingUid() != 1000) { Log.w(TAG, "Someone else got my binder!?"); return null; } if (uid == 1000 && processName.equals("android")) { + Log.e(TAG, "ZHEER"); if (ConfigManager.getInstance().shouldSkipSystemServer()) return null; else - return ServiceManager.getApplicationService(); + return ServiceManager.requestApplicationService(uid, pid, heartBeat); } if (ConfigManager.getInstance().shouldSkipProcess(new ConfigManager.ProcessScope(processName, uid))) { Log.d(TAG, "Skipped " + processName + "/" + uid); @@ -55,7 +57,7 @@ public class LSPosedService extends ILSPosedService.Stub { return null; } Log.d(TAG, "returned service"); - return ServiceManager.getApplicationService(); + return ServiceManager.requestApplicationService(uid, pid, heartBeat); } diff --git a/core/src/main/java/io/github/lsposed/lspd/service/ServiceManager.java b/core/src/main/java/io/github/lsposed/lspd/service/ServiceManager.java index a3af8dfb..5f0eb86f 100644 --- a/core/src/main/java/io/github/lsposed/lspd/service/ServiceManager.java +++ b/core/src/main/java/io/github/lsposed/lspd/service/ServiceManager.java @@ -50,7 +50,7 @@ public class ServiceManager { public static void start() { Log.i(TAG, "starting server..."); - Thread.setDefaultUncaughtExceptionHandler((t, e)->{ + Thread.setDefaultUncaughtExceptionHandler((t, e) -> { Log.e(TAG, Log.getStackTraceString(e)); }); @@ -114,6 +114,12 @@ public class ServiceManager { return applicationService; } + public static LSPApplicationService requestApplicationService(int uid, int pid, IBinder heartBeat) { + if (applicationService.registerHeartBeat(uid, pid, heartBeat)) + return applicationService; + else return null; + } + public static LSPManagerService getManagerService() { return managerService; }