Proxy transaction from system server service to application service

This commit is contained in:
kotori0 2022-02-02 16:02:58 +08:00 committed by LoveSy
parent a628528cd8
commit d3b0140230
6 changed files with 54 additions and 39 deletions

View File

@ -188,17 +188,25 @@ namespace lspd {
Context::OnNativeForkSystemServerPost(JNIEnv *env) { Context::OnNativeForkSystemServerPost(JNIEnv *env) {
if (!skip_) { if (!skip_) {
auto *instance = Service::instance(); auto *instance = Service::instance();
auto binder = instance->RequestBinderForSystemServer(env); auto system_server_binder = instance->RequestSystemServerBinder(env);
// TODO: binder could be not available if (!system_server_binder) {
auto dex = instance->RequestLSPDex(env, 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)); LoadDex(env, std::get<0>(dex), std::get<1>(dex));
instance->HookBridge(*this, env); instance->HookBridge(*this, env);
if (binder) { if (application_binder) {
obfuscated_signature_ = std::move(std::get<2>(dex)); obfuscated_signature_ = std::move(std::get<2>(dex));
InstallInlineHooks(); InstallInlineHooks();
Init(env); Init(env);
FindAndCall(env, "forkSystemServerPost", "(Landroid/os/IBinder;)V", binder); FindAndCall(env, "forkSystemServerPost", "(Landroid/os/IBinder;)V", application_binder);
} else skip_ = true; } else skip_ = true;
} }
if (skip_) [[unlikely]] { if (skip_) [[unlikely]] {

View File

@ -15,7 +15,7 @@
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>. * along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
* *
* Copyright (C) 2020 EdXposed Contributors * Copyright (C) 2020 EdXposed Contributors
* Copyright (C) 2021 LSPosed Contributors * Copyright (C) 2021 - 2022 LSPosed Contributors
*/ */
#pragma once #pragma once

View File

@ -253,7 +253,7 @@ namespace lspd {
return service; return service;
} }
ScopedLocalRef<jobject> Service::RequestBinderForSystemServer(JNIEnv *env) { ScopedLocalRef<jobject> Service::RequestSystemServerBinder(JNIEnv *env) {
if (!initialized_) [[unlikely]] { if (!initialized_) [[unlikely]] {
LOGE("Service not initialized"); LOGE("Service not initialized");
return {env, nullptr}; return {env, nullptr};
@ -277,17 +277,20 @@ namespace lspd {
LOGW("Fail to get binder for system server"); LOGW("Fail to get binder for system server");
return {env, nullptr}; return {env, nullptr};
} }
return binder;
}
ScopedLocalRef<jobject> Service::RequestApplicationBinderFromSystemServer(JNIEnv *env, const ScopedLocalRef<jobject> &system_server_binder) {
auto heart_beat_binder = JNI_NewObject(env, binder_class_, binder_ctor_); auto heart_beat_binder = JNI_NewObject(env, binder_class_, binder_ctor_);
auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_); auto data = JNI_CallStaticObjectMethod(env, parcel_class_, obtain_method_);
auto reply = 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_int_method_, getpid());
JNI_CallVoidMethod(env, data, write_string_method_, JNI_NewStringUTF(env, "android")); JNI_CallVoidMethod(env, data, write_string_method_, JNI_NewStringUTF(env, "android"));
JNI_CallVoidMethod(env, data, write_strong_binder_method_, heart_beat_binder); 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, BRIDGE_TRANSACTION_CODE,
data, data,
reply, 0); reply, 0);
@ -297,14 +300,14 @@ namespace lspd {
JNI_CallVoidMethod(env, reply, read_exception_method_); JNI_CallVoidMethod(env, reply, read_exception_method_);
app_binder = JNI_CallObjectMethod(env, reply, read_strong_binder_method_); app_binder = JNI_CallObjectMethod(env, reply, read_strong_binder_method_);
} else { } else {
LOGE("Service::RequestBinderForSystemServer binder.transact failed?"); LOGE("Service::RequestSystemServerBinder binder.transact failed?");
} }
JNI_CallVoidMethod(env, data, recycleMethod_); JNI_CallVoidMethod(env, data, recycleMethod_);
JNI_CallVoidMethod(env, reply, recycleMethod_); JNI_CallVoidMethod(env, reply, recycleMethod_);
if (app_binder) { if (app_binder) {
JNI_NewGlobalRef(env, heart_beat_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; return app_binder;
} }

View File

@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>. * along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
* *
* Copyright (C) 2021 LSPosed Contributors * Copyright (C) 2021 - 2022 LSPosed Contributors
*/ */
// //
@ -53,7 +53,9 @@ namespace lspd {
void HookBridge(const Context& context, JNIEnv *env); void HookBridge(const Context& context, JNIEnv *env);
ScopedLocalRef<jobject> RequestBinder(JNIEnv *env, jstring nice_name); ScopedLocalRef<jobject> RequestBinder(JNIEnv *env, jstring nice_name);
ScopedLocalRef<jobject> RequestBinderForSystemServer(JNIEnv *env); ScopedLocalRef<jobject> RequestSystemServerBinder(JNIEnv *env);
ScopedLocalRef<jobject> RequestApplicationBinderFromSystemServer(JNIEnv *env, const ScopedLocalRef<jobject> &system_server_binder);
std::tuple<int, size_t, std::string> RequestLSPDex(JNIEnv *env, const ScopedLocalRef<jobject> &binder); std::tuple<int, size_t, std::string> RequestLSPDex(JNIEnv *env, const ScopedLocalRef<jobject> &binder);

View File

@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>. * along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
* *
* Copyright (C) 2021 LSPosed Contributors * Copyright (C) 2021 - 2022 LSPosed Contributors
*/ */
package org.lsposed.lspd.service; package org.lsposed.lspd.service;
@ -40,7 +40,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class LSPApplicationService extends ILSPApplicationService.Stub { public class LSPApplicationService extends ILSPApplicationService.Stub {
private final static int DEX_TRANSACTION_CODE = 1310096052; final static int DEX_TRANSACTION_CODE = 1310096052;
// <uid, pid> // <uid, pid>
private final static Set<Pair<Integer, Integer>> cache = ConcurrentHashMap.newKeySet(); private final static Set<Pair<Integer, Integer>> cache = ConcurrentHashMap.newKeySet();
private final static Map<Integer, IBinder> handles = new ConcurrentHashMap<>(); private final static Map<Integer, IBinder> handles = new ConcurrentHashMap<>();
@ -48,7 +48,7 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
@Override @Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws android.os.RemoteException { 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) { if (code == DEX_TRANSACTION_CODE) {
try { try {
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(ObfuscationManager.preloadDex()); ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(ObfuscationManager.preloadDex());
@ -60,9 +60,8 @@ public class LSPApplicationService extends ILSPApplicationService.Stub {
return false; return false;
} }
return true; 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) { public boolean registerHeartBeat(int uid, int pid, IBinder handle) {

View File

@ -1,5 +1,5 @@
/* /*
* <!--This file is part of LSPosed. * This file is part of LSPosed.
* *
* LSPosed is free software: you can redistribute it and/or modify * LSPosed is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>. * along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
* *
* Copyright (C) 2021 LSPosed Contributors--> * Copyright (C) 2021 - 2022 LSPosed Contributors
*/ */
package org.lsposed.lspd.service; package org.lsposed.lspd.service;
@ -88,29 +88,32 @@ public class LSPSystemServerService extends ILSPSystemServerService.Stub impleme
@Override @Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { 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) { if (originService != null) {
return originService.transact(code, data, reply, flags); return originService.transact(code, data, reply, flags);
} }
if (code == BridgeService.TRANSACTION_CODE) { switch (code) {
// request application service with JNI case BridgeService.TRANSACTION_CODE:
int uid = data.readInt(); int uid = data.readInt();
int pid = data.readInt(); int pid = data.readInt();
String processName = data.readString(); String processName = data.readString();
IBinder heartBeat = data.readStrongBinder(); IBinder heartBeat = data.readStrongBinder();
var service = requestApplicationService(uid, pid, processName, heartBeat); var service = requestApplicationService(uid, pid, processName, heartBeat);
if (service != null) { if (service != null) {
Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService granted: " + service); Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService granted: " + service);
reply.writeNoException(); reply.writeNoException();
reply.writeStrongBinder(service.asBinder()); reply.writeStrongBinder(service.asBinder());
return true; return true;
} else { } else {
Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService rejected"); Log.d(TAG, "LSPSystemServerService.onTransact requestApplicationService rejected");
return false; return false;
} }
} else { case LSPApplicationService.DEX_TRANSACTION_CODE:
return super.onTransact(code, data, reply, flags); // Proxy LSP dex transaction to Application Binder
return ServiceManager.getApplicationService().onTransact(code, data, reply, flags);
default:
return super.onTransact(code, data, reply, flags);
} }
} }