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) {
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]] {

View File

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

View File

@ -253,7 +253,7 @@ namespace lspd {
return service;
}
ScopedLocalRef<jobject> Service::RequestBinderForSystemServer(JNIEnv *env) {
ScopedLocalRef<jobject> 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<jobject> Service::RequestApplicationBinderFromSystemServer(JNIEnv *env, const ScopedLocalRef<jobject> &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;
}

View File

@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* 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);
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);

View File

@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* 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;
@ -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;
// <uid, pid>
private final static Set<Pair<Integer, Integer>> cache = ConcurrentHashMap.newKeySet();
private final static Map<Integer, IBinder> 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) {

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
* 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
* 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;
@ -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);
}
}