From d3b01402301313d2c685ba4257094b2d1e473594 Mon Sep 17 00:00:00 2001 From: kotori0 Date: Wed, 2 Feb 2022 16:02:58 +0800 Subject: [PATCH] Proxy transaction from system server service to application service --- core/src/main/cpp/main/src/context.cpp | 18 +++++--- core/src/main/cpp/main/src/context.h | 2 +- core/src/main/cpp/main/src/service.cpp | 13 +++--- core/src/main/cpp/main/src/service.h | 6 ++- .../lspd/service/LSPApplicationService.java | 9 ++-- .../lspd/service/LSPSystemServerService.java | 45 ++++++++++--------- 6 files changed, 54 insertions(+), 39 deletions(-) diff --git a/core/src/main/cpp/main/src/context.cpp b/core/src/main/cpp/main/src/context.cpp index 298ec9e4..e95c31c8 100644 --- a/core/src/main/cpp/main/src/context.cpp +++ b/core/src/main/cpp/main/src/context.cpp @@ -188,17 +188,25 @@ namespace lspd { Context::OnNativeForkSystemServerPost(JNIEnv *env) { if (!skip_) { auto *instance = Service::instance(); - auto binder = instance->RequestBinderForSystemServer(env); - // TODO: binder could be not available - auto dex = instance->RequestLSPDex(env, binder); + auto system_server_binder = instance->RequestSystemServerBinder(env); + if (!system_server_binder) { + LOGF("Failed to get system server binder, system server initialization failed. "); + return; + } + + auto application_binder = instance->RequestApplicationBinderFromSystemServer(env, system_server_binder); + + // Call application_binder directly if application binder is available, + // or we proxy the request from system server binder + auto dex = instance->RequestLSPDex(env, application_binder ? application_binder : system_server_binder); LoadDex(env, std::get<0>(dex), std::get<1>(dex)); instance->HookBridge(*this, env); - if (binder) { + if (application_binder) { obfuscated_signature_ = std::move(std::get<2>(dex)); InstallInlineHooks(); Init(env); - FindAndCall(env, "forkSystemServerPost", "(Landroid/os/IBinder;)V", binder); + FindAndCall(env, "forkSystemServerPost", "(Landroid/os/IBinder;)V", application_binder); } else skip_ = true; } if (skip_) [[unlikely]] { diff --git a/core/src/main/cpp/main/src/context.h b/core/src/main/cpp/main/src/context.h index 966c8421..98ee066b 100644 --- a/core/src/main/cpp/main/src/context.h +++ b/core/src/main/cpp/main/src/context.h @@ -15,7 +15,7 @@ * along with LSPosed. If not, see . * * Copyright (C) 2020 EdXposed Contributors - * Copyright (C) 2021 LSPosed Contributors + * Copyright (C) 2021 - 2022 LSPosed Contributors */ #pragma once diff --git a/core/src/main/cpp/main/src/service.cpp b/core/src/main/cpp/main/src/service.cpp index 4a598a0f..ba80aac5 100644 --- a/core/src/main/cpp/main/src/service.cpp +++ b/core/src/main/cpp/main/src/service.cpp @@ -253,7 +253,7 @@ namespace lspd { return service; } - ScopedLocalRef Service::RequestBinderForSystemServer(JNIEnv *env) { + ScopedLocalRef Service::RequestSystemServerBinder(JNIEnv *env) { if (!initialized_) [[unlikely]] { LOGE("Service not initialized"); return {env, nullptr}; @@ -277,17 +277,20 @@ namespace lspd { LOGW("Fail to get binder for system server"); return {env, nullptr}; } + return binder; + } + ScopedLocalRef Service::RequestApplicationBinderFromSystemServer(JNIEnv *env, const ScopedLocalRef &system_server_binder) { 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_); - JNI_CallVoidMethod(env, data, write_int_method_, getuid()); // data.writeInt(uid) + JNI_CallVoidMethod(env, data, write_int_method_, getuid()); JNI_CallVoidMethod(env, data, write_int_method_, getpid()); JNI_CallVoidMethod(env, data, write_string_method_, JNI_NewStringUTF(env, "android")); JNI_CallVoidMethod(env, data, write_strong_binder_method_, heart_beat_binder); - auto res = JNI_CallBooleanMethod(env, binder, transact_method_, + auto res = JNI_CallBooleanMethod(env, system_server_binder, transact_method_, BRIDGE_TRANSACTION_CODE, data, reply, 0); @@ -297,14 +300,14 @@ namespace lspd { JNI_CallVoidMethod(env, reply, read_exception_method_); app_binder = JNI_CallObjectMethod(env, reply, read_strong_binder_method_); } else { - LOGE("Service::RequestBinderForSystemServer binder.transact failed?"); + LOGE("Service::RequestSystemServerBinder binder.transact failed?"); } JNI_CallVoidMethod(env, data, recycleMethod_); JNI_CallVoidMethod(env, reply, recycleMethod_); if (app_binder) { JNI_NewGlobalRef(env, heart_beat_binder); } - LOGD("Service::RequestBinderForSystemServer app_binder: %p", app_binder.get()); + LOGD("Service::RequestSystemServerBinder app_binder: %p", app_binder.get()); return app_binder; } diff --git a/core/src/main/cpp/main/src/service.h b/core/src/main/cpp/main/src/service.h index fd74e68e..8fe40886 100644 --- a/core/src/main/cpp/main/src/service.h +++ b/core/src/main/cpp/main/src/service.h @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with LSPosed. If not, see . * - * Copyright (C) 2021 LSPosed Contributors + * Copyright (C) 2021 - 2022 LSPosed Contributors */ // @@ -53,7 +53,9 @@ namespace lspd { void HookBridge(const Context& context, JNIEnv *env); ScopedLocalRef RequestBinder(JNIEnv *env, jstring nice_name); - ScopedLocalRef RequestBinderForSystemServer(JNIEnv *env); + ScopedLocalRef RequestSystemServerBinder(JNIEnv *env); + + ScopedLocalRef RequestApplicationBinderFromSystemServer(JNIEnv *env, const ScopedLocalRef &system_server_binder); std::tuple RequestLSPDex(JNIEnv *env, const ScopedLocalRef &binder); diff --git a/daemon/src/main/java/org/lsposed/lspd/service/LSPApplicationService.java b/daemon/src/main/java/org/lsposed/lspd/service/LSPApplicationService.java index 6ed0371f..93463c08 100644 --- a/daemon/src/main/java/org/lsposed/lspd/service/LSPApplicationService.java +++ b/daemon/src/main/java/org/lsposed/lspd/service/LSPApplicationService.java @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with LSPosed. If not, see . * - * Copyright (C) 2021 LSPosed Contributors + * Copyright (C) 2021 - 2022 LSPosed Contributors */ package org.lsposed.lspd.service; @@ -40,7 +40,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; public class LSPApplicationService extends ILSPApplicationService.Stub { - private final static int DEX_TRANSACTION_CODE = 1310096052; + final static int DEX_TRANSACTION_CODE = 1310096052; // private final static Set> cache = ConcurrentHashMap.newKeySet(); private final static Map handles = new ConcurrentHashMap<>(); @@ -48,7 +48,7 @@ public class LSPApplicationService extends ILSPApplicationService.Stub { @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException { - Log.i(TAG, "LSPApplicationService.onTransact: code=" + code); + Log.d(TAG, "LSPApplicationService.onTransact: code=" + code); if (code == DEX_TRANSACTION_CODE) { try { ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(ObfuscationManager.preloadDex()); @@ -60,9 +60,8 @@ public class LSPApplicationService extends ILSPApplicationService.Stub { return false; } return true; - } else { - return super.onTransact(code, data, reply, flags); } + return super.onTransact(code, data, reply, flags); } public boolean registerHeartBeat(int uid, int pid, IBinder handle) { diff --git a/daemon/src/main/java/org/lsposed/lspd/service/LSPSystemServerService.java b/daemon/src/main/java/org/lsposed/lspd/service/LSPSystemServerService.java index 61adb82b..2f39ef59 100644 --- a/daemon/src/main/java/org/lsposed/lspd/service/LSPSystemServerService.java +++ b/daemon/src/main/java/org/lsposed/lspd/service/LSPSystemServerService.java @@ -1,5 +1,5 @@ /* - * + * Copyright (C) 2021 - 2022 LSPosed Contributors */ package org.lsposed.lspd.service; @@ -88,29 +88,32 @@ public class LSPSystemServerService extends ILSPSystemServerService.Stub impleme @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { - Log.i(TAG, "LSPSystemServerService.onTransact: code=" + code); + Log.d(TAG, "LSPSystemServerService.onTransact: code=" + code); if (originService != null) { return originService.transact(code, data, reply, flags); } - if (code == BridgeService.TRANSACTION_CODE) { - // request application service with JNI - int uid = data.readInt(); - int pid = data.readInt(); - String processName = data.readString(); - IBinder heartBeat = data.readStrongBinder(); - var service = requestApplicationService(uid, pid, processName, heartBeat); - if (service != null) { - Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService granted: " + service); - reply.writeNoException(); - reply.writeStrongBinder(service.asBinder()); - return true; - } else { - Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService rejected"); - return false; - } - } else { - return super.onTransact(code, data, reply, flags); + switch (code) { + case BridgeService.TRANSACTION_CODE: + int uid = data.readInt(); + int pid = data.readInt(); + String processName = data.readString(); + IBinder heartBeat = data.readStrongBinder(); + var service = requestApplicationService(uid, pid, processName, heartBeat); + if (service != null) { + Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService granted: " + service); + reply.writeNoException(); + reply.writeStrongBinder(service.asBinder()); + return true; + } else { + Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService rejected"); + return false; + } + case LSPApplicationService.DEX_TRANSACTION_CODE: + // Proxy LSP dex transaction to Application Binder + return ServiceManager.getApplicationService().onTransact(code, data, reply, flags); + default: + return super.onTransact(code, data, reply, flags); } }